o
    2j!                  &   @   s,  d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
mZmZ ddlmZmZ ddlmZ ddlmZmZmZ dd	lmZmZ dd
lmZ ddlmZmZmZmZmZm Z m!Z! ddl"m#Z# errddl$m%Z% e&e'Z(dZ)dZ*eG dd dZ+eG dd dZ,eG dd dZ-eG dd dZ.eddG dd dZ/eG dd dZ0eG dd dZ1eG d d! d!Z2d"e3d#efd$d%Z4d"e3d#e5fd&d'Z6eG d(d) d)Z7eG d*d+ d+Z8G d,d- d-Z9d.e3d#e:e;e3e3f  fd/d0Z<d"e3d#e;e=e>f dB fd1d2Z?d3e3d#e	e;e3e=e>f  fd4d5Z@d6d7d8e3d9e3d#e	e;e3e=e>ef  fd:d;ZAd<e>d#e3fd=d>ZBdd?d"e3d@edA dBe=dCe>dDe=dEe>dFe3dGe3dHe5dIe5dJe5dKedB d#e7fdLdMZC	N	N	N	N	N		dndOe3dPe3d6d7dQe5dIe5dHe5dRe5dJe5dSe9dB dTedB d#e8fdUdVZDdWe8d#dfdXdYZEdWe8dZe3d#dfd[d\ZFdZe3d#e8fd]d^ZGdodWe8d6d7d_e5dTedB d#df
d`daZHdWe8d#dfdbdcZI		dpdNdNdNdNdNddddddNdNdNddddOe3dB dPe3dB d6d7dQe5dIe5dHe5dRe5dJe5dee:e3 dB dfe:e3 dB dge3dB dWe3dB dhe3dB die5d_e5dje5dke5e3B dB d#e8f$dldmZJdS )qzzShared logic for bucket operations.

This module contains the core buckets logic used by both the CLI and the Python API.
    N)Iterator)	dataclassfield)datetimetimezone)Path)TYPE_CHECKINGAnyLiteral   )	constantslogging)BucketNotFoundError)HfUri
StatusLineXetFileDatadisable_progress_barsenable_progress_barsparse_datetimeparse_hf_uri)_looks_like_hf_urlHfApizhf://buckets/  c                   @   sB   e Zd ZU dZeed< eed< eed< eed< eed< dd Z	d	S )

BucketInfoa  
    Contains information about a bucket on the Hub. This object is returned by [`bucket_info`] and [`list_buckets`].

    Attributes:
        id (`str`):
            ID of the bucket.
        private (`bool`):
            Is the bucket private.
        created_at (`datetime`):
            Date of creation of the bucket on the Hub.
        size (`int`):
            Size of the bucket in bytes.
        total_files (`int`):
            Total number of files in the bucket.
    idprivate
created_atsizetotal_filesc                 K   sV   | d| _| d| _t| d| _| d| _| d| _| jjdi | d S )Nr   r   	createdAtr   
totalFiles )	popr   r   r   r   r   r   __dict__update)selfkwargsr"   r"   S/var/www/html/whisper/venv/lib/python3.10/site-packages/huggingface_hub/_buckets.py__init__V   s   zBucketInfo.__init__N)
__name__
__module____qualname____doc__str__annotations__boolr   intr)   r"   r"   r"   r(   r   >   s   
 r   c                   @   s   e Zd ZU eeB eB ed< eed< eddZedB ed< eddZ	e
dB ed< eddZe
ed	< eddZedB ed
< dddZdS )_BucketAddFilesourcedestinationNdefaultxet_hashr   Finitmtimecontent_typereturnc                 C   sx   d | _ t| jttfrt| jd | _ | j d u r"t| jd | _ tt| jt	s2t
j| jd nt d | _d S Nr   r   )r;   
isinstancer3   r.   r   	mimetypes
guess_typer4   r1   bytesospathgetmtimetimer:   r&   r"   r"   r(   __post_init__i   s   
(
z_BucketAddFile.__post_init__r<   N)r*   r+   r,   r.   r   rA   r/   r   r7   r   r1   r:   r;   rG   r"   r"   r"   r(   r2   _   s   
 r2   c                   @   sv   e Zd ZU eed< eed< eed< eed< eddZedB ed< edd	Zeed
< edd	Z	edB ed< dddZ
dS )_BucketCopyFiler4   r7   source_repo_typesource_repo_idNr5   r   Fr8   r:   r;   r<   c                 C   s(   t | jd | _tt d | _d S r=   )r?   r@   r4   r;   r1   rE   r:   rF   r"   r"   r(   rG      s   z_BucketCopyFile.__post_init__rH   )r*   r+   r,   r.   r/   r   r   r1   r:   r;   rG   r"   r"   r"   r(   rI   u   s   
 rI   c                   @   s   e Zd ZU eed< dS )_BucketDeleteFilerC   N)r*   r+   r,   r.   r/   r"   r"   r"   r(   rL      s   
 rL   T)frozenc                   @   s"   e Zd ZU dZeed< eed< dS )BucketFileMetadataa%  Data structure containing information about a file in a bucket.

    Returned by [`get_bucket_file_metadata`].

    Args:
        size (`int`):
            Size of the file in bytes.
        xet_file_data (`XetFileData`):
            Xet information for the file (hash and refresh route).
    r   xet_file_dataN)r*   r+   r,   r-   r1   r/   r   r"   r"   r"   r(   rN      s   
 rN   c                   @   sf   e Zd ZU dZeed< dZeed< eddZeed< eddZ	eed< eddZ
eed	< dddZdS )	BucketUrla  Describes a bucket URL on the Hub.

    `BucketUrl` is returned by [`create_bucket`]. At initialization, the URL is parsed to populate properties:
    - endpoint (`str`)
    - namespace (`str`)
    - bucket_id (`str`)
    - url (`str`)
    - uri (`HfUri`)

    Args:
        url (`str`):
            String value of the bucket url.
        endpoint (`str`, *optional*):
            Endpoint of the Hub. Defaults to <https://huggingface.co>.
    url endpointFr8   	namespace	bucket_idurir<   Nc                 C   s   | j ptj| _ | j| j dd}|dr|tdd  }t|}|j	r.t
d| j |jdd | _|j| _|| _d S )NrR   /zbuckets/zUnable to parse bucket URL: r   )rS   r   ENDPOINTrQ   replacestrip
startswithlen_parse_bucket_uripath_in_repo
ValueErrorr   splitrT   rU   rV   )r&   url_pathparsedr"   r"   r(   rG      s   

zBucketUrl.__post_init__rH   )r*   r+   r,   r-   r.   r/   rS   r   rT   rU   rV   r   rG   r"   r"   r"   r(   rP      s   
 rP   c                   @   sV   e Zd ZU dZed ed< eed< eed< eed< edB ed< edB ed	< d
d Z	dS )
BucketFilez
    Contains information about a file in a bucket on the Hub. This object is returned by [`list_bucket_tree`].

    Similar to [`RepoFile`] but for files in buckets.
    filetyperC   r   r7   Nr:   uploaded_atc                 K   sv   | d| _| d| _| d| _| d| _| dd }|r$t|nd | _| dd }|r6t|| _d S d | _d S )Nre   rC   r   xetHashr:   
uploadedAt)r#   re   rC   r   r7   r   r:   rf   )r&   r'   r:   rf   r"   r"   r(   r)      s   zBucketFile.__init__)
r*   r+   r,   r-   r
   r/   r.   r1   r   r)   r"   r"   r"   r(   rc      s   
 rc   c                   @   s:   e Zd ZU dZed ed< eed< edB ed< dd ZdS )	BucketFolderz
    Contains information about a directory in a bucket on the Hub. This object is returned by [`list_bucket_tree`].

    Similar to [`RepoFolder`] but for directories in buckets.
    	directoryre   rC   Nrf   c                 K   s`   | d| _| d| _| dd p| dd }|r+t|tr$|| _d S t|| _d S d | _d S )Nre   rC   rh   rf   )r#   re   rC   r>   r   r   rf   )r&   r'   rf   r"   r"   r(   r)      s   zBucketFolder.__init__)	r*   r+   r,   r-   r
   r/   r.   r   r)   r"   r"   r"   r(   ri      s   
 ri   rC   r<   c                 C   s   |  tjs
