U
    diҼ                     @   s  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 d dlmZmZ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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* ddl+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5 e6dej7Z8eG dd dZ9G dd dej:Z;G dd dej<j=Z>G dd dej<j=Z?e@e@dddZAe@e@dd d!ZBe@eeC ed"d#d$ZDe;e@e@eEe@d%d&d'ZFd(d) ZGdS )*    N)deque)	dataclassfield)datetime)chain)Path)AnyDictIteratorListNoReturnOptionalTupleUnion)quoteunquote)_DEFAULT_CALLBACKNoOpCallbackTqdmCallback)
isfilelike)Response   )	constants)CommitOperationCopyCommitOperationDelete)EntryNotFoundErrorRepositoryNotFoundErrorRevisionNotFoundError)
hf_hub_urlhttp_get)HfApiLastCommitInfoRepoFile)HFValidationErrorhf_raise_for_statushttp_backoffzy
    (^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	< ed
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rh| dt
| j d| j dS | d| j dS d S )N @/)r   REPO_TYPES_URL_PREFIXESgetr'   r(   r-   r*   rstripr)   DEFAULT_REVISIONsafe_revision)selfZ	repo_path r9   B/tmp/pip-unpacked-wheel-ohruig0i/huggingface_hub/hf_file_system.py	unresolve0   s    "z"HfFileSystemResolvedPath.unresolve)
__name__
__module____qualname____doc__str__annotations__r   r-   r   r;   r9   r9   r9   r:   r&   $   s   
r&   c                       st  e Zd ZdZdZdZddddee ee	edf ee
 d fddZeeee ee	ee f dd	d
