o
    0iP                  &   @   s  d 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mZ ddl	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mZmZmZmZ dd	lmZmZmZmZmZm Z m!Z!m"Z" e#e$Z%e"d
dZ&de'de(e'e'f fddZ)ddee*e+f de,de'fddZ-ddee de,de'fddZ.		dde/eeef  de,de,de/e' fddZ0			dde1de/e' de'de*d e*de,ddfd!d"Z2e&j3d#g d$d%				dd&ee'e	j4d'df d(ee,e	j5d)d*df d+ee,e	j5d,d-df ded.eddfd/d#Z6de'de,fd0d1Z7e&j3d2g d3d%ddddej8ddfdeee' e	j4d4df dee,e	j5d5d6d7df d8ee,e	j5d9d:df d;ee,e	j5d<d=d>df d?eded.eddfd@dAZ9dBee' de,d8e,d;e,d?ede,d.ee' ddfdCdDZ:de'de,d8e,d;e,d?ede,d.ee' ddfdEdFZ;e&j3dGdHdIgd%		dd&ee'e	j4dJdf ded.eddfdKdGZ<e&j3dLg dMd%				dd&ee'e	j4dJdf dNee,e	j5dOdPdQdf dRee,e	j5dSdTdf ded.eddfdUdLZ=e&j3dVg dWd%							ddee'e	j4dXdf d;ee,e	j5d<d=dYdf dNee,e	j5dOdPdQdf dZee,e	j5d[d\df d]eee/e'  e	j5d^df d_eee/e'  e	j5d`df ded.eddfdadbZ>e&j3dcg ddd%	ddeee'e	j4dfdf dgee'e	j4dhdf d.eddfdidcZ?e&j3djg dkd%																ddleee' e	j4dmdf dneee' e	j4dodf dLee,e	j5dpdf dqee,e	j5drdsdf dtee,e	j5dudvdf dweee' e	j5dxdf dyeee' e	j5dzdf dZee,e	j5d[d{df d]eee/e'  e	j5d|df d_eee/e'  e	j5d}df d~eee' e	j5ddf dee,e	j5dddf dee,e	j5dddf dee,e	j5ddddf dee,e	j5ddddf d.eddf"ddjZ@e&j3dg dd%			ddee'e	j4ddf deee' e	j4ddf ded.eddf
ddZAdS )z7Contains commands to interact with buckets via the CLI.    N)datetime)	AnnotatedOptionalUnion)logging)BUCKET_PREFIX
BucketFileBucketFolderFilterMatcher_is_bucket_path_parse_bucket_path_split_bucket_id_and_prefix)SoftTemporaryDirectory
StatusLineare_progress_bars_disableddisable_progress_barsenable_progress_bars   )	FormatOptOutputFormatQuietOptTokenOptapi_object_to_dict
get_hf_apiprint_list_outputtyper_factoryz"Commands to interact with buckets.)helpargumentreturnc              	   C   sB   |  tr	t| S zt| W S  ty    td|  dt dw )zParse a bucket argument accepting both 'namespace/name(/prefix)' and 'hf://buckets/namespace/name(/prefix)'.

    Returns:
        tuple: (bucket_id, prefix) where bucket_id is "namespace/bucket_name" and prefix may be empty string.
    zInvalid bucket argument: -. Must be in format namespace/bucket_name or znamespace/bucket_name)
startswithr   r   r   
ValueError)r    r"   U/home/kim/smarthome/.venv/lib/python3.10/site-packages/huggingface_hub/cli/buckets.py_parse_bucket_argument=   s   

