o
    0i                  
   @   s  U d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZmZ d dlmZ d dlmZ d dlmZmZ d d	lmZmZmZmZmZmZ d d
lmZmZ d dlZd dlZd dlm Z m!Z!m"Z" d dl#m$Z$ ddl%m&Z& ddl'm(Z(m)Z) ddl*m+Z+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9 ddl:m;Z;m<Z<m=Z=m>Z> ddl?m@Z@ eAdejBZCeG dd dZDeG dd deDZEeG dd deDZFeGejHZIeeJd< G dd deIZKG dd  d ejHeKd!ZLG d"d# d#ejMjNZOG d$d% d%ejMjNZPd&eQd'eQfd(d)ZRd*eQd'eQfd+d,ZSd-eQd.eeT d'efd/d0ZUd1eLd-eQd2eQd3eVd4eQf
d5d6ZWd7d8 ZXeL ZYdS )9    N)deque)	ExitStack)deepcopy)	dataclassfield)datetime)chain)PathPurePosixPath)AnyIterableIteratorNoReturnOptionalUnion)quoteunquote)_DEFAULT_CALLBACKNoOpCallbackTqdmCallback)
isfilelike   )	constants)CommitOperationCopyCommitOperationDelete)BucketNotFoundErrorEntryNotFoundErrorHfHubHTTPErrorRepositoryNotFoundErrorRevisionNotFoundError)
hf_hub_urlhttp_get)
BucketFileBucketFolderHfApiLastCommitInfoRepoFile
RepoFolder)HFValidationErrorhf_raise_for_statushttp_backoffhttp_stream_backoff)md5zy
    (^refs\/convert\/\w+)     # `refs/convert/parquet` revisions
    |
    (^refs\/pr\/\d+)          # PR revisions
    c                   @   s0   e Zd ZU dZeed< eed< defddZdS )HfFileSystemResolvedPathz_Top level Data structure containing information about a resolved Hugging Face file system path.rootpathreturnc                 C   s   | j  d| j dS )N/)r.   r/   rstripself r5   X/home/kim/smarthome/.venv/lib/python3.10/site-packages/huggingface_hub/hf_file_system.py	unresolve5   s   z"HfFileSystemResolvedPath.unresolveN)__name__
__module____qualname____doc__str__annotations__r7   r5   r5   r5   r6   r-   .   s
   
 r-   c                   @   sv   e Zd ZU dZeed< eed< eed< eed< eddZeed< eddZeed	< ed
ddZ	e
e ed< dd Zd
S )"HfFileSystemResolvedRepositoryPathzLData structure containing information about a resolved path in a repository.	repo_typerepo_idrevisionpath_in_repoFinitr.   r/   N)defaultrepr_raw_revisionc                 C   sf   t j| jd| j }| jr| d| j | _n| jt jkr*| dt	| j | _n|| _| j
| _d S )N @)r   REPO_TYPES_URL_PREFIXESgetr?   r@   rG   r.   rA   DEFAULT_REVISIONsafe_revisionrB   r/   )r4   	repo_pathr5   r5   r6   __post_init__G   s   z0HfFileSystemResolvedRepositoryPath.__post_init__)r8   r9   r:   r;   r<   r=   r   r.   r/   rG   r   rO   r5   r5   r5   r6   r>   9   s   
 r>   c                   @   s4   e Zd ZU dZeed< eddZeed< dd ZdS )	HfFileSystemResolvedBucketPathzHData structure containing information about a resolved path in a bucket.	bucket_idFrC   r.   c                 C   s   d| j  | _d S )Nzbuckets/)rQ   r.   r3   r5   r5   r6   rO   Y   s   z,HfFileSystemResolvedBucketPath.__post_init__N)	r8   r9   r:   r;   r<   r=   r   r.   rO   r5   r5   r5   r6   rP   R   s
   
 rP   _cached_basec                       s(   e Zd ZdZ fddZdd Z  ZS )_Cacheda  
    Metaclass for caching HfFileSystem instances according to the args.

    This creates an additional reference to the filesystem, which prevents the
    filesystem from being garbage collected when all *user* references go away.
    A call to the :meth:`AbstractFileSystem.clear_instance_cache` must *also*
    be made for a filesystem instance to be garbage collected.

    This is a slightly modified version of `fsspec.spec._Cached` to improve it.
    In particular in `_tokenize` the pid isn't taken into account for the
    `fs_token` used to identify cached instances. The `fs_token` logic is also
    robust to defaults values and the order of the args. Finally new instances
    reuse the states from sister instances in the main thread.
    c                    s   t  j|i | i | _d S N)super__init___cache)clsargskwargs	__class__r5   r6   rV   q   s   
z_Cached.__init__c           
      O   s   | dd}| j| t g|R i |}| j| t jg|R i |}|s7| jr7|| jv r7|| _| j| S t	j
| g|R i |}|sc| jrc|| jv rc| j|  }| D ]
\}}	t|||	 qX||_||_||_| jry|sy|| _|| j|< |S )NZskip_instance_cacheF)pop	_tokenize	threading	get_identmain_threadidentZcachablerW   Z_latesttype__call___get_instance_stateitemssetattrZ
_fs_token_storage_argsstorage_options)
rX   rY   rZ   skipZfs_tokenZfs_token_main_threadobjinstance_stateattrstate_valuer5   r5   r6   rd   y   s$    


