
    Y jc              &       $   S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKJ	r	  SSK
JrJr  SSKJrJr  SSKJr  SSKJrJrJr  SS	KJrJr  SS
KJr  SSKJrJrJrJr  SSKJ r   \(       a  SSK!J"r"  \RF                  " \$5      r%Sr&Sr'S\(S\)\(\(4   4S jr*\ " S S5      5       r+\ " S S5      5       r,\ " S S5      5       r-\ " S S5      5       r.\" SS9 " S S5      5       r/\ " S S 5      5       r0\ " S! S"5      5       r1\ " S# S$5      5       r2S\(S\)\(\(4   4S% jr3S\(S\44S& jr5\ " S' S(5      5       r6\ " S) S*5      5       r7 " S+ S,5      r8S-\(S\9\)\(\(4      4S. jr:S\(S\)\;\<4   S-  4S/ jr=S0\(S\	\)\(\;\<4      4S1 jr>S2S3S4\(S5\(S\	\)\(\;\<\4      4S6 jr?S7\<S\(4S8 jr@SS9.S\(S:\S;   S<\;S=\<S>\;S?\<S@\(SA\(SB\4SC\4SD\4SE\S-  S\64SF jjrA       S`SH\(SI\(S2S3SJ\4SC\4SB\4SK\4SD\4SL\8S-  SM\S-  S\74SN jjrBSO\7SS4SP jrCSO\7SQ\(SS4SR jrDSQ\(S\74SS jrESaSO\7S2S3ST\4SM\S-  SS4
SU jjrFSO\7SS4SV jrG  SbSGSGSGSGSGSSSSSSGSGSGSSW.SH\(S-  SI\(S-  S2S3SJ\4SC\4SB\4SK\4SD\4SX\9\(   S-  SY\9\(   S-  SZ\(S-  SO\(S-  S[\(S-  S\\4ST\4S]\4S^\4\(-  S-  S\74$S_ jjjrHg)czzShared 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)XetFileDatadisable_progress_barsenable_progress_barsparse_datetime)
StatusLineHfApihf://buckets/  pathreturnc                     U R                  SS5      n[        U5      S:  d  US   (       a
  US   (       d  [        SU  S35      eUS    SUS    3n[        U5      S:  a  US   OSnX#4$ )zSplit 'namespace/name(/optional/prefix)' into ('namespace/name', 'prefix').

Returns (bucket_id, prefix) where prefix may be empty string.
Raises ValueError if path doesn't contain at least namespace/name.
/   r   r   zInvalid bucket path: 'z)'. Expected format: namespace/bucket_name )splitlen
ValueError)r   parts	bucket_idprefixs       i/root/GenerationalWealth/GenerationalWealth/venv/lib/python3.13/site-packages/huggingface_hub/_buckets.py_split_bucket_id_and_prefixr&   6   sw     JJsAE
5zA~U1XU1X1$7`abb8*AeAhZ(IUaU1XRF    c                   R    \ rS rSr% Sr\\S'   \\S'   \\S'   \	\S'   \	\S'   S r
S	rg
)
BucketInfoD   a  
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                 *   UR                  S5      U l        UR                  S5      U l        [        UR                  S5      5      U l        UR                  S5      U l        UR                  S5      U l        U R                  R                  " S0 UD6  g )Nr+   r,   	createdAtr.   
totalFiles )	popr+   r,   r   r-   r.   r/   __dict__update)selfkwargss     r%   __init__BucketInfo.__init__\   sm    **T"zz),(K)@AJJv&	!::l3&v&r'   )r-   r+   r,   r.   r/   N)__name__
__module____qualname____firstlineno____doc__str__annotations__boolr   intr9   __static_attributes__r3   r'   r%   r)   r)   D   s)      	GM
I'r'   r)   c                       \ rS rSr% \\-  \-  \S'   \\S'   \" SS9r	\S-  \S'   \" SS9r
\S-  \S'   \" SS	9r\\S
'   \" SS	9r\S-  \S'   SS jrSrg)_BucketAddFilee   sourcedestinationNdefaultxet_hashr.   Finitmtimecontent_typec                    S U l         [        U R                  [        [        45      (       a(  [
        R                  " U R                  5      S   U l         U R                   c(  [
        R                  " U R                  5      S   U l         [        [        U R                  [        5      (       d,  [        R                  R                  U R                  5      S-  O[        R                  " 5       S-  5      U l        g Nr   r   )rP   
isinstancerH   r@   r   	mimetypes
guess_typerI   rC   bytesosr   getmtimetimerO   r7   s    r%   __post_init___BucketAddFile.__post_init__o   s     dkkC;// ) 4 4T[[ A! DD$ ) 4 4T5E5E Fq ID8B4;;PU8V8VBGGT[[)D0\`\e\e\gjn\n

r'   rP   rO   r   N)r;   r<   r=   r>   r@   r   rV   rA   r   rL   r.   rC   rO   rP   r[   rD   r3   r'   r%   rF   rF   e   sd    $J .HcDj.T*D#**E"E3"$%0L#*0	
r'   rF   c                       \ rS rSr% \\S'   \\S'   \\S'   \\S'   \" SS9r\S-  \S'   \" S	S
9r	\\S'   \" S	S
9r
\S-  \S'   SS jrSrg)_BucketCopyFile{   rI   rL   source_repo_typesource_repo_idNrJ   r.   FrM   rO   rP   c                     [         R                  " U R                  5      S   U l        [	        [
        R
                  " 5       S-  5      U l        g rR   )rT   rU   rI   rP   rC   rY   rO   rZ   s    r%   r[   _BucketCopyFile.__post_init__   s7    %001A1AB1Et+,
r'   r]   r^   )r;   r<   r=   r>   r@   rA   r   r.   rC   rO   rP   r[   rD   r3   r'   r%   r`   r`   {   sS    MT*D#**E"E3"$%0L#*0-r'   r`   c                        \ rS rSr% \\S'   Srg)_BucketDeleteFile   r   r3   N)r;   r<   r=   r>   r@   rA   rD   r3   r'   r%   rg   rg      s    
Ir'   rg   T)frozenc                   .    \ rS rSr% Sr\\S'   \\S'   Srg)BucketFileMetadata   a	  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_datar3   N)	r;   r<   r=   r>   r?   rC   rA   r   rD   r3   r'   r%   rk   rk      s    	 Ir'   rk   c                   ~    \ rS rSr% Sr\\S'   Sr\\S'   \" SS9r	\\S'   \" SS9r
\\S	'   \" SS9r\\S
'   SS jrSrg)	BucketUrl   a  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`)
- handle (`str`)

Args:
    url (`str`):
        String value of the bucket url.
    endpoint (`str`, *optional*):
        Endpoint of the Hub. Defaults to <https://huggingface.co>.
urlr   endpointFrM   	namespacer#   handleNc                    U R                   =(       d    [        R                  U l         U R                  R	                  U R                   S5      R                  S5      nUR                  S5      (       a  U[        S5      S  n[        U5      u  p#U(       a  [        SU R                   35      eUR                  S5      S   U l        X l        SU R                   3U l        g )Nr   r   zbuckets/zUnable to parse bucket URL: r   r   )rr   r   ENDPOINTrq   replacestrip
startswithr    r&   r!   r   rs   r#   rt   )r7   url_pathr#   r$   s       r%   r[   BucketUrl.__post_init__   s    ;);); 88##DMM26<<SAz**J 12H7A	;DHH:FGG"-a0"%dnn%56r'   )r#   rr   rt   rs   r^   )r;   r<   r=   r>   r?   r@   rA   rr   r   rs   r#   rt   r[   rD   r3   r'   r%   ro   ro      sJ      
HHc&Is&&Is&U#FC#7r'   ro   c                   n    \ rS rSr% Sr\S   \S'   \\S'   \\S'   \\S'   \	S-  \S	'   \	S-  \S
'   S r
Srg)
BucketFile   z
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typer   r.   rL   NrO   uploaded_atc                 l   UR                  S5      U l        UR                  S5      U l        UR                  S5      U l        UR                  S5      U l        UR                  SS 5      nU(       a  [        U5      OS U l        UR                  SS 5      nU(       a  [        U5      U l        g S U l        g )Nr   r   r.   xetHashrO   
uploadedAt)r4   r   r   r.   rL   r   rO   r   )r7   r8   rO   r   s       r%   r9   BucketFile.__init__   s    JJv&	JJv&	JJv&	

9-

7D).3^E*
jjt4:E>+64r'   )rO   r   r.   r   r   rL   )r;   r<   r=   r>   r?   r   rA   r@   rC   r   r9   rD   r3   r'   r%   r}   r}      s<     &/
I
IMd?D Pr'   r}   c                   J    \ rS rSr% Sr\S   \S'   \\S'   \S-  \S'   S r	S	r
g)
BucketFolder   z
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.
	directoryr   r   Nr   c                 ,   UR                  S5      U l        UR                  S5      U l        UR                  SS 5      =(       d    UR                  SS 5      nU(       a/  [        U[        5      (       a  UU l        g [        U5       U l        g S U l        g )Nr   r   r   r   )r4   r   r   rS   r   r   r   )r7   r8   r   s      r%   r9   BucketFolder.__init__   s    JJv&	JJv&	jjt4W

=RV8W  '{H==[ 	CQR]C^ 	  	r'   )r   r   r   )r;   r<   r=   r>   r?   r   rA   r@   r   r9   rD   r3   r'   r%   r   r      s(     +

ID 
r'   r   c                     U R                  [        5      (       d  [        SU  S[         35      e[        U R	                  [        5      5      $ )zParse a bucket path like hf://buckets/namespace/bucket_name/prefix into (bucket_id, prefix).

Returns:
    tuple: (bucket_id, prefix) where bucket_id is "namespace/bucket_name" and prefix may be empty string.
zInvalid bucket path: z. Must start with )ry   BUCKET_PREFIXr!   r&   removeprefixr   s    r%   _parse_bucket_pathr      sC     ??=))06HXYY&t'8'8'GHHr'   c                 ,    U R                  [        5      $ )z!Check if a path is a bucket path.)ry   r   r   s    r%   _is_bucket_pathr   
  s    ??=))r'   c                       \ rS rSr% Sr\S   \S'   \\S'   Sr\	S-  \S'   Sr
