
    QЦiP              '          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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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9 " S S5      5       r.\ " S S5      5       r/\ " S S5      5       r0\ " S  S!5      5       r1S\(S\)\(\(4   4S" jr2S\(S\34S# jr4\ " S$ S%5      5       r5\ " S& S'5      5       r6 " S( S)5      r7S*\(S\8\)\(\(4      4S+ jr9S,\(S\\)\(\:\;4      4S- jr<S.S/S0\(S1\(S\\)\(\:\;\4      4S2 jr=S3\;S\(4S4 jr>SS5.S\(S6\S7   S8\:S9\;S:\:S;\;S<\(S=\(S>\3S?\3S@\3SA\\   S\54SB jjr?       S\SD\(SE\(S.S/SF\3S?\3S>\3SG\3S@\3SH\\7   SI\\   S\64SJ jjr@SK\6SS4SL jrASK\6SM\(SS4SN jrBSM\(S\64SO jrCS]SK\6S.S/SP\3SI\\   SS4
SQ jjrDSK\6SS4SR jrE  S^SCSCSCSCSCSSSSSSCSCSCSSS.SD\\(   SE\\(   S.S/SF\3S?\3S>\3SG\3S@\3ST\\8\(      SU\\8\(      SV\\(   SK\\(   SW\\(   SX\3SP\3SY\3SZ\\3\(S4   S\64$S[ jjjrFg)_zzShared logic for bucket operations.

This module contains the core buckets logic used by both the CLI and the Python API.
    N)	dataclassfield)datetimetimezone)Path)TYPE_CHECKINGAnyIteratorLiteralOptionalUnion   )	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       W/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/huggingface_hub/_buckets.py_split_bucket_id_and_prefixr(   5   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
)
BucketInfoC   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.   	createdAtr0   
totalFiles )	popr-   r.   r   r/   r0   r1   __dict__updateselfkwargss     r'   __init__BucketInfo.__init__[   sm    **T"zz),(K)@AJJv&	!::l3&v&r)   )r/   r-   r.   r0   r1   N)__name__
__module____qualname____firstlineno____doc__str__annotations__boolr   intr<   __static_attributes__r5   r)   r'   r+   r+   C   s)      	GM
I'r)   r+   c                       \ rS rSr% \\\\4   \S'   \\S'   \	" SS9r
\\   \S'   \	" SS9r\\   \S'   \	" SS	9r\\S
'   \	" SS	9r\\   \S'   SS jrSrg)_BucketAddFiled   sourcedestinationN)defaultxet_hashr0   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   )rR   
isinstancerK   rC   r   	mimetypes
guess_typerL   rF   bytesosr   getmtimetimerQ   )r:   s    r'   __post_init___BucketAddFile.__post_init__n   s     dkkC;// ) 4 4T[[ A! DD$ ) 4 4T5E5E Fq ID8B4;;PU8V8VBGGT[[)D0\`\e\e\gjn\n

r)   )rR   rQ   r   N)r>   r?   r@   rA   r   rC   r   rW   rD   r   rN   r   r0   rF   rQ   rR   r[   rG   r5   r)   r'   rI   rI   d   sg    #tU"###D1Hhsm1-D(3--E"E3""'U"3L(3-3	
r)   rI   c                        \ rS rSr% \\S'   Srg)_BucketDeleteFilez   r   r5   N)r>   r?   r@   rA   rC   rD   rG   r5   r)   r'   r_   r_   z   s    
Ir)   r_   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).
r0   xet_file_datar5   N)	r>   r?   r@   rA   rB   rF   rD   r   rG   r5   r)   r'   rc   rc      s    	 Ir)   rc   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    endpointFrO   	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   )rj   r   ENDPOINTri   replacestrip
startswithr"   r(   r#   r!   rk   r%   rl   )r:   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%   rj   rl   rk   r]   )r>   r?   r@   rA   rB   rC   rD   rj   r   rk   r%   rl   r[   rG   r5   r)   r'   rg   rg      sJ      
HHc&Is&&Is&U#FC#7r)   rg   c                   ^    \ rS rSr% Sr\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   r0   rN   rQ   c                    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      U l        g S U l        g )Nrx   r   r0   xetHashrQ   )r6   rx   r   r0   rN   r   rQ   )r:   r;   rQ   s      r'   r<   BucketFile.__init__   sf    JJv&	JJv&	JJv&	

