o
    2j                  
   @   s  U d dl Z d dlZd dl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 d dlmZ d d	lmZmZ d d
l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' ddl(m)Z)m*Z* ddl+m,Z,m-Z-m.Z.m/Z/m0Z0 ddl1m2Z2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z; ddl<m=Z=m>Z>m?Z?m@Z@mAZA ddlBmCZC e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/eTdB d(efd0d1ZUd2eLd.eQd3eQd4eVd5eQf
d6d7ZWd8d9 ZXeL ZYdS ):    N)deque)IterableIterator)	ExitStack)deepcopy)	dataclassfield)datetime)chain)PathPurePosixPath)AnyNoReturnUnion)quoteunquote)_DEFAULT_CALLBACKNoOpCallbackTqdmCallback)apply_config)
isfilelike   )	constants)CommitOperationCopyCommitOperationDelete)BucketNotFoundErrorEntryNotFoundErrorHfHubHTTPErrorRepositoryNotFoundErrorRevisionNotFoundError)
hf_hub_urlhttp_get)SPECIAL_REFS_REVISION_REGEX
BucketFileBucketFolderHfApiLastCommitInfoRepoFile
RepoFolder)HFValidationErrorhf_raise_for_statushttp_backoffhttp_stream_backoffparse_hf_uri)md5c                   @   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/)r0   r1   rstripself r7   Y/var/www/html/whisper/venv/lib/python3.10/site-packages/huggingface_hub/hf_file_system.py	unresolve+   s   z"HfFileSystemResolvedPath.unresolveN)__name__
__module____qualname____doc__str__annotations__r9   r7   r7   r7   r8   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d
B 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initr0   r1   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getrA   rB   rI   r0   rC   DEFAULT_REVISIONsafe_revisionrD   r1   )r6   	repo_pathr7   r7   r8   __post_init__=   s   z0HfFileSystemResolvedRepositoryPath.__post_init__)r:   r;   r<   r=   r>   r?   r   r0   r1   rI   rQ   r7   r7   r7   r8   r@   /   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_idFrE   r0   c                 C   s   d| j  | _d S )Nzbuckets/)rS   r0   r5   r7   r7   r8   rQ   O   s   z,HfFileSystemResolvedBucketPath.__post_init__N)	r:   r;   r<   r=   r>   r?   r   r0   rQ   r7   r7   r7   r8   rR   H   s
   
 rR   _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__r7   r8   rX   g   s   
z_Cached.__init__c           
      O   s   t | |}|dd}| j| t g|R i |}| j| t jg|R i |}|s<| jr<|| jv r<|| _	| j| S t