ZdCeee edddZdDee ddddZdEeeee ee
 ddddZdFeee ddddZdGee	ee
 ee ddddZdHee	e	ee eeeeeef f  dddZdIee	e	ee e	ee
 d d!d"Zeeeeee ee f  d fd#d$Zeee d fd%d&ZdJeee
 e	e	e	ee eee eeeeef f f d'd(d)ZdKeeee dd*d+d,Zeedd-d.Z dLee	ee eeef d/d0d1Z!d2d3 Z"d4d5 Z#d6d7 Z$eedd8d9Z%e&dfdd: fd;d<Z'e(d=d> Z)d?d@ Z*dAdB Z+  Z,S )MHfFileSystema%  
    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:
        token (`str` or `bool`, *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`.
        endpoint (`str`, *optional*):
            Endpoint of the Hub. Defaults to <https://huggingface.co>.
    Usage:

    ```python
    >>> from huggingface_hub import HfFileSystem

    >>> fs = HfFileSystem()

    >>> # List files
    >>> fs.glob("my-username/my-model/*.bin")
    ['my-username/my-model/pytorch_model.bin']
    >>> fs.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 fs.open("my-username/my-model/pytorch_model.bin") as f:
    ...     data = f.read()
    >>> with fs.open("my-username/my-model/pytorch_model.bin", "wb") as f:
    ...     f.write(data)
    ```
    r0   ZhfN)endpointtoken
block_sizec                   sD   t  j|| |ptj| _|| _t||d| _|| _i | _	i | _
d S )N)rC   rD   )super__init__r   ZENDPOINTrC   rD   r    _apirE   _repo_and_revision_exists_cachedircache)r8   rC   rD   rE   argsstorage_options	__class__r9   r:   rG   c   s    zHfFileSystem.__init__)r'   r(   r)   r/   c              
   C   s   |||f| j krz| jj|||tjd W n ttfk
rx } z,d|f| j |||f< d|f| j ||d f< W 5 d }~X Y nf tk
r } z(d|f| j |||f< d| j ||d f< W 5 d }~X Y n"X d| j |||f< d| j ||d f< | j |||f S )N)r)   r'   timeoutF)TN)rI   rH   Z	repo_infor   ZHF_HUB_ETAG_TIMEOUTr   r#   r   )r8   r'   r(   r)   er9   r9   r:   _repo_and_revision_existy   s"       
$"z%HfFileSystem._repo_and_revision_exist)pathr)   r/   c                 C   s|  t t t t t t ddd}| |}|s6tdnN|dd d tj kr~d|krbtd|dd\}}tj| }ntj	}|
ddkr d|kr>|dd\}}d|krt|}|d	k	r|d	| fk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	 }|}|}| |||\}	}
|	sVt|
ttfr|}|}| |||\}	}|	st||
 n
t||
 nV|}d
}d|kr2|dd\}}|t||}nd	}| |||\}	}|	sVtd|d	k	rd|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   s8   |d k	r0| d k	r4| |kr4t d|  d| dn| }|S )NzRevision specified in path ("z ") and in `revision` argument ("z") are not the same.)
ValueError)rS   r)   r9   r9   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   Nr0      )r-   )r   r@   Z_strip_protocolNotImplementedErrorsplitr   r3   valuesZREPO_TYPES_MAPPINGZREPO_TYPE_MODELcountSPECIAL_REFS_REVISION_REGEXsearchgroupsublstripr   rQ   _raise_file_not_foundjoin
isinstancer   r#   r6   r&   )r8   rR   r)   rU   r'   r(   rS   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_r9   r9   r:   resolve_path   sl     






zHfFileSystem.resolve_path)rR   r/   c                 C   s   |s| j   | j  nh| |}| }|rJ| j |d | |}q,|js| j|j|j	dfd | j|j|j	|j
fd 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)rJ   clearrI   rf   r;   pop_parentr*   r'   r(   r)   )r8   rR   resolved_pathr9   r9   r:   invalidate_cache   s    

 zHfFileSystem.invalidate_cacherbHfFileSystemFile)rR   moder)   rE   r/   c                 K   sn   |d k	r|n| j }|d k	r"||d< d|kr2td|dkrRt| |f||d|S t| |f||d|S d S )NrE   az/Appending to remote files is not yet supported.r   )rn   r)   )rE   rW   HfFileSystemStreamFilerm   )r8   rR   rn   r)   rE   kwargsr9   r9   r:   _open  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(   rD   r'   r)   rt   ru   rR   )rf   rH   Zdelete_filer*   r(   rD   r'   r)   r4   rk   r;   )r8   rR   r)   rq   rj   r9   r9   r:   _rm  s    	zHfFileSystem._rmF)rR   	recursivemaxdepthr)   r/   c              
      s    j ||d} j||||d} fdd|D }dd |D }	d| d}
|
|rVdnd	7 }
|
|d
k	rrd| 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.

        rs   )rx   ry   r)   c                    s"   g | ]}  |s |jqS r9   )isdirrf   r*   ).0rR   r8   r9   r:   
<listcomp>C  s     
 z#HfFileSystem.rm.<locals>.<listcomp>c                 S   s   g | ]}t |d qS ))r*   )r   )r{   r*   r9   r9   r:   r}   D  s     zDelete  zrecursively r0   Nzup to depth rt   ru   )r(   r'   rD   
operationsr)   rt   ru   rv   )rf   Zexpand_pathrH   create_commitr(   r'   rD   r)   r4   rk   r;   )r8   rR   rx   ry   r)   rq   rj   pathsZpaths_in_repor   rt   r9   r|   r:   rm&  s"    
	zHfFileSystem.rmT)rR   detailrefreshr)   r/   c                    s   | j  |d}|  z| j f||d|}W nj tk
r   |jsRt d | j|  f||d|} fdd|D }t|dkrt d Y nX |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).
        rs   )r   r)   Nc                    s   g | ]}|d   kr|qS namer9   r{   orv   r9   r:   r}   w  s      z#HfFileSystem.ls.<locals>.<listcomp>r   c                 S   s   g | ]}|d  qS r   r9   r   r9   r9   r:   r}   z  s     )rf   r;   _ls_treer   r*   r`   ri   len)r8   rR   r   r   r)   rq   rj   outr9   rv   r:   lsT  s    
