o
    Zi1                  
   @   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 d d	l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, ddl-m.Z.m/Z/ ddl0m1Z1m2Z2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z: e;dej<Z=eG dd dZ>e?ej@ZAeeBd< G dd deAZCG dd dej@eCdZDG dd dejEjFZGG d d! d!ejEjFZHd"eId#eIfd$d%ZJd&eId#eIfd'd(ZKd)eId*eeL d#efd+d,ZMd-eDd)eId.eId/eNd0eIf
d1d2ZOd3d4 ZPeD ZQdS )5    N)deque)	ExitStack)deepcopy)	dataclassfield)datetime)chain)Path)AnyIteratorNoReturnOptionalUnion)quoteunquote)_DEFAULT_CALLBACKNoOpCallbackTqdmCallback)
isfilelike   )	constants)CommitOperationCopyCommitOperationDelete)EntryNotFoundErrorHfHubHTTPErrorRepositoryNotFoundErrorRevisionNotFoundError)
hf_hub_urlhttp_get)HfApiLastCommitInfoRepoFile)HFValidationErrorhf_raise_for_statushttp_backoffhttp_stream_backoff)md5zy
    (^refs\/convert\/\w+)     # `refs/convert/parquet` revisions
    |
    (^refs\/pr\/\d+)          # PR revisions
    c                   @   sX   e Zd ZU dZeed< eed< eed< eed< edddZee ed	< d
efddZ	dS )HfFileSystemResolvedPathzUData structure containing information about a resolved Hugging Face file system path.	repo_typerepo_idrevisionpath_in_repoNF)defaultrepr_raw_revisionreturnc                 C   s~   t j| jd| j }| jr| d| j d| j dS | jt j	kr4| dt
| j d| j dS | d| j dS )N @/)r   REPO_TYPES_URL_PREFIXESgetr(   r)   r.   r+   rstripr*   DEFAULT_REVISIONsafe_revision)self	repo_path r:   U/home/app/Keep/.python/lib/python3.10/site-packages/huggingface_hub/hf_file_system.py	unresolve4   s   "z"HfFileSystemResolvedPath.unresolve)
__name__
__module____qualname____doc__str__annotations__r   r.   r   r<   r:   r:   r:   r;   r'   (   s   
 r'   _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__r:   r;   rG   R   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cachablerH   Z_latesttype__call___get_instance_stateitemssetattrZ
_fs_token_storage_argsstorage_options)
rI   rJ   rK   skipZfs_tokenZfs_token_main_threadobjinstance_stateattrstate_valuer:   r:   r;   rU   Z   s$    


z_Cached.__call__)r=   r>   r?   r@   rG   rU   __classcell__r:   r:   rL   r;   rD   B   s    rD   c                       s"  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dNdedee defddZdNdee ddfddZ			dOdededee
 dee ded f
ddZdNdedee ddfdd Z	!		dPded"e	d#ee
 dee ddf