9-

7D).3^E*

r)   )rQ   r   r0   rx   rN   N)r>   r?   r@   rA   rB   r   rD   rC   rF   r   r   r<   rG   r5   r)   r'   ru   ru      s2     &/
I
IMH>r)   ru   c                   D    \ rS rSr% Sr\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.
	directoryrx   r   uploaded_atc                     UR                  S5      U l        UR                  S5      U l        [        UR                  S5      5      U l        g )Nrx   r   
uploadedAt)r6   rx   r   r   r   r9   s     r'   r<   BucketFolder.__init__   s8    JJv&	JJv&	)&**\*BCr)   )r   rx   r   N)r>   r?   r@   rA   rB   r   rD   rC   r   r<   rG   r5   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 )rq   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.)rq   r   r   s    r'   _is_bucket_pathr      s    ??=))r)   c                       \ rS rSr% Sr\S   \S'   \\S'   Sr\	\
   \S'   Sr\\S	'   Sr\	\   \S
'   Sr\	\   \S'   Sr\	\   \S'   Srg)SyncOperation   z,Represents a sync operation to be performed.)uploaddownloaddeleteskipactionr   Nr0   r    reasonlocal_mtimeremote_mtimebucket_filer5   )r>   r?   r@   rA   rB   r   rD   rC   r0   r   rF   r   r   r   r   ru   rG   r5   r)   r'   r   r      sY    6:;;
ID(3-FC!%K#%"&L(3-&(,K*%,r)   r   c                   v    \ rS rSr% Sr\\S'   \\S'   \\S'   \" \S9r	\\
   \S'   S\\\\\4   4   4S	 jrS
rg)SyncPlani	  z Represents a complete sync plan.rK   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   r0   r   s     r'   r   r     s&     g"99PfCfAs   55)uploads	downloadsdeletesskips
total_size)sumr   )r:   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)   r5   N)r>   r?   r@   rA   rB   rC   rD   r   listr   r   dictr   rF   r   rG   r5   r)   r'   r   r   	  sF    *K
IN&+D&AJ]#A
c5c?23 
r)   r   c                   x    \ rS rSrSr   SS\\\      S\\\      S\\\\\4         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   )r:   r   r   r   s       r'   r<   FilterMatcher.__init__)  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   )r:   r   signpatterns       r'   matchesFilterMatcher.matches:  s     "..MDt--s{" /
 ,,Gt-- - ,,Gt-- -
    r)   )r   r   r   )NNN)r>   r?   r@   rA   rB   r   r   rC   tupler<   rE   r   rG   r5   r)   r'   r   r   &  sh    > 15048<	/"49-/ #49-/ tE#s(O45	/"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-)openrp   rq   append)r   rulesflines       r'   _parse_filter_filer   W  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+
local_pathc              #   J  #    [         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[         R                  R                  XP5      nUR                  [         R                  S5      n[         R                  R                  U5      n[         R                  R                  U5      S-  nXgU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: r   r   N)rX   r   abspathisdirr#   walkjoinrelpathro   sepgetsizerY   )	r   root_filesfilename	full_pathrel_pathr0   mtime_mss	            r'   _list_local_filesr   t  s      ,J77==$$;J<HII''*-HT4Iwwy=H''4H77??9-Dww''	2T9H(**  .s   D!D#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_treerT   r}   r   rq   r"   rsplitrQ   r   r0   )r   r%   r&   itemr   r   r   s          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   r0   r   r   r   z&exists on receiver (--ignore-existing))r   r   )r   r   r   z
same mtimezsize differsz	same size	identicalr5   )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)   FrK   r   r   existingfilter_matcherstatusc
                 0   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      (       aZ  [        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        [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Nf = f! [.         a    [0        R3                  S
U S35         GN_f = f! [*         a     GNLf = 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.rK   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   r0   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   r0   r   r   r   )r   r   r0   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   )#r   r   r#   r   r   nowr   r   r   rX   r   r   r   r   r   r   r8   r"   donebucket_infor1   	Exceptionr   r   loggerdebugsetkeyssortedgetr   r   r   r   r  )"rK   r   r   r   r   r   r  r   r  r  	is_uploadis_downloadplanremote_totalr   r%   r&   local_filesr   r0   r   remote_filesr   	total_str	all_pathsr   
local_inforemote_info
local_sizer   remote_sizer   bucket_file_mapr   s"                                     r'   _compute_sync_planr    s   " $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 &v 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==$$,=j,I($!))(33-18,<K)6MM$>s;?O>PPW"XY	 -J
 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<    ] <6] 6.] -^ 
]]#^^
^^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)rx   rK   r   r   r   
	operation)rx   r   r   r   Nr0   r   r   )rK   r   r   r   writejsondumpsr   r   r   r   r0   r   r   )r  r   r!  r   op_dicts        r'   _write_planr(    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   r(  )r  r)  r   s      r'   