zHfFileSystem.ls)rR   rx   r   r)   expand_infory   c              
      s  j ||d}| }t|j|j|jd|jd }g }	|jkr|sj| }
|	|
 g }|rdt	fdd|
D }|r|
 \}|d ks|kr|d jkr||d  qj|d  }
|	|
 |fdd|
D  qg }|rfd	d|	D }|r|s$|r|rtj|| }|d
sZ||ksZ|t||krd|d
n| |d k	r t|d  d
}||8 } fdd|	D }	tjD ]$}| d
 rj|d  qj d  |	j |d|||d nЈjj|j|j|||j|jd}|D ]}|d
 |j }t|trf||jd|j|j |j!|j"d}n|dd|j#|j!d}|d }j$|g | |t|d  d
|d ksƈ|kr(|	| q(|	S )Nrs   r0   r*   r-   rV   c                    s    g | ]}|d  dkr |fqS type	directoryr9   r{   	path_infodepthr9   r:   r}     s      z)HfFileSystem._ls_tree.<locals>.<listcomp>r   c                    s$   g | ]}|d  dkr d |fqS )r   r   r   r9   r   r   r9   r:   r}     s   c                    s&   g | ]}|d  dkr  |d qS )last_commitNr   )ri   r   r|   r9   r:   r}     s      r2   c                    s"   g | ]}|d    d s|qS )r   r2   )
startswithr   )common_pathr9   r:   r}     s      T)rx   r   r)   r   ry   )rx   expandr)   r'   filer   sizer   blob_idlfsr   securityr   r   r   r   r   tree_idr   )%rf   r;   r&   r'   r(   r)   r-   rJ   extendr   popleftappendosrR   commonprefixendswithr   r5   ri   r   rZ   listr   rh   r   rH   Zlist_repo_treer*   rb   r"   r   r   r   r   r   r   
setdefault)r8   rR   rx   r   r)   r   ry   rj   	root_pathr   Zcached_path_infosZdirs_not_in_dircacheZdirs_to_visitZdir_infoZdirs_not_expandedcommon_prefixZcommon_path_depthZcached_pathtreer   
cache_pathZcache_path_infoparent_pathr9   )r   r   r8   r:   r   |  s    	





zHfFileSystem._ls_treec                 /   s6   | j ||dd }t j|f||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)   rs   N)rf   r4   r;   rF   walk)r8   rR   rK   rq   rM   r9   r:   r     s    zHfFileSystem.walkc                    s(   | j ||dd }t j|f|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)   rs   )rf   r4   r;   rF   globr8   rR   rq   rM   r9   r:   r     s    zHfFileSystem.glob)rR   ry   withdirsr   r   r)   r/   c                    s,  |dk	r|dk rt d| j||d}| }z"| j|fd||j|d| W n^ tk
r   z0| j|fd|i|d d	kr|i i ni  W n tk
r   i  Y nX Y nVX |sd
d  D  n2| j|fd|ji|}	|	d dkr|	g  n  dd  D  t }
|s|
S  fdd|
D S 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 1rs   T)rx   r   r)   ry   r)   r   r   c                 S   s   g | ]}|d  dkr|qS r   r9   r   r9   r9   r:   r}   E  s      z%HfFileSystem.find.<locals>.<listcomp>r   c                 S   s   i | ]}|d  |qS r   r9   r   r9   r9   r:   
<dictcomp>J  s      z%HfFileSystem.find.<locals>.<dictcomp>c                    s   i | ]}| | qS r9   r9   )r{   r   r   r9   r:   r   O  s      )	rT   rf   r;   r   r)   r   infoFileNotFoundErrorsorted)r8   rR   ry   r   r   r   r)   rq   rj   r   namesr9   r   r:   find  s>        

zHfFileSystem.find)path1path2r)   r/   c                 K   s  | j ||d}| j ||d}|j|jko2|j|jk}|rd| d| }| jj|j|j|j|d||ddt|j|j|jdgd nj| j	|d	|jd}	|	
 }