\\S	'   Sr\S-  \S
'   Sr\S-  \S'   Sr\S-  \S'   Srg)SyncOperationi  z,Represents a sync operation to be performed.)uploaddownloaddeleteskipactionr   Nr.   r   reasonlocal_mtimeremote_mtimebucket_filer3   )r;   r<   r=   r>   r?   r   rA   r@   r.   rC   r   r   r   r   r}   rD   r3   r'   r%   r   r     sY    6:;;
ID#*FC"Kt"#L#*#%)Kd")r'   r   c                   r    \ rS rSr% Sr\\S'   \\S'   \\S'   \" \S9r	\\
   \S'   S\\\\-  4   4S	 jrS
rg)SyncPlani!  z Represents a complete sync plan.rH   dest	timestamp)default_factory
operationsr   c                 *   [        S U R                   5       5      n[        S U R                   5       5      n[        S U R                   5       5      n[        S U R                   5       5      n[        S U R                   5       5      nUUUUUS.$ )Nc              3   H   #    U  H  oR                   S :X  d  M  Sv   M     g7f)r   r   Nr   .0ops     r%   	<genexpr>#SyncPlan.summary.<locals>.<genexpr>+       K/BYY(5Jaa/   "	"c              3   H   #    U  H  oR                   S :X  d  M  Sv   M     g7f)r   r   Nr   r   s     r%   r   r   ,  s     OObyyJ7NOr   c              3   H   #    U  H  oR                   S :X  d  M  Sv   M     g7f)r   r   Nr   r   s     r%   r   r   -  r   r   c              3   H   #    U  H  oR                   S :X  d  M  Sv   M     g7f)r   r   Nr   r   s     r%   r   r   .  s     G"993FAAr   c              3   n   #    U  H+  oR                   S ;   d  M  UR                  =(       d    Sv   M-     g7f)r   r   r   N)r   r.   r   s     r%   r   r   /  s&     g"99PfCfAs   55)uploads	downloadsdeletesskips
total_size)sumr   )r7   r   r   r   r   r   s         r%   summarySyncPlan.summary*  s    K$//KKODOOOO	K$//KKGGGggg
"$
 	
r'   r3   N)r;   r<   r=   r>   r?   r@   rA   r   listr   r   dictrC   r   rD   r3   r'   r%   r   r   !  sA    *K
IN&+D&AJ]#A
c39n- 
r'   r   c            
       x    \ rS rSrSr   SS\\   S-  S\\   S-  S\\\\4      S-  4S jjrS\S	\	4S
 jr
Srg)FilterMatcheri>  z4Matches file paths against include/exclude patterns.Ninclude_patternsexclude_patternsfilter_rulesc                 d    U=(       d    / U l         U=(       d    / U l        U=(       d    / U l        g)zInitialize 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   )r7   r   r   r   s       r%   r9   FilterMatcher.__init__A  s+     !1 6B 0 6B(.Br'   r   r   c                 V   U R                    H'  u  p#[        R                  " X5      (       d  M"  US:H  s  $    U R                   H   n[        R                  " X5      (       d  M     g   U R                   H   n[        R                  " X5      (       d  M     g   U R                  (       a  gg)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   )r7   r   signpatterns       r%   matchesFilterMatcher.matchesR  s     "..MDt--s{" /
 ,,Gt-- - ,,Gt-- -
    r'   )r   r   r   )NNN)r;   r<   r=   r>   r?   r   r@   tupler9   rB   r   rD   r3   r'   r%   r   r   >  sh    > .2-159	/s)d*/ s)d*/ 5c?+d2	/"C D r'   r   filter_filec                    / n[        U 5       nU H  nUR                  5       nU(       a  UR                  S5      (       a  M2  UR                  S5      (       a&  UR                  SUSS R                  5       45        Mn  UR                  S5      (       a&  UR                  SUSS R                  5       45        M  UR                  SU45        M     SSS5        U$ ! , (       d  f       U$ = f)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-)openrx   ry   append)r   rulesflines       r%   _parse_filter_filer   o  s     E	k	aD::<D4??3//s##c48>>#345%%c48>>#345 c4[)  
 L 
	 Ls   CC