z_Cached.__call__)r8   r9   r:   r;   rV   rd   __classcell__r5   r5   r[   r6   rS   a   s    rS   c                       sp  e Zd ZdZdZdZddddddee dee	edf dee
 d	ee	 f fd
dZede
defddZdededee dee	ee f fddZdedee	ee f fddZ	dTdedee deeef fddZdTdee ddfddZ			dUdededee
 dee ded f
d d!ZdTdedee ddfd"d#Z	$		dVded%e	d&ee
 dee ddf
d'd(Z	dWded*e	d+e	dee deeeeeef f  f
d,d-Z	$	$			dXded%e	d+e	dee d	ee	 d&ee
 fd.d/Zded0ed%e	deeee f  fd1d2Z!dede"eeee ee f  f fd3d4Z#dTded&ee
 dee f fd5d6Z$		$	$	$	dYded&ee
 d7e	d*e	d+e	dee deee eeeeef f f fd8d9Z%dTd:ed;edee ddfd<d=Z&dede'fd>d?Z(dZded+e	dee deeef fd@dAZ)dBdC Z*dDdE Z+dFdG Z,dedefdHdIZ-e.dfd[ fdJdKZ/e0dLdM Z1dNdO Z2dPdQ Z3dRdS Z4  Z5S )\HfFileSystemaz
  
    Access a remote Hugging Face Hub repository as if were a local file system.

    > [!WARNING]
    > [`HfFileSystem`] provides fsspec compatibility, which is useful for libraries that require it (e.g., reading
    >     Hugging Face datasets directly with `pandas`). However, it introduces additional overhead due to this compatibility
    >     layer. For better performance and reliability, it's recommended to use `HfApi` methods when possible.

    The file system supports paths for the `hf://` protocol, which follows those URL schemes:

    * Models, Datasets and Spaces repositories:

        ```
        hf://<repo-id>[@<revision>]/<path/in/repo>
        hf://datasets/<repo-id>[@<revision>]/<path/in/repo>
        hf://spaces/<repo-id>[@<revision>]/<path/in/repo>
        ```

    * Buckets (generic storage):

        ```
        hf://buckets/<bucket-id>/<path/in/bucket>
        ```

    Note: when using the [`HfFileSystem`] directly, passing the `hf://` protocol prefix is optional in paths.

    Args:
        endpoint (`str`, *optional*):
                Endpoint of the Hub. Defaults to <https://huggingface.co>.
        token (`bool` or `str`, *optional*):
            A valid user access token (string). Defaults to the locally saved
            token, which is the recommended method for authentication (see
            https://huggingface.co/docs/huggingface_hub/quick-start#authentication).
            To disable authentication, pass `False`.
        block_size (`int`, *optional*):
            Block size for reading and writing files.
        expand_info (`bool`, *optional*):
            Whether to expand the information of the files.
        **storage_options (`dict`, *optional*):
            Additional options for the filesystem. See [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.__init__).

    Usage:

    ```python
    >>> from huggingface_hub import hffs

    >>> # List files
    >>> hffs.glob("my-username/my-model/*.bin")
    ['my-username/my-model/pytorch_model.bin']
    >>> hffs.ls("datasets/my-username/my-dataset", detail=False)
    ['datasets/my-username/my-dataset/.gitattributes', 'datasets/my-username/my-dataset/README.md', 'datasets/my-username/my-dataset/data.json']

    >>> # Read/write files
    >>> with hffs.open("my-username/my-model/pytorch_model.bin") as f:
    ...     data = f.read()
    >>> with hffs.open("my-username/my-model/pytorch_model.bin", "wb") as f:
    ...     f.write(data)
    ```

    Specify a token for authentication:
    ```python
    >>> from huggingface_hub import HfFileSystem
    >>> hffs = HfFileSystem(token=token)
    ```
    rH   ZhfN)endpointtoken
block_sizeexpand_inforq   rr   rs   rt   c                   sT   t  j|i | |ptj| _|| _t||d| _|| _|| _	i | _
i | _i | _d S )N)rq   rr   )rU   rV   r   ENDPOINTrq   rr   r$   _apirs   rt   _repo_and_revision_exists_cache_bucket_exists_cachedircache)r4   rq   rr   rs   rt   rY   ri   r[   r5   r6   rV      s   	
zHfFileSystem.__init__threading_identr0   c                    s\     dptj d<   d d<  fddt D  | || f}tt| }| S )zDeterministic token for cachingrq   rr   c                       i | ]}| | qS r5   r5   ).0keyrZ   r5   r6   
<dictcomp>       z*HfFileSystem._tokenize.<locals>.<dictcomp>)rK   r   ru   sortedr,   r<   encode	hexdigest)rX   rz   rY   rZ   Ztokenize_argshr5   r~   r6   r^      s   zHfFileSystem._tokenizer?   r@   rA   c              
   C   s   |||f| j vrqz| jj|||tjd W nK ttfy= } zd|f| j |||f< d|f| j ||d f< W Y d }~n8d }~w ty` } zd|f| j |||f< d| j ||d f< W Y d }~nd }~ww d| j |||f< d| j ||d f< | j |||f S )N)rA   r?   timeoutFTN)rw   rv   Z	repo_infor   ZHF_HUB_ETAG_TIMEOUTr   r(   r   )r4   r?   r@   rA   er5   r5   r6   _repo_and_revision_exist   s"   

 z%HfFileSystem._repo_and_revision_existrQ   c              
   C   sb   || j vr,z| j| W n ty& } zd|f| j |< W Y d }~n
d }~ww d| j |< | j | S )NFr   )rx   rv   Zbucket_infor   )r4   rQ   r   r5   r5   r6   _bucket_exists  s   


zHfFileSystem._bucket_existsr/   c                 C   s  dt t dt t dt t fdd}| |}|std|dd d	krQd|dd
d }d|ddd }| |\}}|sKt|| t||dS |dd d t	j
 v rud|vrgtd|dd
\}}t	j| }nt	j}|ddkr=dd|ddd v r|dd
\}}	d|	v rt|	}
|
dur|d|
 fv rtd|	d}|
 }	n|	dd
\}	}nd}|t|	|}| |||\}}|st|| nd}	d|ddd }d|ddd }|dd }d|dd
d }|}|}| |||\}}|s<t|ttfr7|}|}| |||\}}|s6t|| n1t|| n+|}d}d|v rV|dd
\}}	|t|	|}nd}	| |||\}}|shtd|duro|nt	j}t|||||	dS )a  
        Resolve a Hugging Face file system path into its components.

        Args:
            path (`str`):
                Path to resolve.
            revision (`str`, *optional*):
                The revision of the repo to resolve. Defaults to the revision specified in the path.

        Returns:
            [`HfFileSystemResolvedPath`]: Resolved path information containing `repo_type`, `repo_id`, `revision` and `path_in_repo`.

        Raises:
            `ValueError`:
                If path contains conflicting revision information.
            `NotImplementedError`:
                If trying to list repositories.
        revision_in_pathrA   r0   c                 S   s:   |d ur| d ur| |krt d|  d| d|S | }|S )NzRevision specified in path ("z ") and in `revision` argument ("z") are not the same.)
ValueError)r   rA   r5   r5   r6   %_align_revision_in_path_with_revision3  s   zHHfFileSystem.resolve_path.<locals>._align_revision_in_path_with_revisionz<Access to buckets and repositories lists is not implemented.r1   r   Zbucketsr      N)rQ   r/   z0Access to repositories lists is not implemented.rI      rH   )rG   )r   r<   Z_strip_protocolNotImplementedErrorsplitjoinr   _raise_file_not_foundrP   r   rJ   valuesZREPO_TYPES_MAPPINGZREPO_TYPE_MODELcountSPECIAL_REFS_REVISION_REGEXsearchgroupsublstripr   r   
isinstancer   r(   rL   r>   )r4   r/   rA   r   rQ   Zbucket_existserrr?   r@   r   matchrB   Zrepo_and_revision_existZrepo_id_with_namespaceZpath_in_repo_with_namespaceZrepo_id_without_namespaceZpath_in_repo_without_namespace_r5   r5   r6   resolve_path  s   









zHfFileSystem.resolve_pathc                 C   s   |s| j   | j  dS | |}| }|r'| j |d | |}|s|jsTt|t	rJ| j|j
|jdfd | j|j
|j|jfd dS | j|jd dS dS )ac  
        Clear the cache for a given path.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.invalidate_cache).

        Args:
            path (`str`, *optional*):
                Path to clear from cache. If not provided, clear the entire cache.

        N)ry   clearrw   r   r7   r]   _parentr/   r   r>   r?   r@   rA   rx   rQ   )r4   r/   resolved_pathr5   r5   r6   invalidate_cache  s&   



zHfFileSystem.invalidate_cacherbmode)HfFileSystemFileHfFileSystemStreamFilec                 K   sj   |d ur|n| j }|d ur||d< d|v rtd|dkr)t| |f||d|S t| |f||d|S )Nrs   az/Appending to remote files is not yet supported.r   )r   rA   )rs   r   r   r   )r4   r/   r   rs   rA   rZ   r5   r5   r6   _open  s   zHfFileSystem._openc              
   K   st   | j ||d}t|tr| jj|j|jgd n| jj|j|j	| j
|j|j|d|dd | j| d d S )NrA   deletecommit_messagecommit_description)rB   r@   rr   r?   rA   r   r   r/   )r   r   rP   rv   batch_bucket_filesrQ   r/   Zdelete_filerB   r@   rr   r?   rA   rK   r   r7   )r4   r/   rA   rZ   r   r5   r5   r6   _rm  s   
	zHfFileSystem._rmF	recursivemaxdepthc              
      s    j ||d} j||||d}t|tr( fdd|D } jj|j|d nD fdd|D }	dd |	D }
d| d	}||rCd
nd7 }||durQd| d	nd7 } jj|j|j	 j
|
|j|d||dd  j| d dS )a  
        Delete files from a repository.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.rm).

        > [!WARNING]
        > Note: When possible, use `HfApi.delete_file()` for better performance.

        Args:
            path (`str`):
                Path to delete.
            recursive (`bool`, *optional*):
                If True, delete directory and all its contents. Defaults to False.
            maxdepth (`int`, *optional*):
                Maximum number of subdirectories to visit when deleting recursively.
            revision (`str`, *optional*):
                The git revision to delete from.

        r   )r   r   rA   c                    "   g | ]}  |s |jqS r5   isdirr   r/   r|   r/   r3   r5   r6   
<listcomp>     " z#HfFileSystem.rm.<locals>.<listcomp>r   c                    r   r5   r   r   r3   r5   r6   r     r   c                 S   s   g | ]}t |d qS ))rB   )r   )r|   rB   r5   r5   r6   r     r   zDelete  zrecursively rH   Nzup to depth r   r   )r@   r?   rr   
operationsrA   r   r   r   )r   Zexpand_pathr   rP   rv   r   rQ   create_commitr@   r?   rr   rA   rK   r   r7   )r4   r/   r   r   rA   rZ   r   pathsr   Zpaths_in_repor   r   r5   r3   r6   rm  s(   

	zHfFileSystem.rmTdetailrefreshc                    s   | j  |d}|  z| j f||d|}W nB ty[   |js(t d z| j|  f||d|}W n tyD   g }Y nw  fdd|D }t|dkrYt d Y nw |r`|S dd |D S )a  
        List the contents of a directory.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.ls).

        > [!WARNING]
        > Note: When possible, use `HfApi.list_repo_tree()` for better performance.

        Args:
            path (`str`):
                Path to the directory.
            detail (`bool`, *optional*):
                If True, returns a list of dictionaries containing file information. If False,
                returns a list of file paths. Defaults to True.
            refresh (`bool`, *optional*):
                If True, bypass the cache and fetch the latest data. Defaults to False.
            revision (`str`, *optional*):
                The git revision to list from.

        Returns:
            `list[Union[str, dict[str, Any]]]`: List of file paths (if detail=False) or list of file information
            dictionaries (if detail=True).
        r   )r   rA   Nc                       g | ]
}|d   kr|qS namer5   r|   or   r5   r6   r   "      z#HfFileSystem.ls.<locals>.<listcomp>r   c                 S   s   g | ]}|d  qS r   r5   r   r5   r5   r6   r   %  s    )r   r7   _ls_treer   r/   r   r   len)r4   r/   r   r   rA   rZ   r   outr5   r   r6   ls  s$   
"
zHfFileSystem.lsc              
      sT  |d ur|n	j d urj nd}j||d}| }|j}|r"|nd}g }	|jv r