t| rt| }|jstd|  d|S | dd}t|dk s/|d r/|d s7td|  d|d  d|d  }d	|dd	 }t
d
||dS )a  Parse a bucket path into a HfUri.

    Accepts:
    - `hf://buckets/namespace/name(/path/in/repo)` URIs,
    - Hugging Face web URLs such as `https://huggingface.co/buckets/namespace/name(/tree/path)`,
    - plain `namespace/name(/path/in/repo)` paths.
    zInvalid bucket path: z*. Must be a bucket URI (hf://buckets/...).rW      r   r   zInvalid bucket path: 'z)'. Expected format: namespace/bucket_nameNbucket)re   r   r^   )r[   r   HF_PROTOCOLr   r   	is_bucketr_   r`   r\   joinr   )rC   rb   partsrU   prefixr"   r"   r(   r]      s   r]   c                 C   s   |  tjsdS t| jS )zCheck if a path is a bucket path.

    Do not raise if the path is not a hf:// URI.
    Raise if the path is a hf:// URI but with an incorrect format.
    F)r[   r   rm   r   rn   )rC   r"   r"   r(   _is_bucket_path  s   
rr   c                   @   sr   e Zd ZU dZed ed< eed< dZedB ed< dZ	eed< dZ
edB ed	< dZedB ed
< dZedB ed< dS )SyncOperationz,Represents a sync operation to be performed.)uploaddownloaddeleteskipactionrC   Nr   rR   reasonlocal_mtimeremote_mtimebucket_file)r*   r+   r,   r-   r
   r/   r.   r   r1   ry   rz   r{   r|   rc   r"   r"   r"   r(   rs     s   
 rs   c                   @   sZ   e Zd ZU dZeed< eed< eed< eedZee	 ed< de
eeeB f fdd	Zd
S )SyncPlanz Represents a complete sync plan.r3   dest	timestamp)default_factory
operationsr<   c                 C   st   t dd | jD }t dd | jD }t dd | jD }t dd | jD }t dd | jD }|||||dS )Nc                 s       | ]
}|j d krdV  qdS )rt   r   Nrx   .0opr"   r"   r(   	<genexpr>5      z#SyncPlan.summary.<locals>.<genexpr>c                 s   r   )ru   r   Nr   r   r"   r"   r(   r   6  r   c                 s   r   )rv   r   Nr   r   r"   r"   r(   r   7  r   c                 s   r   )rw   r   Nr   r   r"   r"   r(   r   8  r   c                 s   s$    | ]}|j d v r|jpdV  qdS )rt   ru   r   N)rx   r   r   r"   r"   r(   r   9  s   " )uploads	downloadsdeletesskips
total_size)sumr   )r&   r   r   r   r   r   r"   r"   r(   summary4  s   zSyncPlan.summaryN)r*   r+   r,   r-   r.   r/   r   listr   rs   dictr1   r   r"   r"   r"   r(   r}   +  s   
 r}   c                
   @   s`   e Zd ZdZ			ddee dB dee dB deeeef  dB fddZded	efd
dZ	dS )FilterMatcherz4Matches file paths against include/exclude patterns.Ninclude_patternsexclude_patternsfilter_rulesc                 C   s"   |pg | _ |pg | _|pg | _dS )a  Initialize the filter matcher.

        Args:
            include_patterns: Patterns to include (from --include)
            exclude_patterns: Patterns to exclude (from --exclude)
            filter_rules: Rules from filter file as list of ("+"/"-", pattern) tuples
        Nr   r   r   )r&   r   r   r   r"   r"   r(   r)   K  s   

zFilterMatcher.__init__rC   r<   c                 C   sr   | j D ]\}}t||r|dk  S q| jD ]}t||r" dS q| jD ]}t||r1 dS q&| jr7dS dS )zCheck if a path should be included based on the filter rules.

        Filtering rules:
        - Filters are evaluated in order, first matching rule decides
        - If no rules match, include by default (unless include patterns are specified)
        +FT)r   fnmatchr   r   )r&   rC   signpatternr"   r"   r(   matches\  s   

zFilterMatcher.matches)NNN)
r*   r+   r,   r-   r   r.   tupler)   r0   r   r"   r"   r"   r(   r   H  s    


r   filter_filec                 C   s   g }t | G}|D ];}| }|r|drq	|dr*|d|dd  f q	|dr=|d|dd  f q	|d|f q	W d   |S 1 sPw   Y  |S )zParse a filter file and return a list of (sign, pattern) tuples.

    Filter file format:
    - Lines starting with "+" are include patterns
    - Lines starting with "-" are exclude patterns
    - Empty lines and lines starting with "#" are ignored
    #r   r   N-)openrZ   r[   append)r   rulesfliner"   r"   r(   _parse_filter_filey  s    



r   c                 C   sD   zt | }W n
 ty   Y dS w t|jrdS |j|jd fS )zStat a local file and return (size, mtime_ms).

    Returns None if the path is missing or is a directory. Uses a single
    ``os.stat`` call so callers don't pay for multiple syscalls per file.
    Nr   )rB   statOSErrorS_ISDIRst_modest_sizest_mtime)rC   str"   r"   r(   _stat_local  s   r   
local_pathc                 c   s    t j| } t j| std|  t | D ]2\}}}|D ]*}t j||}t|}|du r2q t j|| }|	t j
d}||d |d fV  q qdS )zsList all files in a local directory.

    Yields:
        tuple: (relative_path, size, mtime_ms) for each file
    z Local path must be a directory: NrW   r   r   )rB   rC   abspathisdirr_   walkro   r   relpathrY   sep)r   root_filesfilename	full_path	stat_inforel_pathr"   r"   r(   _list_local_files  s   r   apir   rU   rq   c                 c   s    | j ||pdddD ]I}t|trq|j}|r>||d r*|t|d d }n||kr=d|v r:|ddd n|}nq|}|jrJ|j d nd}||j	||fV  qdS )	zList all files in a bucket with a given prefix.

    Yields:
        tuple: (relative_path, size, mtime_ms, bucket_file) for each file.
            bucket_file is the BucketFile object from list_bucket_tree.
    NT)rq   	recursiverW   r   r   r   )
list_bucket_treer>   ri   rC   r[   r\   rsplitr:   r   r   )r   rU   rq   itemrC   r   mtime_msr"   r"   r(   _list_remote_files  s   
r   r   c                 C   s   t j| d tjd S )z3Convert mtime in milliseconds to ISO format string.r   )tz)r   fromtimestampr   utc	isoformat)r   r"   r"   r(   _mtime_to_iso  s   r   )r|   rx   r   source_sizesource_mtime	dest_size
dest_mtimesource_newer_labeldest_newer_labelignore_sizesignore_timesignore_existingr|   c                 C   s  t |dkr|n|}t |dkr|n|}| |||d}|
r'tdddd|S ||k}|| tk}|rV|r@td|||d|S || tk}|rJ|nd}tdd|d|S |	ro|retd|d|d|S tddd	d|S |ss|r|rwdn|}td|||d|S tddd
d|S )a  Compare source and dest files and return the appropriate sync operation.

    This is a unified helper for both upload and download directions.

    Args:
        path: Relative file path
        action: "upload" or "download"
        source_size: Size of the source file (bytes)
        source_mtime: Mtime of the source file (milliseconds)
        dest_size: Size of the destination file (bytes)
        dest_mtime: Mtime of the destination file (milliseconds)
        source_newer_label: Label when source is newer (e.g., "local newer" or "remote newer")
        dest_newer_label: Label when dest is newer (e.g., "remote newer" or "local newer")
        ignore_sizes: Only compare mtime
        ignore_times: Only compare size
        ignore_existing: Skip files that exist on receiver
        bucket_file: BucketFile object (for downloads only)

    Returns:
        SyncOperation describing the action to take
    rt   )rC   r   rz   r{   rw   z&exists on receiver (--ignore-existing))rx   ry   )rx   ry   r|   z
same mtimezsize differsz	same size	identicalNr"   )r   rs   _SYNC_TIME_WINDOW_MS)rC   rx   r   r   r   r   r   r   r   r   r   r|   local_mtime_isoremote_mtime_isobase_kwargssize_differssource_newer
dest_newerskip_reasonry   r"   r"   r(   _compare_files_for_sync  s2   $r   Fr3   r~   rv   existingfilter_matcherstatusc
           %      C   s  |pt  }t|  ot|}
t| ot| }|
s|stdt| |ttj d}d}|
rt	j
| }t|}|j|j}}t	j
|sOtd| i }t|D ]\}}}||re||f||< |	rr|	dt| d qU|	r|	dt| d i }|	rz||j}W n	 ty   Y nw z4t|||D ]+\}}}}||r||f||< |	r|durd| nd}|	d	t| | d qW n ty   td
| d Y nw |	r|	d	t| d t| t| B }|	r|	dt| d t|D ]}||}||}|rG|sG|r2|j !t"d||d dt#|d d q|j !t"d||d dt#|d d q|rj|rj|\}}|\}} |j !t$|d|||| dd|||d q|s|r|r|j !t"d||d dt#|d d q|S t| }|j|j}}t	j
|}i }i }!|	rz||j}W n
 ty   Y nw t|||D ]3\}}}}"||r||f||< |"|!|< |	r|durd| nd}|	d	t| | d q|	r|	d	t| d i }t	j
|rY|r/t|D ] \}}}||r||f||< |	r,|	dt| d qn*|D ]'}t	j
%||}#t&|#}$|$du rEq1|$||< |	rW|	dt| d q1|	rg|	dt| d t| t| B }|	r|	dt| d t|D ]}||}||}|r|s|r|j !t"d||d dt#|d d q|j !t"d||d dt#|d |!|d q|r|r|\}} |\}}|j !t$|d|| ||dd||||!|d q|s|r|r|j !t"d||d dt#|d d q|S )zCompute the sync plan by comparing source and destination.

    Returns:
        SyncPlan with all operations to be performed
    z[One of source or dest must be a bucket path (hf://buckets/...) and the other must be local.r3   r~   r   NzSource must be a directory: zScanning local directory (z files)rW   rR   zScanning remote bucket (zBucket 'z' not found, treating as empty.zComparing files (z paths)rw   r   znew file (--existing)r   )rx   rC   r   ry   rz   rt   znew filezlocal newerzremote newer)rC   rx   r   r   r   r   r   r   r   r   r   rv   znot in source (--delete))rx   rC   r   ry   r{   ru   )rx   rC   r   ry   r{   r|   )rC   rx   r   r   r   r   r   r   r   r   r   r|   )'r   rr   r_   r}   r   nowr   r   r   rB   rC   r   r]   r   r^   r   r   r   r%   r\   donebucket_infor   	Exceptionr   r   loggerdebugsetkeyssortedgetr   r   rs   r   r   ro   r   )%r3   r~   r   rv   r   r   r   r   r   r   	is_uploadis_downloadplanremote_totalr   rb   rU   rq   local_filesr   r   r   remote_filesr   	total_str	all_pathsrC   
local_inforemote_info
local_sizerz   remote_sizer{   bucket_file_mapr|   
local_filer   r"   r"   r(   _compute_sync_plan*  s  







	
{









r   r   c                 C   s   d| j | j| j|  d}|t|d  | jD ]4}d|j|j	|j
d}|jdur0|j|d< |jdur:|j|d< |jdurD|j|d	< |t|d  qdS )
z1Write a sync plan as JSONL to a file-like object.header)re   r3   r~   r   r   
	operation)re   rx   rC   ry   Nr   rz   r{   )r3   r~   r   r   writejsondumpsr   rx   rC   ry   r   rz   r{   )r   r   r   r   op_dictr"   r"   r(   _write_plan&  s*   






r  	plan_filec                 C   s:   t |d}t| | W d   dS 1 sw   Y  dS )z!Save a sync plan to a JSONL file.wN)r   r  )r   r  r   r"   r"   r(   
_save_planC  s   "r  c                 C   s   t | }| }W d   n1 sw   Y  |s!td|  t|d }|ddkr3tdt|d |d |d	 d
}|dd D ].}t|}|ddkrUqF|jt	|d |d |d|dd|d|dd qF|S )z#Load a sync plan from a JSONL file.NzEmpty plan file: r   re   r   z0Invalid plan file: expected header as first liner3   r~   r   r   r   r   rx   rC   r   ry   rR   rz   r{   )rx   rC   r   ry   rz   r{   )
r   	readlinesr_   r   loadsr   r}   r   r   rs   )r  r   linesr   r   r   r   r"   r"   r(   
_load_planI  s8   



r  verbosec              	   C   s  t | j o
t | j}t | jot | j }|rtj| j}t| j}|j|j}}	g }
g }| j	D ]o}|j
 dkrg tj||j}|	rM|	 d|j n|j}|r_td|j d|j d |
||f q2 dkr |	rv|	 d|j n|j}|rtd|j d|j d || q2dkr|rtd	|j d|j d q2q2|
s|r|rg }|
r|d
t|
 d |r|dt| d |d|  |j||
pd|pdd dS dS |rt| j}|j|j}}	tj| j}tj|dd g }g }| j	D ]}|j
dkrTtj||j}tjtj|dd |r-td|j d|j d |jdur=||j|f q|	rH|	 d|j n|j}|||f q|j
dkrytj||j}|rrtd|j d|j d || q|j
dkr|rtd	|j d|j d qt|dkr|r|dt| d ||| |r|r|dt| d |D ]9}tj|rt| tj|}||krzt| tj|}W n
 ty   Y nw ||ksؐqdS dS )zExecute a sync plan.rt   rW   z  Uploading: z ()rv   z  Deleting: rw   z  Skipping: z
uploading z filesz	deleting z, N)addrv   T)exist_okru   z  Downloading: r   zDownloading z	Deleting z local files)rr   r3   r~   rB   rC   r   r]   r   r^   r   rx   ro   printry   r   r\   r   
capitalizebatch_bucket_filesmakedirsdirnamer|   download_bucket_filesexistsremovermdirr   )r   r   r	  r   r   r   r   rb   rU   rq   	add_filesdelete_pathsr   r   remote_pathrp   download_filesdelete_files	file_pathparentr"   r"   r(   _execute_plant  s   











*r  c                 C   sl   |   }td| j d| j  td|d   td|d   td|d   td	|d
   dS )z!Print a summary of the sync plan.zSync plan: z -> z  Uploads: r   z  Downloads: r   z  Deletes: r   z	  Skips: r   N)r   r  r3   r~   )r   r   r"   r"   r(   _print_plan_summary  s   r  )rv   r   r   r   r   includeexcludefilter_fromr   applydry_runr	  quiettokenr  r   r!  r"  r#  r$  r%  c                C   s  |durddl m} ||d}|r| s|rtd|dur!td|r'td|r-td|r3td	|r9td
|	r?td|
rEtd|rKtd|rQtd|rWtdt|}t| d}|skt| td |rpt  zt||||d W |rt	  n|rt	  w w |std |S | r|stdt
| }t
|}|r|rtd|s|std|r|rtd|r|rtd|r|rtd|rtj|rtj|std| ntj| std|  d}|
rt|
}t||	|d}t| o| d}t| |||||||||d
}|rt|tj |S |r3t|| |s1t| td|  |S |s:t| | }|d d kr\|d! d kr\|d" d kr\|sZtd# |S |sctd$ |rit  zt||||d W |ryt	  n|rt	  w w |std |S )%a  Sync files between a local directory and a bucket.

    This is equivalent to the ``hf buckets sync`` CLI command. One of ``source`` or ``dest`` must be a bucket path
    (``hf://buckets/...``) and the other must be a local directory path.

    Args:
        source (`str`, *optional*):
            Source path: local directory or ``hf://buckets/namespace/bucket_name(/prefix)``.
            Required unless using ``apply``.
        dest (`str`, *optional*):
            Destination path: local directory or ``hf://buckets/namespace/bucket_name(/prefix)``.
            Required unless using ``apply``.
        api ([`HfApi`]):
            The HfApi instance to use for API calls.
        delete (`bool`, *optional*, defaults to `False`):
            Delete destination files not present in source.
        ignore_times (`bool`, *optional*, defaults to `False`):
            Skip files only based on size, ignoring modification times.
        ignore_sizes (`bool`, *optional*, defaults to `False`):
            Skip files only based on modification times, ignoring sizes.
        existing (`bool`, *optional*, defaults to `False`):
            Skip creating new files on receiver (only update existing files).
        ignore_existing (`bool`, *optional*, defaults to `False`):
            Skip updating files that exist on receiver (only create new files).
        include (`list[str]`, *optional*):
            Include files matching patterns (fnmatch-style).
        exclude (`list[str]`, *optional*):
            Exclude files matching patterns (fnmatch-style).
        filter_from (`str`, *optional*):
            Path to a filter file with include/exclude rules.
        plan (`str`, *optional*):
            Save sync plan to this JSONL file instead of executing.
        apply (`str`, *optional*):
            Apply a previously saved plan file. When set, ``source`` and ``dest`` are not needed.
        dry_run (`bool`, *optional*, defaults to `False`):
            Print sync plan to stdout as JSONL without executing.
        verbose (`bool`, *optional*, defaults to `False`):
            Show detailed per-file operations.
        quiet (`bool`, *optional*, defaults to `False`):
            Suppress all output and progress bars.
        token (Union[bool, str, None], optional):
            A valid user access token. If not provided, the locally saved token will be used.

    Returns:
        [`SyncPlan`]: The computed (or loaded) sync plan.

    Raises:
        `ValueError`: If arguments are invalid (e.g., both paths are remote, conflicting options).

    Example:
        ```python
        >>> from huggingface_hub import HfApi
        >>> api = HfApi()

        # Upload local directory to bucket
        >>> api.sync_bucket("./data", "hf://buckets/username/my-bucket")

        # Download bucket to local directory
        >>> api.sync_bucket("hf://buckets/username/my-bucket", "./data")

        # Sync with delete and filtering
        >>> api.sync_bucket(
        ...     "./data",
        ...     "hf://buckets/username/my-bucket",
        ...     delete=True,
        ...     include=["*.safetensors"],
        ... )

        # Dry run: preview what would be synced
        >>> plan = api.sync_bucket("./data", "hf://buckets/username/my-bucket", dry_run=True)
        >>> plan.summary()
        {'uploads': 3, 'downloads': 0, 'deletes': 0, 'skips': 1, 'total_size': 4096}

        # Save plan for review, then apply
        >>> api.sync_bucket("./data", "hf://buckets/username/my-bucket", plan="sync-plan.jsonl")
        >>> api.sync_bucket(apply="sync-plan.jsonl")
        ```
    Nr   r   )r%  z,Cannot specify source/dest when using apply.z#Cannot specify both plan and apply.z'Cannot specify delete when using apply.z-Cannot specify ignore_times when using apply.z-Cannot specify ignore_sizes when using apply.z(Cannot specify include when using apply.z(Cannot specify exclude when using apply.z,Cannot specify filter_from when using apply.z)Cannot specify existing when using apply.z0Cannot specify ignore_existing when using apply.z(Cannot specify dry_run when using apply.)enabledzExecuting plan...)r	  r   zSync completed.z7Both source and dest are required (unless using apply).z?Remote to remote sync is not supported. One path must be local.z?One of source or dest must be a bucket path (hf://buckets/...).z2Cannot specify both ignore_times and ignore_sizes.z1Cannot specify both existing and ignore_existing.z%Cannot specify both dry_run and plan.z!Destination must be a directory: z&Source must be an existing directory: r   )
r3   r~   r   rv   r   r   r   r   r   r   zPlan saved to: r   r   r   r   zNothing to sync.z
Syncing...)hf_apir   r_   r  r   r  r  r   r  r   rr   rB   rC   r  r   r   r   r   r  sysstdoutr  r   )r3   r~   r   rv   r   r   r   r   r  r   r!  r   r"  r#  r	  r$  r%  r   	sync_planr   source_is_bucketdest_is_bucketr   r   r   r"   r"   r(   sync_bucket_internal  s   c

*r-  )FFFFFNN)FN)NN)Kr-   r   r   r?   rB   r   r(  rE   collections.abcr   dataclassesr   r   r   r   pathlibr   typingr   r	   r
   rR   r   r   errorsr   utilsr   r   r   r   r   r   r   utils._hf_urisr   r'  r   
get_loggerr*   r   BUCKET_PREFIXr   r   r2   rI   rL   rN   rP   rc   ri   r.   r]   r0   rr   rs   r}   r   r   r   r   r1   floatr   r   r   r   r   r   r  r  r  r  r  r-  r"   r"   r"   r(   <module>   sP  $	
 '1 *"	

L	

 }$+d	