W 5 Q R X 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.

        rs   zCopy z to rt   ru   r0   )Zsrc_path_in_repor*   Zsrc_revision)r(   r'   r)   rt   ru   r   rl   Zpath_or_fileobjr*   r(   rD   r'   r)   rt   ru   rv   N)rf   r'   r(   rH   r   r)   r4   r   r*   openreadupload_filerD   rk   r;   )r8   r   r   r)   rq   Zresolved_path1Zresolved_path2Z	same_report   fcontentr9   r9   r:   cp_fileQ  sD    



zHfFileSystem.cp_filec                 K   s"   | j |f|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.
        r   Tr   dater   )r8   rR   rq   r   r9   r9   r:   modified  s    zHfFileSystem.modified)rR   r   r)   r/   c                    s  | j |d}| |dd}|jsxdddd |rt| jj|j|j|jdd	 } dt	|j
|j|jd
d nDd | }|s|| jkr| | || jkrևfdd| j| D }	|	std |	d  |s dks|r r d dkr| jj|j|j||j|jd}
|
s*td |
d }t|j|j|jd|jd }t|tr|d |j |jd|j|j|j|jd n|d |j dd|j|jd |s fdddD   dk	st 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.).

        rs   r   Fr   r   N)r   r   r   r   )r'   r)   )oidtitler   )r   r   c                    s   g | ]}|d   kr|qS r   r9   r   rv   r9   r:   r}     s      z%HfFileSystem.info.<locals>.<listcomp>r   )r   r)   r'   r0   r   r2   r   r   r   c                    s   i | ]}| | qS r9   r9   )r{   kr   r9   r:   r     s      z%HfFileSystem.info.<locals>.<dictcomp>)r   r   r   )rf   r;   r4   r*   rH   Zlist_repo_commitsr(   r'   r)   r!   Z	commit_idr   Z
created_atri   rJ   r   r`   Zget_paths_infor&   r-   rb   r"   rR   r   r   r   r   r   r   AssertionError)r8   rR   r   r)   rq   rj   r   r   r   Zout1Z
paths_infor   r   r9   )r   rR   r:   r     s         



&

zHfFileSystem.infoc                 K   s>   z*| ddr| | | j|f| W dS    Y dS X 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   FTN)r4   rk   r   r   r9   r9   r:   exists  s    
zHfFileSystem.existsc                 C   s0   z|  |d dkW S  tk
r*   Y dS X dS )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.
        r   r   FN)r   OSErrorr8   rR   r9   r9   r:   rz     s    zHfFileSystem.isdirc                 C   s(   z|  |d dkW S    Y dS X 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.
        r   r   FNr   r   r9   r9   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)   rC   z	/resolve/z/tree/r   )	rf   r   r(   r*   r'   r)   rC   rz   replace)r8   rR   rj   urlr9   r9   r:   r   8  s    

zHfFileSystem.urlr.   c              
      sV  | d}t| dh }t|ttfr6t|dkrRt j||f||d|S t	|r`|}n| 
|r|tj|dd dS t|ttfrtjtj|dd d}|dkrt|d}d}| }	| j||d	}
| j||d	d
 }|| zTtt|
j|
j|
j|
j| jd|||d| j t|tr,|j ndd |!|	 W 5 |rP|  X dS )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wbrs   r   r(   r)   filenamer'   rC   )r   	temp_fileZdisplayed_filenameexpected_sizeZresume_sizeheadersZ	_tqdm_bar)"r4   setkeysrb   r   r   r   rF   get_filer   rz   r   makedirsr@   r   rR   dirnamer   tellrf   r   Zset_sizecloser   r   r(   r)   r*   r'   rC   rH   _build_hf_headersZtqdmseek)r8   ZrpathZlpathr   r   rq   r)   Zunhandled_kwargsZ
close_fileZinitial_posZresolve_remote_pathr   rM   r9   r:   r   O  sL    