_save_planr,     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   rx   r!  z0Invalid plan file: expected header as first linerK   r   r   r  r   r#  r   r   r0   r   r    r   r   )r   r   r0   r   r   r   )
r   	readlinesr#   r%  loadsr  r   r   r   r   )r)  r   linesr!  r  r   r'  s          r'   
_load_planr1    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at  [        R                  R                  U R                  5      n[        U R                  5      u  pxUR                  S5      n/ n	/ n
U R                   GHZ  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  UR                  S:X  ae  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  UR                  S:X  d  GM*  U(       d  GM4  [        S	UR                   SUR                   S35        GM]     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   rK   r   rX   r   r   r   rstripr   r   r   printr   r   r"   r	  
capitalizebatch_bucket_filesmakedirsdirnamer   download_bucket_filesexistsremovermdirOSError)r  r   r2  r  r  r  r   r%   r&   	add_filesdelete_pathsr   
local_fileremote_pathr$   download_filesdelete_files	file_pathparents                      r'   _execute_planrJ  1  s   #DKK00O_TYY5OI!$++.Qtyy7Q3QKWW__T[[1
.tyy9	s# @B	"$//ByyH$WW\\*gg>
7="''3277M"''"RYYKqAB  *!:;h&7="''3277L	BII;a@A##K0f$RWWIR		{!<= "  LL:c)n-=V!DELL9S->,?v!FGDIIe,779:""%#+t #  % 
.t{{;	s#WW__TYY/
 	J. QS"$//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   5Y
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   r8  rK   r   )r  r   s     r'   _print_plan_summaryrL    s~    llnG	K}D
45	K	*+
,-	M'+./
01	K	*+
,-	Igg&'
()r)   )r   r   r   r  r   includeexcludefilter_fromr  applydry_runr2  quiettokenrM  rN  rO  rP  rQ  rR  rS  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   )rS  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...)r2  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   )
rK   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#   r1  r   rL  r8  r   rJ  r   r   rX   r   r>  r   r   r   r  r(  sysstdoutr,  r   )rK   r   r   r   r   r   r  r   rM  rN  rO  r  rP  rQ  r2  rR  rS  r   	sync_planr  source_is_bucketdest_is_bucketr   r  r   s                            r'   sync_bucket_internalr\    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)GrB   r   r%  rU   rX   rW  rZ   dataclassesr   r   r   r   pathlibr   typingr   r	   r
   r   r   r   r    r   r   errorsr   utilsr   r   r   r   utils._terminalr   rV  r   
get_loggerr>   r  r   r   rC   r   r(   r+   rI   r_   rc   rg   ru   r}   r   rE   r   r   r   r   r   r   rF   floatr   r   r   r  r  r(  r,  r1  rJ  rL  r\  r5   r)   r'   <module>re     s@  
    	 
  ( '  I I   ' [ [ '  
		H	%   c eCHo  ' ' '@ 
 
 
*    $    %7 %7 %7P > > >, D D D,IS IU38_ I*# *$ * 	- 	- 	- 
 
 
8. .bC DsCx,A :+# +(5c53I*J +*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 #ES ESX !.2 cc
c 
c 	c
 c c c c ]+c SMc cV,h ,d ,:X # $ ## #( #V` `w ` `xX[} `hl `F*h *4 *  !n
 !#'#'!%$(%nSMn
3-n 
	n
 n n n n n d3i n d3i n #n 3-n C=n n  !n" #n$ sD!%n& 'nr)   