j| g|R i |}|sh| jrh|| jv rh| j|  }| D ]
\}}	t|||	 q]||_||_||_| jr~|s~|| _	|| j|< |S )Nskip_instance_cacheF)r   pop	_tokenize	threading	get_identmain_threadidentcachablerY   _latesttype__call___get_instance_stateitemssetattr
_fs_token_storage_argsstorage_options)
rZ   r[   r\   skipfs_tokenfs_token_main_threadobjinstance_stateattrstate_valuer7   r7   r8   ri   o   s&   
 


z_Cached.__call__)r:   r;   r<   r=   rX   ri   __classcell__r7   r7   r]   r8   rU   W   s    rU   c                       s^  e Zd ZdZdZdZddddddedB deeB dB dedB d	edB f fd
dZ	e
dedefddZdedededB deeedB f fddZdedeeedB f fddZ	dTdededB deeB fddZdTdedB ddfddZ			dUdedededB dedB ded f
d d!ZdTdededB ddfd"d#Z	$		dVded%ed&edB dedB ddf
d'd(Z	dWded*ed+ededB deeeeef B  f
d,d-Z	$	$			dXded%ed+ededB d	edB d&edB fd.d/Zded0ed%edeeeB  fd1d2Z dede!eeee ee f  f fd3d4Z"dTded&edB dee f fd5d6Z#		$	$	$	dYded&edB d7ed*ed+ededB dee eeeeef f B fd8d9Z$dTd:ed;ededB ddfd<d=Z%dede&fd>d?Z'dZded+ededB 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.e/dLdM Z0dNdO Z1dPdQ Z2dRdS Z3  Z4S )\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)
    ```
    rJ   hfN)endpointtoken
block_sizeexpand_inforz   r{   r|   r}   c                   sT   t  j|i | |ptj| _|| _t||d| _|| _|| _	i | _
i | _i | _d S )N)rz   r{   )rW   rX   r   ENDPOINTrz   r{   r%   _apir|   r}   _repo_and_revision_exists_cache_bucket_exists_cachedircache)r6   rz   r{   r|   r}   r[   ro   r]   r7   r8   rX      s   	
zHfFileSystem.__init__threading_identr2   c                    s\     dptj d<   d d<  fddt D  | || f}tt| }| S )zDeterministic token for cachingrz   r{   c                       i | ]}| | qS r7   r7   ).0keyr\   r7   r8   
<dictcomp>       z*HfFileSystem._tokenize.<locals>.<dictcomp>)rM   r   r~   sortedr.   r>   encode	hexdigest)rZ   r   r[   r\   tokenize_argshr7   r   r8   ra      s   zHfFileSystem._tokenizerA   rB   rC   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)rC   rA   timeoutFTN)r   r   	repo_infor   HF_HUB_ETAG_TIMEOUTr   r)   r   )r6   rA   rB   rC   er7   r7   r8   _repo_and_revision_exist   s"   

 z%HfFileSystem._repo_and_revision_existrS   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   )r   r   bucket_infor   )r6   rS   r   r7   r7   r8   _bucket_exists
  s   


zHfFileSystem._bucket_existsr1   c                 C   s"  |  |}|std|ddkrtd| dttj | }|jr=| |j	\}}|s5t
|| t|j	|jdS |dur|jdur|j|kr|dd tjv r]|ddd n|}|d	d\}}d|v rq|ddn|d
f\}	}
t|	}||krtd| d| d| |j||\}}|st
|| t|j|||
|	dS |jdur|du r|j}| |j|j	|\}}|st
|| d}d	|v r|jdur|dd tjv r|ddd n|}|d	dd }|jr|dt|jd   n|}|dur|ntj}t|j|j	||j|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.
        z<Access to buckets and repositories lists is not implemented.r3   r   z-Repository id must be 'namespace/name', got 'z<'. Single-segment ids (e.g. 'gpt2') are no longer supported.)rS   r1   Nr   rK   rJ   zRevision specified in path ("z ") and in `revision` argument ("z") are not the same.)rI   )_strip_protocolNotImplementedErrorcount
ValueErrorr-   r   HF_PROTOCOL	is_bucketr   id_raise_file_not_foundrR   rD   rC   splitHF_URI_TYPE_PREFIXESr   r   rh   r@   lenrN   )r6   r1   rC   parsedbucket_existserrpath_without_typerB   after_atrevision_in_pathrD   revision_in_path_decodedrepo_and_revision_existraw_revisionraw_after_atr7   r7   r8   resolve_path  sT   


( 

("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)r   clearr   r   r9   r`   _parentr1   
isinstancer@   rA   rB   rC   r   rS   )r6   r1   resolved_pathr7   r7   r8   invalidate_cachec  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 )Nr|   az/Appending to remote files is not yet supported.r   )r   rC   )r|   r   r   r   )r6   r1   r   r|   rC   r\   r7   r7   r8   _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rC   deletecommit_messagecommit_description)rD   rB   r{   rA   rC   r   r   r1   )r   r   rR   r   batch_bucket_filesrS   r1   delete_filerD   rB   r{   rA   rC   rM   r   r9   )r6   r1   rC   r\   r   r7   r7   r8   _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   rC   c                    "   g | ]}  |s |jqS r7   isdirr   r1   r   r1   r5   r7   r8   
<listcomp>     " z#HfFileSystem.rm.<locals>.<listcomp>r   c                    r   r7   r   r   r5   r7   r8   r     r   c                 S   s   g | ]}t |d qS ))rD   )r   )r   rD   r7   r7   r8   r     r   zDelete  zrecursively rJ   Nzup to depth r   r   )rB   rA   r{   
operationsrC   r   r   r   )r   expand_pathr   rR   r   r   rS   create_commitrB   rA   r{   rC   rM   r   r9   )r6   r1   r   r   rC   r\   r   pathsr   paths_in_repor   r   r7   r5   r8   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   rC   Nc                       g | ]
}|d   kr|qS namer7   r   or   r7   r8   r         z#HfFileSystem.ls.<locals>.<listcomp>r   c                 S   s   g | ]}|d  qS r   r7   r   r7   r7   r8   r     s    )r   r9   _ls_treer   r1   r   r   r   )r6   r1   r   r   rC   r\   r   outr7   r   r8   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      c                    s    g | ]}|d  dkr |fqS rh   	directoryr7   r   	path_infodepthr7   r8   r     s     z)HfFileSystem._ls_tree.<locals>.<listcomp>r   c                    s$   g | ]}|d  dkr d |fqS )rh   r   r   r7   r   r   r7   r8   r   )  s
    