|s
j| }
|	|
 g }|rdtfdd|
D }|r| \}|d u sZ|kr|d jvri||d  nj|d  }
|	|
 |fdd|
D  |sLg }|rt	|t
rfd	d|	D }|r|s|r|rtj|| }|d
s||ks|t||v r|d
n| |d urԈ t|d  d
}||8 } fdd|	D }	tjD ]}| d
 rj|d  qj d  |	j |d|||d |	S t	|trj|j|j|d}njj|j|j|||j|jd}|D ]z}|d
 |j }t	|t rN||j!d|j"|j#|j$|j%|j&d}n-t	|t'rb||j!d|j$|j(|j)d}nt	|t*rs|dd|j+|j%d}n|dd|j)d}|d }j,|g | |t|d  d
|d u s|kr|	| q-|	S )NFr   r   r   c                    s    g | ]}|d  dkr |fqS rc   	directoryr5   r|   	path_infodepthr5   r6   r   B  s     z)HfFileSystem._ls_tree.<locals>.<listcomp>r   c                    s$   g | ]}|d  dkr d |fqS )rc   r   r   r5   r   r   r5   r6   r   M  s
    
c                    s&   g | ]}|d  du r  |d qS )last_commitNr   )r   r   r3   r5   r6   r   W  s   & r1   c                    s"   g | ]}|d    d s|qS )r   r1   )
startswithr   )common_pathr5   r6   r   h  r   T)r   r   rA   rt   r   )prefixr   )r   expandrA   r?   filer   sizerc   blob_idlfsxet_hashr   security)r   r   rc   r   mtimeuploaded_atr   r   r   r   rc   tree_idr   )r   r   rc   r   )-rt   r   r7   r.   ry   extendr   popleftappendr   r>   osr/   commonprefixendswithr   r2   r   r   r   listr   r]   r   rP   _list_bucket_tree_with_foldersrQ   rv   Zlist_repo_treer@   rA   r?   r&   r   r   r   r   r   r   r"   r   r   r'   r   
setdefault)r4   r/   r   r   rA   rt   r   r   	root_pathr   Zcached_path_infosZdirs_not_in_dircacheZdirs_to_visitdir_infoZdirs_not_expandedcommon_prefixZcommon_path_depthZcached_pathtreer   
cache_pathZcache_path_infoparent_pathr5   )r   r   r4   r6   r   '  s   