r$   Fsizehuman_readablec                 C   s`   |st | S dD ]!}| dk r%|dkr|  d|   S | dd|   S | d } q| ddS )zFormat a size in bytes.)BZKBMBGBTBi  r'    z.1fz PB)str)r%   r&   unitr"   r"   r#   _format_sizeN   s   
r.   mtimec                 C   s$   | du rdS |r|  dS |  dS )z0Format mtime datetime to a readable date string.N z%b %d %H:%Mz%Y-%m-%d %H:%M:%S)strftime)r/   r&   r"   r"   r#   _format_mtime\   s
   

r2   itemsquietc                 C   s  i }| D ]=}|j d}|}|dd D ]}||vr di i||< || d }q|d }t|tr;||vr:di i||< qd|i||< qd}	d}
d}|sx| D ]!}t|trmt|j|}t|
t|}
t	|j
|}t|t|}qL|
dkrx|
d | }	g }t||d|	|
|d	 |S )
a  Build a tree representation of files and directories.

    Produces ASCII tree with size and date columns before the tree connector.
    When quiet=True, only the tree structure is shown (no size/date).

    Args:
        items: List of BucketFile/BucketFolder items
        human_readable: Whether to show human-readable sizes and short dates
        quiet: If True, show only the tree structure without sizes/dates

    Returns:
        List of formatted tree lines
    /N__children____item__r      r0   prefix_widthmax_size_widthr&   )pathsplit
isinstancer	   r   r.   r%   maxlenr2   r/   _render_tree)r3   r&   r4   treeitempartscurrentpartZ
final_partr;   r<   Zmax_date_widthsize_strdate_strlinesr"   r"   r#   _build_treee   sJ   

rK   noderJ   indentr;   r<   c              	   C   s*  t |  }t|D ]\}\}}	|t|d k}
|
rdnd}d|	v }|	di }|dkrm|r3d| }n%|	d}|durTt|j|}t|j|}|d	| d
| }nd| }|	| d
| | | |rgdnd  n|	| | | |rydnd  |r||
rdnd }t
||||||d q
dS )z:Recursively render a tree structure with size+date prefix.r   u
   └── u
   ├── r7   r   r+   r8   N>  r5   r0   z    u   │   r:   )sortedr3   	enumeraterA   getr.   r%   r2   r/   appendrB   )rL   rJ   rM   r;   r<   r&   r3   inamevalueZis_lastZ	connectoris_dirchildrenprefixrD   rH   rI   Zchild_indentr"   r"   r#   rB      s:   	

*"rB   create)zhf buckets create my-bucketz hf buckets create user/my-bucketz-hf buckets create hf://buckets/user/my-bucketz*hf buckets create user/my-bucket --privatez+hf buckets create user/my-bucket --exist-ok)rU   Zexamples	bucket_idzTBucket ID: bucket_name, namespace/bucket_name, or hf://buckets/namespace/bucket_nameprivatez	--privatezCreate a private bucket.exist_okz
--exist-okz3Do not raise an error if the bucket already exists.tokenc           
   
   C   s   t |d}| tr6zt| \}}W n ty% } ztt|d}~ww |r4td|  dt d|} |j| |r=|nd|d}	|rKt	|	j
 dS t	d|	j d|	j
 d	 dS )
zCreate a new bucket.r^   Nz-Cannot specify a prefix for bucket creation: . Use namespace/bucket_name or namespace/bucket_name.)r\   r]   zBucket created: z
 (handle: ))r   r    r   r$   r!   typerBadParameterr,   Zcreate_bucketprinthandleurl)
r[   r\   r]   r4   r^   api	parsed_idrY   eZ
bucket_urlr"   r"   r#   rZ      s.   
#

c                 C   s.   |  tr| ttd }d|v S | }d|v S )zFCheck if argument is a bucket ID (namespace/name) vs just a namespace.Nr5   )r    r   rA   )r   r=   r"   r"   r#   _is_bucket_id  s
   
rk   z	list | ls)	zhf buckets listzhf buckets list huggingfacezhf buckets list user/my-bucketz!hf buckets list user/my-bucket -Rz!hf buckets list user/my-bucket -hz%hf buckets list user/my-bucket --treez(hf buckets list user/my-bucket --tree -hz+hf buckets list hf://buckets/user/my-bucketz%hf buckets list user/my-bucket/sub -RzyNamespace (user or org) to list buckets, or bucket ID (namespace/bucket_name(/prefix) or hf://buckets/...) to list files.z--human-readablez-hz$Show sizes in human readable format.as_treez--treez3List files in tree format (only for listing files).	recursivez--recursivez-Rz0List files recursively (only for listing files).formatc              	   C   sH   | duot | }|rt| ||||||d dS t| ||||||d dS )zList buckets or files in a bucket.

    When called with no argument or a namespace, lists buckets.
    When called with a bucket ID (namespace/bucket_name), lists files in the bucket.
    N)r   r&   rl   rm   rn   r4   r^   )	namespacer&   rl   rm   rn   r4   r^   )rk   _list_files_list_buckets)r   r&   rl   rm   rn   r4   r^   Zis_file_moder"   r"   r#   list_cmd  s(   9


rr   ro   c                    s   |rt d|rt d| dur$| tr$| ttd } | d} t|d}dd |j| dD }|sS|sS|tj	krS| durC| n|
 d	 }	td
|	 d dS g d}
dtdtt f fdd}ddd}t||||
||d dS )zList buckets in a namespace.z'Cannot use --tree when listing buckets.z,Cannot use --recursive when listing buckets.Nr5   r_   c                 S      g | ]}t |qS r"   r   ).0bucketr"   r"   r#   
<listcomp>}      z!_list_buckets.<locals>.<listcomp>)ro   rU   z"No buckets found under namespace ''.)idr\   r%   total_files
created_atrD   r   c                    sR   ddl m} || d|| dt| dd d|| d|| d	gS )
Nr   )_format_cellrz   r\   r%   r   r&   r{   r|   )
_cli_utilsr}   rR   r.   )rD   r}   r~   r"   r#   row_fn  s   z_list_buckets.<locals>.row_fnright)r%   r{   )rn   r4   headersr   
alignments)rc   rd   r    r   rA   rstripr   Zlist_bucketsr   jsonZwhoamire   dictlistr,   r   )ro   r&   rl   rm   rn   r4   r^   rh   resultsZresolved_namespacer   r   r   r"   r~   r#   rq   f  s$   




rq   c              
   C   s  |r|t jkrtdt|d}zt| \}}	W n ty, }
 ztt|
d}
~
ww t|j	||	p4d|d}|sAt
d dS tdd |D }|t jkr`dd	 |D }t
tj|d
d nj|rst|||d}|D ]}t
| qknW|r|D ]}t|trt
|j d qwt
|j qwn<|D ]9}t|trt|j|}t
ddd|dd|j d qt|j|}t|j|}t
|dd|dd|j  q|s|rt d dS dS dS )zList files in a bucket.z%Cannot use --tree with --format json.r_   NrY   rm   z(empty)c                 s   s    | ]}t |tV  qd S N)r?   r	   ru   rD   r"   r"   r#   	<genexpr>  s    z_list_files.<locals>.<genexpr>c                 S   rs   r"   rt   r   r"   r"   r#   rw     rx   z_list_files.<locals>.<listcomp>r9   rM   )r&   r4   r5   r0   z>12rO   z>19z!Use -R to list files recursively.)r   r   rc   rd   r   r$   r!   r,   r   list_bucket_treere   anydumpsrK   r?   r	   r=   r2   Zuploaded_atr.   r%   r/   r   done)r   r&   rl   rm   rn   r4   r^   rh   r[   rY   rj   r3   Zhas_directoriesr   Z
tree_lineslinerD   Z	mtime_strrH   r"   r"   r#   rp     sX   