d$d%Z	dQded'e	d(e	dee deeeeeef f  f
d)d*Z	!	!			dRded"e	d(e	dee d	ee	 d#ee
 fd+d,Zdedeeeee ee f  f fd-d.ZdNded#ee
 dee f fd/d0Z		!	!	!	dSded#ee
 d1e	d'e	d(e	dee deee eeeeef f f fd2d3ZdNd4ed5edee ddfd6d7Z dede!fd8d9Z"dTded(e	dee deeef fd:d;Z#d<d= Z$d>d? Z%d@dA Z&dedefdBdCZ'e(dfdU fdDdEZ)e*dFdG Z+dHdI Z,dJdK Z-dLdM Z.  Z/S )VHfFileSystemaL  
    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.

    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)
    ```
    r0   ZhfN)endpointtoken
block_sizeexpand_inforb   rc   rd   re   c                   sN   t  j|i | |ptj| _|| _t||d| _|| _|| _	i | _
i | _d S )N)rb   rc   )rF   rG   r   ENDPOINTrb   rc   r   _apird   re   _repo_and_revision_exists_cachedircache)r8   rb   rc   rd   re   rJ   rZ   rL   r:   r;   rG      s   	
zHfFileSystem.__init__threading_identr/   c                    s\     dptj d<   d d<  fddt D  | || f}tt| }| S )zDeterministic token for cachingrb   rc   c                       i | ]}| | qS r:   r:   ).0keyrK   r:   r;   
<dictcomp>       z*HfFileSystem._tokenize.<locals>.<dictcomp>)r4   r   rf   sortedr&   rA   encode	hexdigest)rI   rj   rJ   rK   Ztokenize_argshr:   rn   r;   rO      s   zHfFileSystem._tokenizer(   r)   r*   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)r*   r(   timeoutF)TN)rh   rg   Z	repo_infor   ZHF_HUB_ETAG_TIMEOUTr   r"   r   )r8   r(   r)   r*   er:   r:   r;   _repo_and_revision_exist   s"   

 z%HfFileSystem._repo_and_revision_existpathc                 C   s  dt t dt t dt t fdd}| |}|std|dd d tj v r@d|vr2t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r|}|}| |||\}	}|	st||
 n1t||
 n+|}d}d
|v r!|d
d	\}}|t||}nd}| |||\}	}|	s3td|dur:|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_pathr*   r/   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)ry   r*   r:   r:   r;   %_align_revision_in_path_with_revision   s   zHHfFileSystem.resolve_path.<locals>._align_revision_in_path_with_revisionz0Access to repositories lists is not implemented.r2   r   r   r1   N   r0   )r.   )r   rA   Z_strip_protocolNotImplementedErrorsplitr   r3   valuesZREPO_TYPES_MAPPINGZREPO_TYPE_MODELcountjoinSPECIAL_REFS_REVISION_REGEXsearchgroupsublstripr   rw   _raise_file_not_found
isinstancer   r"   r6   r'   )r8   rx   r*   r{   r(   r)   ry   matchr+   Zrepo_and_revision_existerrZrepo_id_with_namespaceZpath_in_repo_with_namespaceZrepo_id_without_namespaceZpath_in_repo_without_namespace_r:   r:   r;   resolve_path   sx   







zHfFileSystem.resolve_pathc                 C   s   |s| j   | j  dS | |}| }|r'| j |d | |}|s|jsE| j|j|j	dfd | j|j|j	|j
f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)ri   clearrh   r   r<   rN   _parentr+   r(   r)   r*   )r8   rx   resolved_pathr:   r:   r;   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 )Nrd   az/Appending to remote files is not yet supported.r   )r   r*   )rd   r}   r   r   )r8   rx   r   rd   r*   rK   r:   r:   r;   _openZ  s   zHfFileSystem._openc              
   K   sR   | j ||d}| jj|j|j| j|j|j|d|dd | j	|
 d d S )Nr*   commit_messagecommit_description)r+   r)   rc   r(   r*   r   r   rx   )r   rg   Zdelete_filer+   r)   rc   r(   r*   r4   r   r<   )r8   rx   r*   rK   r   r:   r:   r;   _rml  s   	zHfFileSystem._rmF	recursivemaxdepthc              
      s    j ||d} j||||d} fdd|D }dd |D }	d| d}
|
|r+dnd	7 }
|
|d
ur9d| 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   r*   c                    s"   g | ]}  |s |jqS r:   )isdirr   r+   )rl   rx   r8   r:   r;   
<listcomp>     " z#HfFileSystem.rm.<locals>.<listcomp>c                 S   s   g | ]}t |d qS ))r+   )r   )rl   r+   r:   r:   r;   r     rp   zDelete  zrecursively r0   Nzup to depth r   r   )r)   r(   rc   
operationsr*   r   r   r   )r   Zexpand_pathrg   create_commitr)   r(   rc   r*   r4   r   r<   )r8   rx   r   r   r*   rK   r   pathsZpaths_in_repor   r   r:   r   r;   rmy  s"   
	zHfFileSystem.rmTdetailrefreshc                    s   | j  |d}|  z| j f||d|}W n4 tyM   |js(t d | j|  f||d|} fdd|D }t|dkrKt d Y nw |rR|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   r*   Nc                       g | ]
}|d   kr|qS namer:   rl   or   r:   r;   r         z#HfFileSystem.ls.<locals>.<listcomp>r   c                 S   s   g | ]}|d  qS r   r:   r   r:   r:   r;   r     s    )r   r<   _ls_treer   r+   r   r   len)r8   rx   r   r   r*   rK   r   outr:   r   r;   ls  s   

zHfFileSystem.lsc              
      s  |d ur|n	j d urj nd}j||d}| }t|j|j|jd|jd }g }	|jv r|sj| }
|		|
 g }|rdt
fdd|
D }|r| \}|d u s`|kr|d jvro||d  nj|d  }
|		|
 |	fd	d|