E
	
zHfFileSystem._ls_treer   c                 C   s   | j j|||d}i }|rd|d nd}g }|D ]O}|| |s$qtt|jjd| d  D ]5}	tdt	|	|j
d}
|
j|vrO||
 |
||
j< q3|
j
durh||
j }|j
du sd|j
|
j
k rh|
j
|_
q3q|swtd| d	| d
|S )z<Same as `HfApi.list_bucket_tree` but always includes folders)r   r   r1   r   Nr   )rc   r/   r   zFile not found in bucket 'z': '')rv   Zlist_bucket_treer   r   r   r
   r/   parentsr#   r<   r   r   )r4   rQ   r   r   Zbucket_filesZbucket_foldersZ	min_depthr   Zbucket_entryZparent_bucket_folder_strZparent_bucket_folderZbucket_folderr5   r5   r6   r     s4   
"





z+HfFileSystem._list_bucket_tree_with_foldersc                 /   s>    | j ||dd }t j|g|R i |E dH  dS )a  
        Return all files below the given path.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.walk).

        Args:
            path (`str`):
                Root path to list files from.

        Returns:
            `Iterator[tuple[str, list[str], list[str]]]`: An iterator of (path, list of directory names, list of file names) tuples.
        rA   r   N)r   rK   r7   rU   walk)r4   r/   rY   rZ   r[   r5   r6   r     s   $zHfFileSystem.walkc                    s0   | j ||dd }t j|fd|i|S )ah  
        Find files by glob-matching.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.glob).

        Args:
            path (`str`):
                Path pattern to match.

        Returns:
            `list[str]`: List of paths matching the pattern.
        rA   r   r   )r   rK   r7   rU   glob)r4   r/   r   rZ   r[   r5   r6   r     s   zHfFileSystem.globwithdirsc                    s  |dur|dk rt d| j||d}| }z| j|fd||d| W n- tyS   z| j|fd|i|d d	krB|i i ni  W n tyP   i  Y nw Y n(w |s^d
d  D  n| j|fi |}	|	d dkrr|	g  n  dd  D  t }
|s|
S  fdd|
D S )a  
        List all files below path.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.find).

        Args:
            path (`str`):
                Root path to list files from.
            maxdepth (`int`, *optional*):
                Maximum depth to descend into subdirectories.
            withdirs (`bool`, *optional*):
                Include directory paths in the output. Defaults to False.
            detail (`bool`, *optional*):
                If True, returns a dict mapping paths to file information. Defaults to False.
            refresh (`bool`, *optional*):
                If True, bypass the cache and fetch the latest data. Defaults to False.
            revision (`str`, *optional*):
                The git revision to list from.

        Returns:
            `Union[list[str], dict[str, dict[str, Any]]]`: List of paths or dict of file information.
        Nr   zmaxdepth must be at least 1r   T)r   r   r   rA   rc   r   c                 S   s   g | ]
}|d  dkr|qS r   r5   r   r5   r5   r6   r   -  r   z%HfFileSystem.find.<locals>.<listcomp>r   c                 S   s   i | ]}|d  |qS r   r5   r   r5   r5   r6   r   2  r   z%HfFileSystem.find.<locals>.<dictcomp>c                    r{   r5   r5   )r|   r   r   r5   r6   r   7  r   )r   r   r7   r   r   infoFileNotFoundErrorr   )r4   r/   r   r   r   r   rA   rZ   r   r   namesr5   r   r6   find  s4    