C+c                      [         R                  " U 5      n[        R                  " UR                  5      (       a  gUR
                  UR                  S-  4$ ! [         a     gf = f)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   )rW   statOSErrorS_ISDIRst_modest_sizest_mtime)r   sts     r%   _stat_localr     sX    WWT] ||BJJ::r{{T)))	  s   A 
A&%A&
local_pathc              #     #    [         R                  R                  U 5      n [         R                  R                  U 5      (       d  [	        SU  35      e[         R
                  " U 5       H  u  pnU H}  n[         R                  R                  X5      n[        U5      nUc  M2  [         R                  R                  XP5      nUR                  [         R                  S5      nXvS   US   4v   M     M     g7f)zgList all files in a local directory.

Yields:
    tuple: (relative_path, size, mtime_ms) for each file
z Local path must be a directory: Nr   r   r   )rW   r   abspathisdirr!   walkjoinr   relpathrw   sep)r   root_filesfilename	full_path	stat_inforel_paths           r%   _list_local_filesr     s      ,J77==$$;J<HII''*-HT4I#I.I wwy=H''4HaL)A,66  .s   C6C8apir   r#   r$   c              #     #    U R                  X=(       d    SSS9 H  n[        U[        5      (       a  M  UR                  nU(       aP  UR	                  US-   5      (       a  U[        U5      S-   S nO'XB:X  a  SU;   a  UR                  SS5      S   OUnOM}  UnUR                  (       a  UR                  R                  5       S-  OSnXSR                  Xc4v   M     g7f)	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)r$   	recursiver   r   r   r   )
list_bucket_treerS   r   r   ry   r    rsplitrO   r   r.   )r   r#   r$   itemr   r   mtime_mss          r%   _list_remote_filesr     s      $$Y~QU$VdL))yy v|,,Fa 1269Tk4;;sA.r2t H48JJ4::'')D0A		811' Ws   CC r   c                 j    [         R                  " U S-  [        R                  S9R	                  5       $ )z3Convert mtime in milliseconds to ISO format string.r   )tz)r   fromtimestampr   utc	isoformat)r   s    r%   _mtime_to_isor     s&    !!(T/hllCMMOOr'   )r   r   r   source_sizesource_mtime	dest_size
dest_mtimesource_newer_labeldest_newer_labelignore_sizesignore_timesignore_existingr   c                    [        US:X  a  UOU5      n[        US:X  a  UOU5      nU UUUS.nU
(       a  [        SSSS.UD6$ X$:g  nX5-
  [        :  nU(       a9  U(       a  [        SXUS.UD6$ XS-
  [        :  nU(       a  UOSn[        SSUS.UD6$ U	(       a$  U(       a  [        SUSUS.UD6$ [        SSS	S.UD6$ U(       d  U(       a  U(       a  SOUn[        SUUUS.UD6$ [        SSS
S.UD6$ )aS  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
r   )r   r.   r   r   r   z&exists on receiver (--ignore-existing))r   r   )r   r   r   z
same mtimezsize differsz	same size	identicalr3   )r   r   _SYNC_TIME_WINDOW_MS)r   r   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_reasonr   s                       r%   _compare_files_for_syncr    s-   H $Fh4FLJWO$6X3EZ<X &(	#K kF3[k_jkk+L -1EEL rWbrfqrr$37KKJ.8*lK R{RkRR	 n~S^nbmnn R{RkRR<'3^9KF fv;fZeff R{RkRRr'   FrH   r   r   existingfilter_matcherstatusc
                 
   U=(       d
    [        5       n[        U 5      (       + =(       a    [        U5      n
[        U 5      =(       a    [        U5      (       + nU
(       d  U(       d  [        S5      e[        U U[        R
                  " [        R                  5      R                  5       S9nSnU
(       Ga>  [        R                  R                  U 5      n[        U5      u  nn[        R                  R                  U5      (       d  [        SU 35      e0 n[        U5       HK  u  nnnUR                  U5      (       a  UU4UU'   U	(       d  M-  U	R!                  S[#        U5       S35        MM     U	(       a  U	R%                  S[#        U5       S35        0 nU	(       a   UR'                  U5      R(                  n [-        X/U5       HX  u  nnnnUR                  U5      (       a  UU4UU'   U	(       d  M.  Ub  SU 3OSnU	R!                  S	[#        U5       U S35        MZ     U	(       a  U	R%                  S	[#        U5       S35        [5        UR7                  5       5      [5        UR7                  5       5      -  nU	(       a  U	R%                  S[#        U5       S35        [9        U5       GHA  nUR;                  U5      nUR;                  U5      nU(       a|  U(       du  U(       a7  UR<                  R?                  [A        SUUS   S[C        US   5      S95        Mr  UR<                  R?                  [A        SUUS   S[C        US   5      S95        M  U(       a?  U(       a8  Uu  nnUu  nnUR<                  R?                  [E        USUUUUSSUUUS95        M  U(       a  M  U(       d  GM  U(       d  GM  UR<                  R?                  [A        SUUS   S[C        US   5      S95        GMD     U$ [        U 5      u  nn[        R                  R                  U5      n0 n0 n U	(       a   UR'                  U5      R(                  n[-        X/U5       H]  u  nnnn!UR                  U5      (       a  UU4UU'   U!U U'   U	(       d  M3  Ub  SU 3OSnU	R!                  S	[#        U5       U S35        M_     U	(       a  U	R%                  S	[#        U5       S35        0 n[        R                  R                  U5      (       a  U(       a[  [        U5       HK  u  nnnUR                  U5      (       a  UU4UU'   U	(       d  M-  U	R!                  S[#        U5       S35        MM     OeU H_  n[        R                  RG                  UU5      n"[I        U"5      n#U#c  M3  U#UU'   U	(       d  MA  U	R!                  S[#        U5       S35        Ma     U	(       a  U	R%                  S[#        U5       S35        [5        UR7                  5       5      [5        UR7                  5       5      -  nU	(       a  U	R%                  S[#        U5       S35        [9        U5       GHc  nUR;                  U5      nUR;                  U5      nU(       a  U(       d  U(       a7  UR<                  R?                  [A        SUUS   S[C        US   5      S95        Mr  UR<                  R?                  [A        SUUS   S[C        US   5      U R;                  U5      S95        M  U(       aP  U(       aI  Uu  nnUu  nnUR<                  R?                  [E        USUUUUSSUUUU R;                  U5      S95        GM  U(       a  GM  U(       d  GM$  U(       d  GM.  UR<                  R?                  [A        SUUS   S[C        US   5      S95        GMf     U$ ! [*         a     GNf = f! [.         a    [0        R3                  S
U S35         GNf = f! [*         a     GNf = f)zvCompute 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.rH   r   r   NzSource must be a directory: zScanning local directory (z files)r   r   zScanning remote bucket (zBucket 'z' not found, treating as empty.zComparing files (z paths)r   r   znew file (--existing)r   )r   r   r.   r   r   r   znew filezlocal newerzremote newer)r   r   r   r   r  r  r  r  r  r  r  r   znot in source (--delete))r   r   r.   r   r   r   )r   r   r.   r   r   r   )r   r   r   r   r  r  r  r  r  r  r  r   )%r   r   r!   r   r   nowr   r   r   rW   r   r   r   r   r   r   r6   r    donebucket_infor/   	Exceptionr   r   loggerdebugsetkeyssortedgetr   r   r   r   r  r   r   )$rH   r   r   r   r  r  r  r  r  r  	is_uploadis_downloadplanremote_totalr   r#   r$   local_filesr   r.   r   remote_filesr   	total_str	all_pathsr   
local_inforemote_info
local_sizer   remote_sizer   bucket_file_mapr   
local_filer   s$                                       r%   _compute_sync_planr0     ss   " $6}N#F++E0EI!&)G/$2G.GK[vww,,x||,668D  $LWW__V,
.t4	6ww}}Z((;J<HII (9*(E$HdH%%h//)-x(8H%v :3{;K:LGTU	 )F
 KK4S5E4FgNO"y9EE		P/A#RX/Y+$!!))(33.2H-=L*66B6N!L> 2TVIMM$<S=N<OPY{Za"bc 0Z KK23|3D2EWMN ((*+c,2C2C2E.FF	KK+C	N+;7CD9%D$.J&**40K+OO**%#)!%!+A#:(5jm(D OO**%#+!%!+A#-(5jm(D *4'
K,7)\&&+!'$.%0"-#/+8)7%1%1(7  ZKKFF&&!'!(^9%2;q>%Ba &T K] /v6	6WW__T*
 *,"y9EE 6HX^5_1HdHk%%h//*.)9X&,7)v2>2Ja~.PR	 8\9J8KI;V]^_ 6` KK23|3D2EWMN77==$$0A*0M,HdH%--h7715x0@H-v(B3{CSBTT[&\]	 1N !-H!#j(!CJ +J 7I ( ,5K)v(B3{CSBTT[&\] !- KK4S5E4FgNO ))+,s;3C3C3E/FF	KK+C	N+;7CD9%D&**40K$.J:OO**%#)!%!,Q#:)6{1~)F OO**%#-!%!,Q#-)6{1~)F(7(;(;D(A	 ,7)\*4'
K&&+!)$/%1",#.+9)6%1%1(7$3$7$7$=  ![ZZFF&&!'!']9$1*Q-$@e &x K{   # 	PLL8I;.MNO	P^  s<    ^9 <6_
 6._
 -_4 9
__
#_10_14
``r$  c                 $   SU R                   U R                  U R                  U R                  5       S.nUR	                  [
        R                  " U5      S-   5        U R                   H  nSUR                  UR                  UR                  S.nUR                  b  UR                  US'   UR                  b  UR                  US'   UR                  b  UR                  US	'   UR	                  [
        R                  " U5      S-   5        M     g)
z1Write a sync plan as JSONL to a file-like object.header)r   rH   r   r   r   
	operation)r   r   r   r   Nr.   r   r   )rH   r   r   r   writejsondumpsr   r   r   r   r.   r   r   )r$  r   r2  r   op_dicts        r%   _write_planr9    s     ++		^^<<>F GGDJJv%& ooiiGGii	#
 77 ggGFO>>%%'^^GM"??&&(ooGN#	

7#d*+ r'   	plan_filec                 f    [        US5       n[        X5        SSS5        g! , (       d  f       g= f)z!Save a sync plan to a JSONL file.wN)r   r9  )r$  r:  r   s      r%   
_save_planr=  7  s"    	i	D 
		s   "
0c                 |   [        U 5       nUR                  5       nSSS5        W(       d  [        SU  35      e[        R                  " US   5      nUR                  S5      S:w  a  [        S5      e[        US   US   US	   S
9nUSS  H  n[        R                  " U5      nUR                  S5      S:w  a  M0  UR                  R                  [        US   US   UR                  S5      UR                  SS5      UR                  S5      UR                  S5      S95        M     U$ ! , (       d  f       GN= f)z#Load a sync plan from a JSONL file.NzEmpty plan file: r   r   r2  z0Invalid plan file: expected header as first linerH   r   r   r  r   r4  r   r   r.   r   r   r   r   )r   r   r.   r   r   r   )
r   	readlinesr!   r6  loadsr!  r   r   r   r   )r:  r   linesr2  r$  r   r8  s          r%   
_load_planrB  =  s$   	iA 
 ,YK899 ZZa!Fzz&X%KLLhF^%D ab	**T";;v+-x(V_[[({{8R0#KK6$[[8		
	  KC 
s   D,,
D;verbosec                    [        U R                  5      (       + =(       a    [        U R                  5      n[        U R                  5      =(       a    [        U R                  5      (       + nU(       Gab  [        R                  R                  U R                  5      n[        U R                  5      u  pxUR                  S5      n/ n	/ n
U R                   GHH  nUR                  =S:X  a    [        R                  R                  XkR                  5      nU(       a  U SUR                   3OUR                  nU(       a&  [        SUR                   SUR                   S35        U	R                  X45        M  =S:X  af    U(       a  U SUR                   3OUR                  nU(       a&  [        SUR                   SUR                   S35        U
R                  U5        GM  S:X  d  GM  U(       d  GM"  [        S	UR                   SUR                   S35        GMK     U	(       d  U
(       a  U(       az  / nU	(       a  UR                  S
[        U	5       S35        U
(       a  UR                  S[        U
5       S35        UR                  SR                  U5      R!                  5       5        UR#                  UU	=(       d    SU
=(       d    SS9  ggU(       GaU  [        U R                  5      u  pxUR                  S5      n[        R                  R                  U R                  5      n[        R$                  " USS9  / n/ nU R                   GH  nUR                  S:X  a  [        R                  R                  XkR                  5      n[        R$                  " [        R                  R'                  U5      SS9  U(       a&  [        SUR                   SUR                   S35        UR(                  b  UR                  UR(                  U45        M  U(       a  U SUR                   3OUR                  nUR                  X45        GM  UR                  S:X  aj  [        R                  R                  XkR                  5      nU(       a&  [        SUR                   SUR                   S35        UR                  U5        GM{  UR                  S:X  d  GM  U(       d  GM  [        S	UR                   SUR                   S35        GM     [        U5      S:  a6  U(       a  UR                  S[        U5       S35        UR+                  X5        U(       a%  U(       a  UR                  S[        U5       S35        U H  n[        R                  R-                  U5      (       d  M)  [        R.                  " U5        [        R                  R'                  U5      nUU:w  d  Mf   [        R0                  " U5        [        R                  R'                  U5      nUU:w  a  M>  M     gg! [2         a     M  f = f)zExecute a sync plan.r   r   z  Uploading: z ()r   z  Deleting: r   z  Skipping: z
uploading z filesz	deleting z, N)addr   T)exist_okr   z  Downloading: r   zDownloading z	Deleting z local files)r   rH   r   rW   r   r   r   rstripr   r   r   printr   r   r    r  
capitalizebatch_bucket_filesmakedirsdirnamer   download_bucket_filesexistsremovermdirr   )r$  r   rC  r  r"  r#  r   r#   r$   	add_filesdelete_pathsr   r/  remote_pathr"   download_filesdelete_files	file_pathparents                      r%   _execute_planrY  h  s   #DKK00O_TYY5OI!$++.Qtyy7Q3QKWW__T[[1
.tyy9	s# ;=	"$//B))!#j''!BJ;AVHAbggY"7rwwKbggYb1EF$$j%>?;AVHAbggY"7rwwKRWWIR		{!DE ''4wwL	BII;a@A "" LL:c)n-=V!DELL9S->,?v!FGDIIe,779:""%#+t #  % 
.t{{;	s#WW__TYY/
 	J. EG"$//ByyJ&WW\\*gg>
BGGOOJ7$GOBGG9BryykCD>>-"))2>>:*FG;AVHAbggY"7rwwK"));*CDh&WW\\*gg>
L	BII;a@A##J/f$RWWIR		{!<=' ", ~"l3~+>*?vFG%%i@ lKK)C$5#6lCD%Iww~~i((		)$3
*(!#!8 
* &U 
f # s   25X55
YYc                     U R                  5       n[        SU R                   SU R                   35        [        SUS    35        [        SUS    35        [        SUS    35        [        S	US
    35        g)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   rI  rH   r   )r$  r   s     r%   _print_plan_summaryr[    s~    llnG	K}D
45	K	*+
,-	M'+./
01	K	*+
,-	Igg&'
()r'   )r   r  r  r  r  includeexcludefilter_fromr$  applydry_runrC  quiettokenr\  r]  r^  r_  r`  ra  rb  c                   Ub  SSK Jn  U" US9nU(       GaA  U (       d  U(       a  [        S5      eUb  [        S5      eU(       a  [        S5      eU(       a  [        S5      eU(       a  [        S	5      eU(       a  [        S
5      eU	(       a  [        S5      eU
(       a  [        S5      eU(       a  [        S5      eU(       a  [        S5      eU(       a  [        S5      e[        U5      n[	        U(       + S9nU(       d  [        U5        [        S5        U(       a
  [        5          [        UX.US9  U(       a
  [        5         U(       d  [        S5        U$ U (       a  U(       d  [        S5      e[        U 5      n[        U5      nU(       a  U(       a  [        S5      eU(       d  U(       d  [        S5      eU(       a  U(       a  [        S5      eU(       a  U(       a  [        S5      eU(       a  U(       a  [        S5      eU(       aW  [        R                  R                  U5      (       a2  [        R                  R                  U5      (       d  [        SU 35      eO2[        R                  R                  U 5      (       d  [        SU  35      eSnU
(       a  [        U
5      n[!        UU	US9n[	        U(       + =(       a    U(       + S9n[#        U UUUUUUUUUS9
nU(       a  [%        U[&        R(                  5        U$ U(       a.  [+        UU5        U(       d  [        U5        [        SU 35        U$ U(       d  [        U5        UR-                  5       nUS   S :X  a&  US!   S :X  a  US"   S :X  a  U(       d  [        S#5        U$ U(       d  [        S$5        U(       a
  [        5          [        UX.US9  U(       a
  [        5         U(       d  [        S5        U$ ! U(       a  [        5         f f = f! U(       a  [        5         f f = f)%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   )rb  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...)rC  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   )
rH   r   r   r   r  r  r  r  r  r  zPlan saved to: r   r   r   r   zNothing to sync.z
Syncing...)hf_apir   r!   rB  r   r[  rI  r   rY  r   r   rW   r   rO  r   r   r   r0  r9  sysstdoutr=  r   )rH   r   r   r   r  r  r  r  r\  r]  r^  r$  r_  r`  rC  ra  rb  r   	sync_planr  source_is_bucketdest_is_bucketr   r  r   s                            r%   sync_bucket_internalrk    sg   F !% TKLLBCCFGGLMMLMMGHHGHHKLLHIIOPPGHHu%	I.	*%&!#	')S&I$&#$ RSS&v.$T*NNZ[[NZ[[MNNOLMM4@AA 77>>$d(;(;@GHHww}}V$$EfXNOO L)+6"  !N E	 9'k:F"!!'%I Iszz*9d#	*OD6*+ I&!GyQ7;#71#<ASWXAX$%l#ifE " G $& z  " s   )O /O6 O36P
)FFFFFNN)FN)NN)Ir?   r   r6  rT   rW   r   rf  rY   collections.abcr   dataclassesr   r   r   r   pathlibr   typingr	   r
   r   r   r   r   errorsr   utilsr   r   r   r   utils._terminalr   re  r   
get_loggerr;   r  r   r
  r@   r   r&   r)   rF   r`   rg   rk   ro   r}   r   r   rB   r   r   r   r   r   r   rC   floatr   r   r   r   r  r0  r9  r=  rB  rY  r[  rk  r3   r'   r%   <module>ru     s~  
    	  
  $ ( '  . .   ' [ [ '  
		H	%   c eCHo  ' ' '@ 
 
 
* - - -    $    %7 %7 %7P P P P2 
 
 
6IS IU38_ I*# *$ * 	* 	* 	* 
 
 
8. .bC DsCx,A :*c *eCJ/$6 *7# 7(5c53I*J 7,2G 2 2S 2XeTWY\^cehThNiEj 2DPE Pc P$ #ES
ES ()ES 	ES
 ES ES ES ES ES ES ES ES tES ESX !+/rr
r 
r 	r
 r r r r "D(r $Jr rt,h ,d ,:X # $ ## #( #Va aw a asUYz aei aH*h *4 *  n
 ! $ $"#%n$Jn
*n 
	n
 n n n n n #Yn #Yn tn *n :n n  !n" #n$ #:%n& 'nr'   