zHfFileSystem.get_filec                 C   s   t ddS )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.NrW   r|   r9   r9   r:   transaction  s    	zHfFileSystem.transactionc                 C   s   t ddS )z@Begin write transaction for deferring files, non-context versionr   Nr   r|   r9   r9   r:   start_transaction  s    zHfFileSystem.start_transactionc                 C   s"   t t| | j| j| j| jdffS )N)rJ   rI   )make_instancer   Zstorage_argsrL   rJ   rI   r|   r9   r9   r:   
__reduce__  s    zHfFileSystem.__reduce__)N)N)rl   NN)N)FNN)TFN)FFNFN)NFFFN)N)FN)-r<   r=   r>   r?   Zroot_markerprotocolr   r@   r   boolintrG   r   	ExceptionrQ   r&   rf   rk   rr   rw   r   r   r	   r   r   r   r
   r   r   r   r   r   r   r   r   rz   r   r   r   r   propertyr   r   r   __classcell__r9   r9   rM   r:   rB   :   s   %  _      /        +     v*     ?8"bD

rB   c                       s   e Zd Zdeeee d fddZ fddZeee	ddd	Z
dd
ddZdeddddZd fdd	Zed
ddZ  ZS )rm   N)fsrR   r)   c              
      sz   z|j ||d| _W nD tk
rX } z&d|ddkrFt| d| W 5 d }~X Y nX t j|| j f| |  d S )Nrs   wrn   r0   B.
Make sure the repository and revision exist before writing data.)rf   rj   r   r4   rF   rG   r;   )r8   r   rR   r)   rq   rP   rM   r9   r:   rG     s    zHfFileSystemFile.__init__c                    s   t | dsd S t  S Nrj   hasattrrF   __del__r|   rM   r9   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rangezbytes=-r   r   GET)r   rO   )r   rH   r   r   rj   r(   r)   r*   r'   rC   r%   r   HF_HUB_DOWNLOAD_TIMEOUTr$   r   )r8   r   r   r   r   rr9   r9   r:   _fetch_range  s     
zHfFileSystemFile._fetch_ranger.   c                 C   s   t jddd| _d S )Nzhffs-F)prefixdelete)tempfileNamedTemporaryFiler   r|   r9   r9   r:   _initiate_upload  s    z!HfFileSystemFile._initiate_uploadF)finalr/   c                 C   s   | j d | j  }| j| |r| 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 )Nr   rt   ru   r   rv   )bufferr   r   r   writer   r   rH   r   r   rj   r*   r(   rD   r'   r)   rq   r4   r   removerk   r;   )r8   r  blockr9   r9   r:   _upload_chunk  s&    




zHfFileSystemFile._upload_chunkr   c              
      sv   | j dkrj|dks|dkrj| jdkrj| jj| jddd,}| }|  jt|7  _|W  5 Q R  S Q R X t |S )a)  Read remote file.

        If `length` is not provided or is -1, the entire file is downloaded and read. On POSIX systems and if
        `hf_transfer` is not enabled, the file is loaded in memory directly. Otherwise, the file is downloaded to a
        temporary file and read from there.
        rl   Nr   r   )rE   )rn   locr   r   rR   r   r   rF   )r8   lengthr   r   rM   r9   r:   r     s    $zHfFileSystemFile.readc                 C   s   | j | jS Nr   r   rR   r|   r9   r9   r:   r     s    zHfFileSystemFile.url)N)F)r   )r<   r=   r>   rB   r@   r   rG   r   r   bytesr   r  r   r  r   r   r   r9   r9   rM   r:   rm     s   rm   c                       sv   e Zd Zdeeeee eed fddZdeedd	d
ZdedddZ	edddZ
 fddZdd Z  ZS )rp   rl   Nr   none)r   rR   rn   r)   rE   
cache_typec           	   
      s   |dkrt d| |dkr,t d| d|krDt d| dz|j||d| _W nB tk