zHfFileSystem.findpath1path2c                 K   sH  | j ||d}| j ||d}t|tst|trtd|j|jko'|j|jk}|rSd| d| }| jj|j|j|j|	d||	ddt
|j|j|jdgd	 n?| j|d
|jd}	|	 }
W d   n1 skw   Y  d| d| }| jj|
|j|j| j|j|j|	d||	dd | j| d | j| d dS )a  
        Copy a file within or between repositories.

        > [!WARNING]
        > Note: When possible, use `HfApi.upload_file()` for better performance.

        Args:
            path1 (`str`):
                Source path to copy from.
            path2 (`str`):
                Destination path to copy to.
            revision (`str`, *optional*):
                The git revision to copy from.

        r   z)Copy from/to buckets is not available yetzCopy z to r   r   rH   )Zsrc_path_in_reporB   Zsrc_revision)r@   r?   rA   r   r   r   r   NZpath_or_fileobjrB   r@   rr   r?   rA   r   r   r   )r   r   rP   r   r?   r@   rv   r   rA   rK   r   rB   openreadupload_filerr   r   r7   )r4   r   r   rA   rZ   Zresolved_path1Zresolved_path2Z	same_repor   fcontentr5   r5   r6   cp_file9  sN   




zHfFileSystem.cp_filec                 K   s   | j |fi i |ddi}d|v r&|d du r!td| d|d jS d|v r2|d r2|d S d|v r>|d r>|d S td	| d
| d)ak  
        Get the last modified time of a file.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.modified).

        Args:
            path (`str`):
                Path to the file.

        Returns:
            `datetime`: Last modified time of the file.
        rt   Tr   Nz9'modified' is not implemented for repository paths like 'r   r   r   z'Cannot determined 'modified' for path 'z	' (info: ))r   r   date)r4   r/   rZ   r   r5   r5   r6   modifiedu  s   