c                    s&   g | ]}|d  du r  |d qS )last_commitNr   )r   r   r5   r7   r8   r   3  s   & r3   c                    s"   g | ]}|d    d s|qS )r   r3   )
startswithr   )common_pathr7   r8   r   D  r   T)r   r   rC   r}   r   )prefixr   )r   expandrC   rA   filer   sizerh   blob_idlfsxet_hashr   security)r   r   rh   r   mtimeuploaded_atr   r   r   r   rh   tree_idr   )r   r   rh   r   )-r}   r   r9   r0   r   extendr   popleftappendr   r@   osr1   commonprefixendswithr
   r4   r   r   r   listr   r`   r   rR   _list_bucket_tree_with_foldersrS   r   list_repo_treerB   rC   rA   r'   r   r   r   r   r   r   r#   r   r   r(   r   
setdefault)r6   r1   r   r   rC   r}   r   r   	root_pathr   cached_path_infosdirs_not_in_dircachedirs_to_visitdir_infodirs_not_expandedcommon_prefixcommon_path_depthcached_pathtreer   
cache_pathcache_path_infoparent_pathr7   )r   r   r6   r8   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   r3   r   Nr   )rh   r1   r   zFile not found in bucket 'z': '')r   list_bucket_treer   r   r   r   r1   parentsr$   r>   r   r   )r6   rS   r   r   bucket_filesbucket_folders	min_depthr   bucket_entryparent_bucket_folder_strparent_bucket_folderbucket_folderr7   r7   r8   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.
        rC   r   N)r   rM   r9   rW   walk)r6   r1   r[   r\   r]   r7   r8   r    s   $zHfFileSystem.walkc                    s0   | j ||dd }t j|fd|i|S )a  
        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.
            maxdepth (`int`, *optional*):
                Maximum depth to descend into directories. By default, no limit.

        Returns:
            `list[str]`: List of paths matching the pattern.
        rC   r   r   )r   rM   r9   rW   glob)r6   r1   r   r\   r]   r7   r8   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   rC   rh   r   c                 S   s   g | ]
}|d  dkr|qS r   r7   r   r7   r7   r8   r     r   z%HfFileSystem.find.<locals>.<listcomp>r   c                 S   s   i | ]}|d  |qS r   r7   r   r7   r7   r8   r     r   z%HfFileSystem.find.<locals>.<dictcomp>c                    r   r7   r7   )r   r   r   r7   r8   r     r   )r   r   r9   r   r   infoFileNotFoundErrorr   )r6   r1   r   r  r   r   rC   r\   r   r   namesr7   r  r8   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   rJ   )src_path_in_reporD   src_revision)rB   rA   rC   r   r   r   r   Npath_or_fileobjrD   rB   r{   rA   rC   r   r   r   )r   r   rR   r   rA   rB   r   r   rC   rM   r   rD   openreadupload_filer{   r   r9   )r6   r  r  rC   r\   resolved_path1resolved_path2	same_repor   fcontentr7   r7   r8   cp_file  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.
        r}   Tr   Nz9'modified' is not implemented for repository paths like 'r	  r   r   z'Cannot determined 'modified' for path 'z	' (info: ))r  r   date)r6   r1   r\   r  r7   r7   r8   modifiedS  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   r}   NFr   r   )r   r   rh   r   )rA   rC   )oidtitler+  )r   r   )r   c                    r   r   r7   r   r   r7   r8   r     r   z%HfFileSystem.info.<locals>.<listcomp>c                    r   r   r7   r   r   r7   r8   r     r   )r   rC   rA   rJ   )rD   rI   r3   r   r   r   c                    r   r7   r7   )r   kr  r7   r8   r     r   z%HfFileSystem.info.<locals>.<dictcomp>) r   r9   rM   r}   r1   r   r@   r   list_repo_commitsrB   rA   rC   r&   	commit_idr/  
created_atrR   r   r   r   r   get_paths_inforD   rI   r'   r   r   r   r   r   r   r   )r6   r1   r   rC   r\   r   r}   r   r  out1
paths_infor   r   r7   )r   r1   r8   r  l  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)rM   r   r  OSError)r6   r1   r\   r7   r7   r8   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.
        rh   r   Fr  r7  r6   r1   r7   r7   r8   r     
   zHfFileSystem.isdirc                 C   r9  )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.
        rh   r   Fr:  r;  r7   r7   r8   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/)rA   rC   rz   z/tree/r   )r   r   rR   rz   rS   r   r1   r    rB   rD   rA   rC   r   replace)r6   r1   r   urlr7   r7   r8   r?    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.

        rC   r   )callbackoutfileT)exist_okNFwbr   r   )r?  	temp_filedisplayed_filenameexpected_sizeresume_sizeheaders	_tqdm_bar)rM   setkeysr   r   r   r   rW   get_filer   r   r   makedirsr>   r   r1   dirnamer!  tellr   r  set_sizer!   r?  r9   r   _build_hf_headerstqdmseekclose)r6   rpathlpathr@  rA  r\   rC   unhandled_kwargs
close_fileinitial_posresolve_remote_pathrF  r]   r7   r8   rL  1  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   r5   r7   r7   r8   transactiono  s   	zHfFileSystem.transactionc                 C   r[  )z@Begin write transaction for deferring files, non-context versionr\  r]  r5   r7   r7   r8   start_transactionz  s   zHfFileSystem.start_transactionc                 C   s   t t| | j| j|  ffS rV   )make_instancerh   rn   ro   rj   r5   r7   r7   r8   
__reduce__  s   zHfFileSystem.__reduce__c                 C   s   t | jt | jt | jdS )N)r   r   r   )r   r   r   r   r5   r7   r7   r8   rj     s   z HfFileSystem._get_instance_staterV   )r   NN)FNN)TFN)FFNNN)NFFFN)FNr2   N)5r:   r;   r<   r=   root_markerprotocolr>   boolintrX   classmethodra   tuple	Exceptionr   r   r@   rR   r   r   r   r   r   r   r   dictr   r   r   r   r#   r$   r   r   r  r  r  r)  r	   r,  r  r8  r   r=  r?  r   rL  propertyr^  r_  ra  rj   rw   r7   r7   r]   r8   rx      s   B


O$

3
.
 

,($	
 =<(n>

	rx   )	metaclassc                       s   e Zd ZddedededB 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fsr1   rC   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   rJ   B.
Make sure the repository and revision exist before writing data.)r   r   r  rM   rW   rX   r9   )r6   rm  r1   rC   r\   r   r]   r7   r8   rX     s   zHfFileSystemFile.__init__c                    s   t | dsd S t  S Nr   )hasattrrW   __del__r5   r]   r7   r8   rr    s   

zHfFileSystemFile.__del__startendr2   c                 C   sL   dd| d|d  i| j j }|  }td||tjd}t| |jS )Nrangebytes=-r   GETrH  r   )	rm  r   rQ  r?  r+   r   HF_HUB_DOWNLOAD_TIMEOUTr*   r(  )r6   rs  rt  rH  r?  rr7   r7   r8   _fetch_range  s   
zHfFileSystemFile._fetch_rangec                 C   s   t jddd| _d S )Nzhffs-F)r   r   )tempfileNamedTemporaryFilerD  r5   r7   r7   r8   _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   )bufferrS  r"  rD  writerT  r   r   rR   rm  r   r   rS   r   r1   r#  rD   rB   r{   rA   rC   r\   rM   r   remover   r9   )r6   r  blockr7   r7   r8   _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   )r|   )r   locrm  r!  r1   r"  r   rW   )r6   lengthr'  r   r]   r7   r8   r"    s   $ zHfFileSystemFile.readc                 C      | j | jS rV   rm  r?  r1   r5   r7   r7   r8   r?       zHfFileSystemFile.urlrV   rb  )Fr-  )r:   r;   r<   rx   r>   rX   rr  rf  bytesr|  r  re  r  r"  r?  rw   r7   r7   r]   r8   r     s     

r   c                       s   e Zd Z				d!dededededB 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   nonerm  r1   r   rC   r|   
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 r  z?HfFileSystemStreamFile only supports cache_type='none' but got rn  z;HfFileSystemStreamFile only supports reading but got mode='r	  r   r   rJ   ro  )r   r   r   r|   r  )r   r   r   r  rM   r9   detailsrW   rX   responser   _exit_stack_stream_iterator	bytearray_stream_buffer)	r6   rm  r1   r   rC   r|   r  r\   r   r]   r7   r8   rX     s>   

zHfFileSystemStreamFile.__init__r  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)r  r   )r6   r  r  r7   r7   r8   rS     s
   zHfFileSystemStreamFile.seekr-  r  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_streamr  r   ri  rT  )r6   r  retried_oncer   r7   r7   r8   r"    s&   


zHfFileSystemStreamFile.readiteratorr2   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   r  r   )r6   r  r  bufchunkresultneedr7   r7   r8   r  #  s,   



z(HfFileSystemStreamFile._read_from_streamc                 C   r  rV   r  r5   r7   r7   r8   r?  E  r  zHfFileSystemStreamFile.urlc                    s"   t | dsd S | j  t  S rp  )rq  r  rT  rW   rr  r5   r]   r7   r8   rr  H  s   


zHfFileSystemStreamFile.__del__c                 C   s   t | j| j| j| j| jjffS rV   )reopenrm  r1   r   	blocksizecacher   r5   r7   r7   r8   ra  O  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   rv  rw  Rangerx  ry  i  )r  r   r  r?  rm  r   rQ  r  r  enter_contextr,   r   rz  r  r*   r   status_code
iter_bytes)r6   r?  rH  r   r7   r7   r8   r  R  s0   

	z'HfFileSystemStreamFile._open_connection)r   Nr   r  )r   r  )r:   r;   r<   rx   r>   rf  rX   rS  r"  r   r  r  r?  rr  ra  r  rw   r7   r7   r]   r8   r     s2    #"r   rC   r2   c                 C   s   t | r| S t| S rV   )r"   match
safe_quoter   r7   r7   r8   rO   q  s   rO   sc                 C   s   t | ddS )NrJ   )safe)r   )r  r7   r7   r8   r  u  s   r  r1   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  )r1   r   msgr7   r7   r8   r   y  s   




r   rm  r   r|   r  c                 C   s   | j ||||dS )Nr  )r!  )rm  r1   r   r|   r  r7   r7   r8   r    s   r  c                 C   s0   | |i |}|  D ]
\}}t||| q|S rV   )rk   rl   )rZ   r[   r\   rt   rm  ru   rv   r7   r7   r8   r`    s   r`  )Zr   r}  rb   collectionsr   collections.abcr   r   
contextlibr   copyr   dataclassesr   r   r	   	itertoolsr
   pathlibr   r   typingr   r   r   urllib.parser   r   fsspechttpxfsspec.callbacksr   r   r   fsspec.configr   fsspec.utilsr   rJ   r   _commit_apir   r   errorsr   r   r   r   r   file_downloadr    r!   hf_apir"   r#   r$   r%   r&   r'   r(   utilsr)   r*   r+   r,   r-   utils.insecure_hashlibr.   r/   r@   rR   rh   AbstractFileSystemrT   r?   rU   rx   specAbstractBufferedFiler   r   r>   rO   r  ri  r   rf  r  r`  hffsr7   r7   r7   r8   <module>   sf   
 $
5        K 