" rp   infozhf buckets info user/my-bucketz+hf buckets info hf://buckets/user/my-bucketzFBucket ID: namespace/bucket_name or hf://buckets/namespace/bucket_namec              
   C   sx   t |d}zt| \}}W n ty  } ztt|d}~ww ||}|r/t|j dS tt	j
t|dd dS )zGet info about a bucket.r_   Nr9   r   )r   r$   r!   rc   rd   r,   Zbucket_infore   rz   r   r   r   )r[   r4   r^   rh   ri   _rj   rv   r"   r"   r#   r     s   

delete)z hf buckets delete user/my-bucketz-hf buckets delete hf://buckets/user/my-bucketz&hf buckets delete user/my-bucket --yesz-hf buckets delete user/my-bucket --missing-okyesz--yesz-yzSkip confirmation prompt.
missing_okz--missing-okz3Do not raise an error if the bucket does not exist.c           
   
   C   s   |  tr2zt| \}}W n ty  } ztt|d}~ww |r/td|  dt d|} nd| vrBtd|  dt d|sWtd|  d	}|sWtd
 t	 t
|d}	|	j| |d |rkt|  dS td|   dS )zDelete a bucket.

    This deletes the entire bucket and all its contents. Use `hf buckets rm` to remove individual files.
    Nz-Cannot specify a prefix for bucket deletion: r`   ra   r5   zInvalid bucket ID: r   z(Are you sure you want to delete bucket ''?Aborted.r_   )r   zBucket deleted: )r    r   r$   r!   rc   rd   r,   confirmre   Abortr   Zdelete_bucket)
r[   r   r   r4   r^   ri   rY   rj   r   rh   r"   r"   r#   r     s<   
&
zremove | rm)z)hf buckets remove user/my-bucket/file.txtz2hf buckets rm hf://buckets/user/my-bucket/file.txtz.hf buckets rm user/my-bucket/logs/ --recursivez:hf buckets rm user/my-bucket --recursive --include "*.tmp"z8hf buckets rm user/my-bucket/data/ --recursive --dry-runzBucket path: namespace/bucket_name/path or hf://buckets/namespace/bucket_name/path. With --recursive, namespace/bucket_name is also accepted to target all files.z0Remove files recursively under the given prefix.dry_runz	--dry-runz8Preview what would be deleted without actually deleting.includezQInclude only files matching pattern (can specify multiple). Requires --recursive.excludezLExclude files matching pattern (can specify multiple). Requires --recursive.c              
      s&  zt | \}}	W n ty }
 ztt|
d}
~
ww |	dkr.|s.td| d| d|s2|r9|s9tdt|d}|r8t| d}|d	 g }|j||		d
pWdddD ]}t
|trr|| |dt| d q[|dt| d |s|rt||d  fdd|D }n|}dd |D }tdd |D }t|dd}|s|std dS t| d| }|s|s|s|D ]	}td|  qtd| d| d}|std t |r|D ]}tdt | d
|  qtd| d dS |j||d  |r|D ]}t| qdS |D ]}tdt | d
|  qtd!| d| d" dS |		d
}|sEtd#|rZtdt | d
|  td$ dS |sttd%| d&| d}|sttd t |j||gd  |rt| dS tdt | d
|  dS )'zbRemove files from a bucket.

    To delete an entire bucket, use `hf buckets delete` instead.
    Nr0   z?No file path specified. To remove files, provide a path (e.g. 'zd/FILE') or use --recursive to remove all files. To delete the entire bucket, use `hf buckets delete z`.z,--include and --exclude require --recursive.r_   )enabledzListing files from remoter5   Tr   zListing files from remote (z files))Zinclude_patternsZexclude_patternsc                    s   g | ]
}  |jr|qS r"   )matchesr=   ru   fZmatcherr"   r#   rw     s    zremove.<locals>.<listcomp>c                 S   s   g | ]}|j qS r"   )r=   r   r"   r"   r#   rw     s    c                 s   s    | ]}|j V  qd S r   )r%   r   r"   r"   r#   r     s    zremove.<locals>.<genexpr>r~   zNo files to remove.z file(s) totaling rO   zRemove z from 'r   r   zdelete: z
(dry run) z would be removed.)r   zRemoved ry   zFile path cannot be empty.z"(dry run) 1 file would be removed.zRemove 'z' from ')r$   r!   rc   rd   r,   r   r   updater   r   r?   r   rS   rA   r   r
   sumr.   re   r   r   r   batch_bucket_files)r   rm   r   r   r   r   r4   r^   r[   rY   rj   rh   status	all_filesrD   Zmatched_files
file_pathsZ
total_sizerH   Zcount_labelr=   r   	file_pathr"   r   r#   remove<  s   >







r   move)z/hf buckets move user/old-bucket user/new-bucketz/hf buckets move user/my-bucket my-org/my-bucketzIhf buckets move hf://buckets/user/old-bucket hf://buckets/user/new-bucketfrom_idzMSource bucket ID: namespace/bucket_name or hf://buckets/namespace/bucket_nameto_idzRDestination bucket ID: namespace/bucket_name or hf://buckets/namespace/bucket_namec                 C   s   t | \}}|rtd|  dt dt |\}}|r(td| dt dt|d}|j||d td| d|  dS )	z2Move (rename) a bucket to a new name or namespace.z)Cannot specify a prefix for bucket move: r`   ra   r_   )r   r   zBucket moved:  -> N)r$   rc   rd   r   r   Zmove_bucketre   )r   r   r^   Zparsed_from_idZfrom_prefixZparsed_to_idZ	to_prefixrh   r"   r"   r#   r     s"   
sync)z2hf buckets sync ./data hf://buckets/user/my-bucketz2hf buckets sync hf://buckets/user/my-bucket ./dataz;hf buckets sync ./data hf://buckets/user/my-bucket --deletez^hf buckets sync hf://buckets/user/my-bucket ./data --include "*.safetensors" --exclude "*.tmp"zIhf buckets sync ./data hf://buckets/user/my-bucket --plan sync-plan.jsonlz'hf buckets sync --apply sync-plan.jsonlz<hf buckets sync ./data hf://buckets/user/my-bucket --dry-runzChf buckets sync ./data hf://buckets/user/my-bucket --dry-run | jq .sourcezKSource path: local directory or hf://buckets/namespace/bucket_name(/prefix)destzPDestination path: local directory or hf://buckets/namespace/bucket_name(/prefix)z/Delete destination files not present in source.ignore_timesz--ignore-timesz;Skip files only based on size, ignoring modification times.ignore_sizesz--ignore-sizesz<Skip files only based on modification times, ignoring sizes.planz=Save sync plan to JSONL file for review instead of executing.applyz#Apply a previously saved plan file.z5Print sync plan to stdout as JSONL without executing.z6Include files matching pattern (can specify multiple).z6Exclude files matching pattern (can specify multiple).filter_fromz(Read include/exclude patterns from file.existingz
--existingzASkip creating new files on receiver (only update existing files).ignore_existingz--ignore-existingzCSkip updating files that exist on receiver (only create new files).verbosez	--verbosez-vz%Show detailed logging with reasoning.z--quietz-qzMinimal output.c                 C   s6   t |d}|j| ||||||||	|
|||||d dS )z0Sync files between local directory and a bucket.r_   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r4   N)r   Zsync_bucket)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r4   r^   rh   r"   r"   r#   r     s$   
t
cp)z5hf buckets cp hf://buckets/user/my-bucket/config.jsonz=hf buckets cp hf://buckets/user/my-bucket/config.json ./data/zDhf buckets cp hf://buckets/user/my-bucket/config.json my-config.jsonz7hf buckets cp hf://buckets/user/my-bucket/config.json -z8hf buckets cp my-config.json hf://buckets/user/my-bucketz>hf buckets cp my-config.json hf://buckets/user/my-bucket/logs/zKhf buckets cp my-config.json hf://buckets/user/my-bucket/remote-config.jsonz7hf buckets cp - hf://buckets/user/my-bucket/config.jsonsrcz9Source: local file, hf://buckets/... path, or - for stdindstz?Destination: local path, hf://buckets/... path, or - for stdoutc              	   C   s  t |d}t| }|duot|}| dk}|dk}|r"|r"td|s6|s6|s6|du r1tdtd|r?|s?td|r]|r]|dusIJ t|\}	}
|
dksX|
d	r]td
|rf|sftd|su|sutj| rutd|rdt| \}}
|
dks|
d	rtd|
	d	dd }|rt
 }|st  zWt B}tj||}|||