zHfFileSystem.modifiedc              	      sN  | j |d}| |d| jdur| jnd}|jsRddd t|tr+d d< t|trQ|rQ| jj|j	|j
|jd	d
 }i  dt|j|j|jdd nt|tr{| }| j||d fdd| j| D }	|	svtd |	d  nd | }|s|| jvr| | || jv rfdd| j| D }	|	std |	d  |s du s|r r d du r| jj|j	|j||j|j
d}
|
std |
d }t|j
|j	|jd|jd }t|tr|d |j |jd|j|j|j|j|jd n|d |j dd|j|jd |s fdddD   dus%J  S )aS  
        Get information about a file or directory.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.info).

        > [!WARNING]
        > Note: When possible, use `HfApi.get_paths_info()` or `HfApi.repo_info()`  for better performance
        > (or `HfApi.get_bucket_paths_info()` or `HfApi.bucket_info()` for buckets)

        Args:
            path (`str`):
                Path to get info for.
            refresh (`bool`, *optional*):
                If True, bypass the cache and fetch the latest data. Defaults to False.
            revision (`str`, *optional*):
                The git revision to get info from.

        Returns:
            `dict[str, Any]`: Dictionary containing file information (type, size, commit info, etc.).

        r   rt   NFr   r   )r   r   rc   r   )r?   rA   )oidtitler  )r   r   )r   c                    r   r   r5   r   r   r5   r6   r     r   z%HfFileSystem.info.<locals>.<listcomp>c                    r   r   r5   r   r   r5   r6   r     r   )r   rA   r?   rH   )rB   rG   r1   r   r   r   c                    r{   r5   r5   )r|   kr   r5   r6   r     r   z%HfFileSystem.info.<locals>.<dictcomp>) r   r7   rK   rt   r/   r   r>   rv   Zlist_repo_commitsr@   r?   rA   r%   	commit_idr  Z
created_atrP   r   r   ry   r   Zget_paths_inforB   rG   r&   r   r   r   r   r   r   r   )r4   r/   r   rA   rZ   r   rt   r   r   Zout1Z
paths_infor   r   r5   )r   r/   r6   r     s   








&
zHfFileSystem.infoc                 K   sD   z| ddr| | | j|fi | W dS  ty!   Y dS w )a  
        Check if a file exists.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.exists).

        > [!WARNING]
        > Note: When possible, use `HfApi.file_exists()` for better performance.

        Args:
            path (`str`):
                Path to check.

        Returns:
            `bool`: True if file exists, False otherwise.
        r   FT)rK   r   r   OSError)r4   r/   rZ   r5   r5   r6   exists  s   