D  |sRg }|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 jj|j|j|||j|jd}|D ]W}|d |j }t|tr>||jd|j |j!|j"|j#|j$d}n
|dd|j%|j#d}|d }j&|g | |t|d  d|d u sn|krs|	| q|	S )NFr   r0   r+   r.   r|   c                    s    g | ]}|d  dkr |fqS rT   	directoryr:   rl   	path_infodepthr:   r;   r     s     z)HfFileSystem._ls_tree.<locals>.<listcomp>r   c                    s$   g | ]}|d  dkr d |fqS )rT   r   r   r:   r   r   r:   r;   r     s
    
c                    s&   g | ]}|d  du r  |d qS )last_commitNr   )r   r   r   r:   r;   r     s   & r2   c                    s"   g | ]}|d    d s|qS )r   r2   )
startswithr   )common_pathr:   r;   r     r   T)r   r   r*   re   r   )r   expandr*   r(   filer   sizerT   blob_idlfsxet_hashr   securityr   r   r   r   rT   tree_idr   )'re   r   r<   r'   r(   r)   r*   r.   ri   extendr   popleftappendosrx   commonprefixendswithr   r5   r   r   r   listr   rN   r   rg   Zlist_repo_treer+   r   r!   r   r   r   r   r   r   r   
setdefault)r8   rx   r   r   r*   re   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_pathr:   )r   r   r8   r;   r     s   





-
zHfFileSystem._ls_treec                 /   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.
        r*   r   N)r   r4   r<   rF   walk)r8   rx   rJ   rK   rL   r:   r;   r   I  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.
        r*   r   r   )r   r4   r<   rF   glob)r8   rx   r   rK   rL   r:   r;   r   Y  s   zHfFileSystem.globwithdirsc                    s"  |dur|dk rt d| j||d}| }z| j|fd||j|d| W n- tyU   z| j|fd|i|d d	krD|i i ni  W n tyR   i  Y nw Y n+w |s`d
d  D  n| j|fd|ji|}	|	d dkrw|	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*   r   r*   rT   r   c                 S   s   g | ]
}|d  dkr|qS r   r:   r   r:   r:   r;   r     r   z%HfFileSystem.find.<locals>.<listcomp>r   c                 S   s   i | ]}|d  |qS r   r:   r   r:   r:   r;   ro     rp   z%HfFileSystem.find.<locals>.<dictcomp>c                    rk   r:   r:   )rl   r   r   r:   r;   ro     rp   )	rz   r   r<   r   r*   r   infoFileNotFoundErrorrq   )r8   rx   r   r   r   r   r*   rK   r   r   namesr:   r   r;   findi  s@    



zHfFileSystem.findpath1path2c                 K   s,  | j ||d}| j ||d}|j|jko|j|jk}|rEd| 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 s]w   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 z to r   r   r0   )Zsrc_path_in_repor+   Zsrc_revision)r)   r(   r*   r   r   r   r   NZpath_or_fileobjr+   r)   rc   r(   r*   r   r   r   )r   r(   r)   rg   r   r*   r4   r   r+   openreadupload_filerc   r   r<   )r8   r   r   r*   rK   Zresolved_path1Zresolved_path2Z	same_repor   fcontentr:   r:   r;   cp_file  sF   




zHfFileSystem.cp_filec                 K   s*   | j |fi i |ddi}|d d S )ai  
        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 commit date of the file.
        re   Tr   dater   )r8   rx   rK   r   r:   r:   r;   modified  s   zHfFileSystem.modifiedc              	      s  | j |d}| |d| jdur| jnd}|jsEdddd |rD| jj|j|j|j	dd	 }i  dt
|j|j|jd
d nd | }|sX|| jvrX| | || jv rtfdd| j| D }	|	spt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sJ  S )a   
        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.

        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   re   NFr   r   )r   r   rT   r   )r(   r*   )oidtitler   )r   r   c                    r   r   r:   r   r   r:   r;   r   %  r   z%HfFileSystem.info.<locals>.<listcomp>r   )r   r*   r(   r0   r   r2   r   r   r   c                    rk   r:   r:   )rl   kr   r:   r;   ro   O  rp   z%HfFileSystem.info.<locals>.<dictcomp>)r   r   rT   )r   r<   r4   re   r+   rg   Zlist_repo_commitsr)   r(   r*   r    	commit_idr   Z
created_atr   ri   r   r   Zget_paths_infor'   r.   r   r!   rx   r   r   r   r   r   r   r   )r8   rx   r   r*   rK   r   re   r   r   Zout1Z
paths_infor   r   r:   )r   rx   r;   r     s   



 