|fg t|d}|d }rtjj| |d }sW d   n1 sw   Y  W d   n1 sw   Y  W |st  dS dS |st  w w |du r|}ntj|s|tjs|d	r!tj||}n|}tj|}|r3tj|dd |r9t  z|||
|fg W |rJt  n|rRt  w w |sbtd|  d|  dS dS |rt|\}}tjj }|ryt  z|j|||fgd W |rt  n|rt  w w |std|  dS dS tj| std|  t|\}}
|
dkrtj| }n|
d	r|
tj|  }n|
}|rt  z|j|| |fgd W |rt  n|rt  w w |s	td|  dt | d	|  dS dS )z'Copy a single file to or from a bucket.r_   N-z$Remote-to-remote copy not supported.z2Missing destination. Provide a bucket path as DST.z;One of SRC or DST must be a bucket path (hf://buckets/...).z+Stdin upload requires a bucket destination.r0   r5   zAStdin upload requires a full destination path including filename.z"Cannot pipe to stdout for uploads.zNSource must be a file, not a directory. Use `hf buckets sync` for directories.zJSource path must include a file name, not just a bucket or directory path.r   r6   rbi HT)r]   zDownloaded: r   )addzUploaded: stdin -> zSource file not found: z
Uploaded: )r   r   rc   rd   r   endswithosr=   isdirrsplitr   r   r   joinZdownload_bucket_filesopenreadsysstdoutbufferwriter   sepdirnamemakedirsre   stdinr   isfilebasenamer   )r   r   r4   r^   rh   Zsrc_is_bucketZdst_is_bucketZsrc_is_stdinZdst_is_stdoutr   rY   r[   filenameZpbar_was_disabledZtmp_dirZtmp_pathr   chunkZ
local_path
parent_dirZremote_pathdatar"   r"   r#   r     s   










(
")F)FF)r   r   F)FFFN)FN)FFFNNFNr   )NNFFFNNFNNNFFFFN)NFN)B__doc__r   r   r   r   typingr   r   r   rc   Zhuggingface_hubr   Zhuggingface_hub._bucketsr   r   r	   r
   r   r   r   Zhuggingface_hub.utilsr   r   r   r   r   r   r   r   r   r   r   r   r   r   Z
get_logger__name__loggerZbuckets_clir,   tupler$   intfloatboolr.   r2   r   rK   r   rB   commandZArgumentOptionrZ   rk   tablerr   rq   rp   r   r   r   r   r   r   r"   r"   r"   r#   <module>   s  $	(

 
C
,2	
!"#$C
0
A	<
!
'
-./ *!'-4
:
@FMT\de 