zHfFileSystem.existsc                 C   *   z
|  |d dkW S  ty   Y dS w )ai  
        Check if a path is a directory.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.isdir).

        Args:
            path (`str`):
                Path to check.

        Returns:
            `bool`: True if path is a directory, False otherwise.
        rc   r   Fr   r
  r4   r/   r5   r5   r6   r     
   zHfFileSystem.isdirc                 C   r  )a`  
        Check if a path is a file.

        For more details, refer to [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.spec.AbstractFileSystem.isfile).

        Args:
            path (`str`):
                Path to check.

        Returns:
            `bool`: True if path is a file, False otherwise.
        rc   r   Fr  r  r5   r5   r6   isfile'  r  zHfFileSystem.isfilec                 C   sl   |  |}t|tr| j d|j dt|j }nt|j|j	|j
|j| jd}| |r4|ddd}|S )z
        Get the HTTP URL of the given path.

        Args:
            path (`str`):
                Path to get URL for.

        Returns:
            `str`: HTTP URL to access the file or directory on the Hub.
        z	/buckets/z	/resolve/)r?   rA   rq   z/tree/r   )r   r   rP   rq   rQ   r   r/   r    r@   rB   r?   rA   r   replace)r4   r/   r   urlr5   r5   r6   r  9  s   

 
zHfFileSystem.urlc              
      sT  | d}t| dh }t|ttfrt|dkr)t j||f||d|S t	|r0|}n| 
|r>tj|dd dS t|ttfrPtjtj|dd d}|du r]t|d}d}| }	| j||d	}
| j||d	d
 }|| z+t| |
 |||d| j t|tr|jndd ||	 W |r|  dS dS |r|  w w )ad  
        Copy single remote file to local.

        > [!WARNING]
        > Note: When possible, use `HfApi.hf_hub_download()` or `HfApi.download_bucket_files` for better performance.

        Args:
            rpath (`str`):
                Remote path to download from.
            lpath (`str`):
                Local path to download to.
            callback (`Callback`, *optional*):
                Optional callback to track download progress. Defaults to no callback.
            outfile (`IO`, *optional*):
                Optional file-like object to write to. If provided, `lpath` is ignored.

        rA   r   )callbackoutfileT)exist_okNFwbr   r   )r  	temp_fileZdisplayed_filenameexpected_sizeZresume_sizeheadersZ	_tqdm_bar)rK   setkeysr   r   r   r   rU   get_filer   r   r   makedirsr<   r	   r/   dirnamer   tellr   r   Zset_sizer!   r  r7   rv   _build_hf_headersZtqdmseekclose)r4   ZrpathZlpathr  r  rZ   rA   Zunhandled_kwargsZ
close_fileZinitial_posZresolve_remote_pathr  r[   r5   r6   r  S  sF   



	
zHfFileSystem.get_filec                 C      t d)zA context within which files are committed together upon exit

        Requires the file class to implement `.commit()` and `.discard()`
        for the normal and exception cases.
        (Transactional commits are not supported.r   r3   r5   r5   r6   transaction  s   	zHfFileSystem.transactionc                 C   r#  )z@Begin write transaction for deferring files, non-context versionr$  r%  r3   r5   r5   r6   start_transaction  s   zHfFileSystem.start_transactionc                 C   s   t t| | j| j|  ffS rT   )make_instancerc   rh   ri   re   r3   r5   r5   r6   
__reduce__  s   zHfFileSystem.__reduce__c                 C   s   t | jt | jt | jdS )N)ry   rw   rx   )r   ry   rw   rx   r3   r5   r5   r6   re     s   z HfFileSystem._get_instance_staterT   )r   NN)FNN)TFN)FFNNN)NFFFN)FNr0   N)6r8   r9   r:   r;   Zroot_markerprotocolr   r<   r   boolintrV   classmethodr^   tuple	Exceptionr   r   r>   rP   r   r   r   r   r   r   dictr   r   r   r   r"   r#   r   r   r   r   r   r  r   r  r   r  r   r  r  r   r  propertyr&  r'  r)  re   ro   r5   r5   r[   r6   rp      s   B


j$

3
.
 
,($	
 =<(n>

	rp   )	metaclassc                       s   e Zd Zddededee f fddZ fddZd	ed
ede	fddZ
dddZddeddfddZd fdd	ZdefddZ  ZS )r   Nfsr/   rA   c              
      st   z
|j ||d| _W n ty' } zd|ddv r"t| d| d }~ww t j|| j fi | |  d S )Nr   wr   rH   B.
Make sure the repository and revision exist before writing data.)r   r   r   rK   rU   rV   r7   )r4   r4  r/   rA   rZ   r   r[   r5   r6   rV     s   zHfFileSystemFile.__init__c                    s   t | dsd S t  S Nr   )hasattrrU   __del__r3   r[   r5   r6   r9    s   

zHfFileSystemFile.__del__startendr0   c                 C   sL   dd| d|d  i| j j }|  }td||tjd}t| |jS )Nrangebytes=-r   GETr  r   )	r4  rv   r   r  r*   r   HF_HUB_DOWNLOAD_TIMEOUTr)   r   )r4   r:  r;  r  r  rr5   r5   r6   _fetch_range  s   
zHfFileSystemFile._fetch_rangec                 C   s   t jddd| _d S )Nzhffs-F)r   r   )tempfileNamedTemporaryFiler  r3   r5   r5   r6   _initiate_upload  s   z!HfFileSystemFile._initiate_uploadFfinalc                 C   s   | j d | j  }| j| |rg| j  t| jtr1| j	j
j| jj| jj| jjfgd n#| j	j
j| jj| jj| jj| j	j| jj| jj| jd| jdd t| jj | j	j| j d d S d S )Nr   )addr   r   r   r   )bufferr!  r   r  writer"  r   r   rP   r4  rv   r   rQ   r   r/   r   rB   r@   rr   r?   rA   rZ   rK   r   remover   r7   )r4   rG  blockr5   r5   r6   _upload_chunk  s0   





zHfFileSystemFile._upload_chunkr  c                    s   | j dkr;|du s|dkr;| jdkr;| jj| jddd}| }|  jt|7  _|W  d   S 1 s6w   Y  t |S )zRead remote file.

        If `length` is not provided or is -1, the entire file is downloaded and read. On POSIX systems the file is
        loaded in memory directly. Otherwise, the file is downloaded to a temporary file and read from there.
        r   Nr  r   )rs   )r   locr4  r   r/   r   r   rU   )r4   lengthr   r   r[   r5   r6   r     s   $ zHfFileSystemFile.readc                 C      | j | jS rT   r4  r  r/   r3   r5   r5   r6   r       zHfFileSystemFile.urlrT   r*  )Fr  )r8   r9   r:   rp   r<   r   rV   r9  r-  bytesrC  rF  r,  rM  r   r  ro   r5   r5   r[   r6   r     s     

r   c                       s   e Zd Z				d!dedededee d	ed
ef fddZd"dedefddZd#defddZ	d#de
e dedefddZdefddZ fddZdd Zdd  Z  ZS )$r   r   Nr   noner4  r/   r   rA   rs   
cache_typec           	   
      s   |dkrt d| |dkrt d| d|v r"t d| dz
|j||d| _W n" tyN } zd|d	d
v rDt| d|W Y d }~nd }~ww | j d d| _t j|| j f|||d| d | _	|  t
 | _d | _t | _d S )Nr   z:HfFileSystemStreamFile only supports block_size=0 but got rU  z?HfFileSystemStreamFile only supports cache_type='none' but got r5  z;HfFileSystemStreamFile only supports reading but got mode='r   r   r   rH   r6  )r   r   r   rs   rV  )r   r   r   r   rK   r7   detailsrU   rV   responser   _exit_stack_stream_iterator	bytearray_stream_buffer)	r4   r4  r/   r   rA   rs   rV  rZ   r   r[   r5   r6   rV     s>   

zHfFileSystemStreamFile.__init__rN  whencec                 C   s2   |dkr
|dkr
d S || j kr|dkrd S td)Nr   r   zCannot seek streaming HF file)rN  r   )r4   rN  r^  r5   r5   r6   r!  "  s
   zHfFileSystemStreamFile.seekr  rO  c                 C   s   | j du r	|   d}	 z | j du s| jdu rW dS | | j|}|  jt|7  _|W S  tyH   | j dur=| j   |r@ |   d}Y nw q)zRead the remote file.

        If the file is already open, we reuse the connection.
        Otherwise, open a new connection and read from it.

        If reading the stream fails, we retry with a new connection.
        NFT    )rY  _open_connectionr[  _read_from_streamrN  r   r0  r"  )r4   rO  Zretried_oncer   r5   r5   r6   r   )  s&   


zHfFileSystemStreamFile.readiteratorr0   c                 C   s   |dkrdS |dk r"t | j}| j  |D ]}|| qt|S |t| jkr:t| jd| }| jd|= |S t | j}| j  |D ]+}|t| }|t|krZ|| qF||d|  | j||d   t|S t|S )zRead up to `length` bytes from stream buffer and stream.

        If length < 0, read until EOF.

        If EOF is reached before length, fewer bytes may be returned.
        r   r_  N)r\  r]  r   r   rT  r   )r4   rb  rO  bufchunkresultZneedr5   r5   r6   ra  E  s,   



z(HfFileSystemStreamFile._read_from_streamc                 C   rP  rT   rQ  r3   r5   r5   r6   r  g  rR  zHfFileSystemStreamFile.urlc                    s"   t | dsd S | j  t  S r7  )r8  rZ  r"  rU   r9  r3   r[   r5   r6   r9  j  s   


zHfFileSystemStreamFile.__del__c                 C   s   t | j| j| j| j| jjffS rT   )reopenr4  r/   r   	blocksizecacher   r3   r5   r5   r6   r)  q  s   z!HfFileSystemStreamFile.__reduce__c              
   C   s   | j   d| _|  }| jj }| jdkr d| j d|d< | j	t
d||tjd| _zt| j W n tyR } z|jjdkrMd| _W Y d}~dS  d}~ww | j | _dS )	z%Open a connection to the remote file.Nr   r=  r>  Ranger?  r@  i  )r]  r   r[  r  r4  rv   r   rN  rZ  enter_contextr+   r   rA  rY  r)   r   status_codeZ
iter_bytes)r4   r  r  r   r5   r5   r6   r`  t  s0   

	z'HfFileSystemStreamFile._open_connection)r   Nr   rU  )r   rS  )r8   r9   r:   rp   r<   r   r-  rV   r!  r   r   rT  ra  r  r9  r)  r`  ro   r5   r5   r[   r6   r     s2    #"r   rA   r0   c                 C   s   t | r| S t| S rT   )r   r   