zHfFileSystem.infoc                 K   s<   z| ddr| | | j|fi | W dS    Y dS )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)r4   r   r   )r8   rx   rK   r:   r:   r;   existsS  s   
zHfFileSystem.existsc                 C   s*   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.
        rT   r   F)r   OSErrorr8   rx   r:   r:   r;   r   l  s
   zHfFileSystem.isdirc                 C   s"   z
|  |d dkW S    Y dS )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.
        rT   r   Fr   r   r:   r:   r;   isfile~  s   zHfFileSystem.isfilec                 C   sB   |  |}t|j|j|j|j| jd}| |r|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.
        )r(   r*   rb   z	/resolve/z/tree/r   )	r   r   r)   r+   r(   r*   rb   r   replace)r8   rx   r   urlr:   r:   r;   r     s   

zHfFileSystem.urlc              
      sb  | 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
 }|| z2tt|
j|
j|
j|
j| jd|||d| j t|tr|jndd | |	 W |r|!  dS dS |r|!  w w )aC  
        Copy single remote file to local.

        > [!WARNING]
        > Note: When possible, use `HfApi.hf_hub_download()` 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.

        r*   r   )callbackoutfileT)exist_okNFwbr   r   r)   r*   filenamer(   rb   )r   	temp_fileZdisplayed_filenameexpected_sizeZresume_sizeheadersZ	_tqdm_bar)"r4   setkeysr   r   r   r   rF   get_filer   r   r   makedirsrA   r	   rx   dirnamer   tellr   r   Zset_sizer   r   r)   r*   r+   r(   rb   rg   _build_hf_headersZtqdmseekclose)r8   ZrpathZlpathr   r   rK   r*   Zunhandled_kwargsZ
close_fileZinitial_posZresolve_remote_pathr   rL   r:   r;   r     sR   




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}   r   r:   r:   r;   transaction  s   	zHfFileSystem.transactionc                 C   r  )z@Begin write transaction for deferring files, non-context versionr  r  r   r:   r:   r;   start_transaction  s   zHfFileSystem.start_transactionc                 C   s   t t| | j| j|  ffS rE   )make_instancerT   rY   rZ   rV   r   r:   r:   r;   
__reduce__  s   zHfFileSystem.__reduce__c                 C   s   t | jt | jdS )N)ri   rh   )r   ri   rh   r   r:   r:   r;   rV     s   z HfFileSystem._get_instance_staterE   )r   NN)FNN)TFN)FFNNN)NFFFN)FNr/   N)0r=   r>   r?   r@   Zroot_markerprotocolr   rA   r   boolintrG   classmethodrO   tuple	Exceptionrw   r'   r   r   r   r   r   r   dictr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   propertyr	  r
  r  rV   r`   r:   r:   rL   r;   ra   t   s    0
_

/
+
,z$	
 ?8(cD

	ra   )	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fsrx   r*   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   r0   B.
Make sure the repository and revision exist before writing data.)r   r   r   r4   rF   rG   r<   )r8   r  rx   r*   rK   rv   rL   r:   r;   rG     s   zHfFileSystemFile.__init__c                    s   t | dsd S t  S Nr   )hasattrrF   __del__r   rL   r:   r;   r    s   

zHfFileSystemFile.__del__startendr/   c                 C   sj   dd| d|d  i| j j }t| jj| jj| jj| jj| j j	d}t
d||tjd}t| |jS )Nrangebytes=-r   r   GETr   ru   )r  rg   r  r   r   r)   r*   r+   r(   rb   r$   r   HF_HUB_DOWNLOAD_TIMEOUTr#   r   )r8   r  r  r   r   rr:   r:   r;   _fetch_range  s   
zHfFileSystemFile._fetch_rangec                 C   s   t jddd| _d S )Nzhffs-F)prefixdelete)tempfileNamedTemporaryFiler   r   r:   r:   r;   _initiate_upload/  s   z!HfFileSystemFile._initiate_uploadFfinalc                 C   s   | j d | j  }| j| |rN| j  | 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   r   r   r   r   )bufferr  r   r   writer  r  rg   r   r   r   r+   r)   rc   r(   r*   rK   r4   r   remover   r<   )r8   r,  blockr:   r:   r;   _upload_chunk2  s(   





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   )rd   )r   locr  r   rx   r   r   rF   )r8   lengthr   r   rL   r:   r;   r   G  s   $ zHfFileSystemFile.readc                 C      | j | jS rE   r  r   rx   r   r:   r:   r;   r   T     zHfFileSystemFile.urlrE   r  )Fr   )r=   r>   r?   ra   rA   r   rG   r  r  bytesr&  r+  r  r1  r   r   r`   r:   r:   rL   r;   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   noner  rx   r   r*   rd   
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 r9  z?HfFileSystemStreamFile only supports cache_type='none' but got r  z;HfFileSystemStreamFile only supports reading but got mode=''r   r   r0   r  )r   r   r   rd   r:  )rz   r   r   r   r4   r<   detailsrF   rG   responser   _exit_stack_stream_iterator	bytearray_stream_buffer)	r8   r  rx   r   r*   rd   r:  rK   rv   rL   r:   r;   rG   Y  s>   