r } z$d|d	d
krt| d|W 5 d }~X Y nX | j d d| _t j|| j f|||d| d | _	|  d S )Nr   z:HfFileSystemStreamFile only supports block_size=0 but got r  z?HfFileSystemStreamFile only supports cache_type='none' but got r   z;HfFileSystemStreamFile only supports reading but got mode=''rs   rn   r0   r   )r   r   rn   rE   r  )
rT   rf   rj   r   r4   r;   detailsrF   rG   response)	r8   r   rR   rn   r)   rE   r  rq   rP   rM   r9   r:   rG     s8    
   zHfFileSystemStreamFile.__init__)r	  whencec                 C   s6   |dkr|dkrd S || j kr*|dkr*d S tdd S )Nr   r   zCannot seek streaming HF file)r	  rT   )r8   r	  r  r9   r9   r:   r     s
    zHfFileSystemStreamFile.seekr   )r
  c                 C   sZ  |dkr|fnd}| j d krjt| jj| jj| jj| jj| jjd}t	d|| jj
 dtjd| _ t| j  zd| j j_| j jj| }W n tk
rB   | j   t| jj| jj| jj| jj| jjd}t	d|dd| j i| jj
 dtjd| _ t| j  zd| j j_| j jj| }W n" tk
r<   | j    Y nX Y nX |  jt|7  _|S )	Nr   r9   r   r   T)r   streamrO   ZRangez	bytes=%d-)r  r   rj   r(   r)   r*   r'   r   rC   r%   rH   r   r   r   r$   rawdecode_contentr   r   r   r	  r   )r8   r
  Z	read_argsr   r   r9   r9   r:   r   %  sZ    







zHfFileSystemStreamFile.readr.   c                 C   s   | j | jS r  r  r|   r9   r9   r:   r   V  s    zHfFileSystemStreamFile.urlc                    s   t | dsd S t  S r   r   r|   rM   r9   r:   r   Y  s    
zHfFileSystemStreamFile.__del__c                 C   s   t | j| j| j| j| jjffS r  )reopenr   rR   rn   	blocksizecacher   r|   r9   r9   r:   r   _  s    z!HfFileSystemStreamFile.__reduce__)rl   Nr   r  )r   )r   )r<   r=   r>   rB   r@   r   r   rG   r   r   r   r   r   r   r9   r9   rM   r:   rp     s"       1rp   )r)   r/   c                 C   s   t | r| S t| S r  )r[   rc   
safe_quoters   r9   r9   r:   r7   c  s    r7   )sr/   c                 C   s   t | ddS )Nr0   )safe)r   )r  r9   r9   r:   r  g  s    r  )rR   rd   r/   c                 C   sR   | }t |tr|  d}n*t |tr0|  d}nt |trD|  d}t||d S )Nz (repository not found)z (revision not found)z (invalid repository id))rb   r   r   r#   r   )rR   rd   msgr9   r9   r:   r`   k  s    



r`   r   rR   rn   rE   r  c                 C   s   | j ||||dS )Nr  )r   r  r9   r9   r:   r  v  s    r  c                 C   s,   | ||}|  D ]\}}t||| q|S r  )itemssetattr)clsrK   rq   Zinstance_cache_attributes_dictr   attrZcached_valuer9   r9   r:   r   z  s    
r   )Hr   rer   collectionsr   Zdataclassesr   r   r   	itertoolsr   pathlibr   typingr   r	   r
   r   r   r   r   r   urllib.parser   r   ZfsspecZfsspec.callbacksr   r   r   Zfsspec.utilsr   requestsr   r0   r   Z_commit_apir   r   errorsr   r   r   Zfile_downloadr   r   Zhf_apir    r!   r"   utilsr#   r$   r%   compileVERBOSEr[   r&   ZAbstractFileSystemrB   specZAbstractBufferedFilerm   rp   r@   r7   r  r   r`   r   r  r   r9   r9   r9   r:   <module>   sN   (
      }Me