safe_quoter   r5   r5   r6   rM     s   rM   sc                 C   s   t | ddS )NrH   )safe)r   )rm  r5   r5   r6   rl    s   rl  r/   r   c                 C   sN   | }t |tr|  d}nt |tr|  d}n
t |tr"|  d}t||)Nz (repository not found)z (revision not found)z (invalid repository id))r   r   r   r(   r   )r/   r   msgr5   r5   r6   r     s   




r   r4  r   rs   rV  c                 C   s   | j ||||dS )NrW  )r   )r4  r/   r   rs   rV  r5   r5   r6   rf    s   rf  c                 C   s0   | |i |}|  D ]
\}}t||| q|S rT   )rf   rg   )rX   rY   rZ   rl   r4  rm   rn   r5   r5   r6   r(    s   r(  )Zr   rerD  r_   collectionsr   
contextlibr   copyr   dataclassesr   r   r   	itertoolsr   pathlibr	   r
   typingr   r   r   r   r   r   urllib.parser   r   ZfsspecZhttpxZfsspec.callbacksr   r   r   Zfsspec.utilsr   rH   r   Z_commit_apir   r   errorsr   r   r   r   r   Zfile_downloadr    r!   Zhf_apir"   r#   r$   r%   r&   r'   utilsr(   r)   r*   r+   Zutils.insecure_hashlibr,   compileVERBOSEr   r-   r>   rP   rc   ZAbstractFileSystemrR   r=   rS   rp   specZAbstractBufferedFiler   r   r<   rM   rl  r0  r   r-  rf  r(  Zhffsr5   r5   r5   r6   <module>   sl   
   

2        (K 