zHfFileSystemStreamFile.__init__r2  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)r2  rz   )r8   r2  rC  r:   r:   r;   r  |  s
   zHfFileSystemStreamFile.seekr   r3  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    )r>  _open_connectionr@  _read_from_streamr2  r   r  r  )r8   r3  Zretried_oncer   r:   r:   r;   r     s&   


zHfFileSystemStreamFile.readiteratorr/   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   rD  N)rA  rB  r   r   r8  r   )r8   rG  r3  bufchunkresultZneedr:   r:   r;   rF    s,   



z(HfFileSystemStreamFile._read_from_streamc                 C   r4  rE   r5  r   r:   r:   r;   r     r6  zHfFileSystemStreamFile.urlc                    s"   t | dsd S | j  t  S r  )r  r?  r  rF   r  r   rL   r:   r;   r    s   


zHfFileSystemStreamFile.__del__c                 C   s   t | j| j| j| j| jjffS rE   )reopenr  rx   r   	blocksizecacher   r   r:   r:   r;   r    s   z!HfFileSystemStreamFile.__reduce__c              
   C   s   | j   d| _t| jj| jj| jj| jj| j	j
d}| j	j }| jdkr/d| j d|d< | jtd||tjd| _zt| j W n tya } z|jjd	kr\d| _W Y d}~dS  d}~ww | j | _dS )
z%Open a connection to the remote file.Nr   r   r   r!  Ranger"  r#  i  )rB  r   r@  r   r   r)   r*   r+   r(   r  rb   rg   r  r2  r?  enter_contextr%   r   r$  r>  r#   r   status_codeZ
iter_bytes)r8   r   r   rv   r:   r:   r;   rE    s<   

	z'HfFileSystemStreamFile._open_connection)r   Nr   r9  )r   r7  )r=   r>   r?   ra   rA   r   r  rG   r  r   r   r8  rF  r   r  r  rE  r`   r:   r:   rL   r;   r   X  s2    #"r   r*   r/   c                 C   s   t | r| S t| S rE   )r   r   
safe_quoter   r:   r:   r;   r7     s   r7   sc                 C   s   t | ddS )Nr0   )safe)r   )rR  r:   r:   r;   rQ    s   rQ  rx   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   )rx   r   msgr:   r:   r;   r     s   




r   r  r   rd   r:  c                 C   s   | j ||||dS )Nr<  )r   )r  rx   r   rd   r:  r:   r:   r;   rK    s   rK  c                 C   s0   | |i |}|  D ]
\}}t||| q|S rE   )rW   rX   )rI   rJ   rK   r]   r  r^   r_   r:   r:   r;   r  
  s   r  )Rr   rer)  rP   collectionsr   
contextlibr   copyr   dataclassesr   r   r   	itertoolsr   pathlibr	   typingr
   r   r   r   r   urllib.parser   r   ZfsspecZhttpxZfsspec.callbacksr   r   r   Zfsspec.utilsr   r0   r   Z_commit_apir   r   errorsr   r   r   r   Zfile_downloadr   r   Zhf_apir   r    r!   utilsr"   r#   r$   r%   Zutils.insecure_hashlibr&   compileVERBOSEr   r'   rT   ZAbstractFileSystemrC   rB   rD   ra   specZAbstractBufferedFiler   r   rA   r7   rQ  r  r   r  rK  r  Zhffsr:   r:   r:   r;   <module>   sb   
 
2       L 
