U
    ”Ê¹jGd  ã                   @   s¬  U d Z ddlZddlZ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mZmZmZmZmZmZ ddl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 d
dlmZm Z m!Z!m"Z"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, e& -e.¡Z/dZ0dZ1dZ2ej3dej4d�Z5G dd„ deƒZ6G dd„ deƒZ7ej8dœdd„Z9eg ej8f Z:e9a;e:e<d< e9fe:ddœd d!„Z=ej8dœd"d#„Z>ddœd$d%„Z?ee@e@ej8d&œd'd(„ƒZAd)dd*ejBejCejDjEfd+d,œe,eFe@eGeGeeeH eeeH d-f f ee@ee@d-f f ed.œd/d0„ZIeFeeF eFd1œd2d3„ZJdAeeeF dd4œd5d6„ZKee# eFee#d7œd8d9„ZLejeFd:œd;d<„ZMe 3d=ejN¡ZOeeF e@eeF d>œd?d@„ZPdS )Bz>Contains utilities to handle HTTP requests in Huggingface Hub.é    N)Ú	lru_cache)Úquote)ÚAnyÚCallableÚListÚOptionalÚTupleÚTypeÚUnion)Ú	HTTPErrorÚResponse)ÚHTTPAdapter)ÚPreparedRequest)ÚOfflineModeIsEnabledé   )Ú	constants)ÚBadRequestErrorÚDisabledRepoErrorÚEntryNotFoundErrorÚGatedRepoErrorÚHfHubHTTPErrorÚRepositoryNotFoundErrorÚRevisionNotFoundErroré   )Úlogging)ÚJSONDecodeError)ÚSliceFileObj)ÚHTTP_METHOD_TúX-Amzn-Trace-Idzx-request-idzx-amz-cf-ida  
        # staging or production endpoint
        ^https://[^/]+
        (
            # on /api/repo_type/repo_id
            /api/(models|datasets|spaces)/(.+)
            |
            # or /repo_id/resolve/revision/...
            /(.+)/resolve/(.+)
        )
    )Úflagsc                       s4   e Zd ZdZ‡ fdd„Zeedœ‡ fdd„Z‡  ZS )ÚUniqueRequestIdAdapterr   c                    s„   t ƒ j|f|Ž t|jkr8|j t¡p0tt ¡ ƒ|jt< t	t|j dd¡ƒƒdk}t
 d|jt › d|j› d|j› d|› d�	¡ d S )	NÚauthorizationÚ r   zRequest ú: ú z (authenticated: ú))ÚsuperÚadd_headersÚX_AMZN_TRACE_IDÚheadersÚgetÚX_REQUEST_IDÚstrÚuuidÚuuid4ÚlenÚloggerÚdebugÚmethodÚurl)ÚselfÚrequestÚkwargsZ	has_token©Ú	__class__© úZ/var/www/html/bwave/python/venv/lib/python3.8/site-packages/huggingface_hub/utils/_http.pyr'   N   s    
&ÿz"UniqueRequestIdAdapter.add_headers©r5   Úreturnc              
      s†   t jrt dt|ƒ› �¡ ztƒ j|f|ž|ŽW S  tjk
r€ } z0|j	 
t¡}|dk	rn|jd|› d�f˜|_‚ W 5 d}~X Y nX dS )zSCatch any RequestException to append request id to the error message for debugging.zSend: Nz(Request ID: r%   )r   ZHF_DEBUGr0   r1   Ú_curlifyr&   ÚsendÚrequestsÚRequestExceptionr)   r*   r(   Úargs)r4   r5   rA   r6   ÚeÚ
request_idr7   r9   r:   r>   [   s    zUniqueRequestIdAdapter.send)	Ú__name__Ú
__module__Ú__qualname__r(   r'   r   r   r>   Ú__classcell__r9   r9   r7   r:   r    K   s   r    c                   @   s   e Zd Zeedœdd„ZdS )ÚOfflineAdapterr;   c                 O   s   t d|j› d�ƒ‚d S )NzCannot reach za: offline mode is enabled. To disable it, please unset the `HF_HUB_OFFLINE` environment variable.)r   r3   )r4   r5   rA   r6   r9   r9   r:   r>   j   s    ÿzOfflineAdapter.sendN)rD   rE   rF   r   r   r>   r9   r9   r9   r:   rH   i   s   rH   )r<   c                  C   sL   t  ¡ } tjr,|  dtƒ ¡ |  dtƒ ¡ n|  dtƒ ¡ |  dtƒ ¡ | S )Nzhttp://zhttps://)r?   ÚSessionr   ZHF_HUB_OFFLINEÚmountrH   r    )Úsessionr9   r9   r:   Ú_default_backend_factoryp   s    rL   Ú_GLOBAL_BACKEND_FACTORY)Úbackend_factoryr<   c                 C   s   | a tƒ  dS )aË  
    Configure the HTTP backend by providing a `backend_factory`. Any HTTP calls made by `huggingface_hub` will use a
    Session object instantiated by this factory. This can be useful if you are running your scripts in a specific
    environment requiring custom configuration (e.g. custom proxy or certifications).

    Use [`get_session`] to get a configured Session. Since `requests.Session` is not guaranteed to be thread-safe,
    `huggingface_hub` creates 1 Session instance per thread. They are all instantiated using the same `backend_factory`
    set in [`configure_http_backend`]. A LRU cache is used to cache the created sessions (and connections) between
    calls. Max size is 128 to avoid memory leaks if thousands of threads are spawned.

    See [this issue](https://github.com/psf/requests/issues/2766) to know more about thread-safety in `requests`.

    Example:
    ```py
    import requests
    from huggingface_hub import configure_http_backend, get_session

    # Create a factory function that returns a Session with configured proxies
    def backend_factory() -> requests.Session:
        session = requests.Session()
        session.proxies = {"http": "http://10.10.1.10:3128", "https": "https://10.10.1.11:1080"}
        return session

    # Set it as the default session factory
    configure_http_backend(backend_factory=backend_factory)

    # In practice, this is mostly done internally in `huggingface_hub`
    session = get_session()
    ```
    N)rM   Úreset_sessions)rN   r9   r9   r:   Úconfigure_http_backend   s     rP   c                   C   s   t t ¡ t ¡ d�S )aÜ  
    Get a `requests.Session` object, using the session factory from the user.

    Use [`get_session`] to get a configured Session. Since `requests.Session` is not guaranteed to be thread-safe,
    `huggingface_hub` creates 1 Session instance per thread. They are all instantiated using the same `backend_factory`
    set in [`configure_http_backend`]. A LRU cache is used to cache the created sessions (and connections) between
    calls. Max size is 128 to avoid memory leaks if thousands of threads are spawned.

    See [this issue](https://github.com/psf/requests/issues/2766) to know more about thread-safety in `requests`.

    Example:
    ```py
    import requests
    from huggingface_hub import configure_http_backend, get_session

    # Create a factory function that returns a Session with configured proxies
    def backend_factory() -> requests.Session:
        session = requests.Session()
        session.proxies = {"http": "http://10.10.1.10:3128", "https": "https://10.10.1.11:1080"}
        return session

    # Set it as the default session factory
    configure_http_backend(backend_factory=backend_factory)

    # In practice, this is mostly done internally in `huggingface_hub`
    session = get_session()
    ```
    ©Ú
process_idÚ	thread_id)Ú_get_session_from_cacheÚosÚgetpidÚ	threadingÚ	get_identr9   r9   r9   r:   Úget_session£   s    rY   c                   C   s   t  ¡  dS )z«Reset the cache of sessions.

    Mostly used internally when sessions are reconfigured or an SSLError is raised.
    See [`configure_http_backend`] for more details.
    N)rT   Úcache_clearr9   r9   r9   r:   rO   Ã   s    rO   )rR   rS   r<   c                 C   s   t ƒ S )zÒ
    Create a new session per thread using global factory. Using LRU cache (maxsize 128) to avoid memory leaks when
    using thousands of threads. Cache is cleared when `configure_http_backend` is called.
    )rM   rQ   r9   r9   r:   rT   Ì   s    rT   é   é   )iô  iö  i÷  iø  )Úmax_retriesÚbase_wait_timeÚmax_wait_timeÚretry_on_exceptionsÚretry_on_status_codes.)r2   r3   r]   r^   r_   r`   ra   r<   c                K   sv  t |tƒr|f}t |tƒr |f}d}|}	d}
d|krTt |d tjtfƒrT|d  ¡ }
tƒ }|d7 }zt|
dk	rz|d  |
¡ |j	f | |dœ|—Ž}|j
|kr |W S t d|j
› d| › d|› �¡ ||krÔ| ¡  |W S W nb |k
�r8 } zBt d	|› d
| › d|› �¡ t |tjƒ�rtƒ  ||k�r(|‚W 5 d}~X Y nX t d|	› d|› d|› d�¡ t |	¡ t||	d ƒ}	qZdS )a7  Wrapper around requests to retry calls on an endpoint, with exponential backoff.

    Endpoint call is retried on exceptions (ex: connection timeout, proxy error,...)
    and/or on specific status codes (ex: service unavailable). If the call failed more
    than `max_retries`, the exception is thrown or `raise_for_status` is called on the
    response object.

    Re-implement mechanisms from the `backoff` library to avoid adding an external
    dependencies to `hugging_face_hub`. See https://github.com/litl/backoff.

    Args:
        method (`Literal["GET", "OPTIONS", "HEAD", "POST", "PUT", "PATCH", "DELETE"]`):
            HTTP method to perform.
        url (`str`):
            The URL of the resource to fetch.
        max_retries (`int`, *optional*, defaults to `5`):
            Maximum number of retries, defaults to 5 (no retries).
        base_wait_time (`float`, *optional*, defaults to `1`):
            Duration (in seconds) to wait before retrying the first time.
            Wait time between retries then grows exponentially, capped by
            `max_wait_time`.
        max_wait_time (`float`, *optional*, defaults to `8`):
            Maximum duration (in seconds) to wait before retrying.
        retry_on_exceptions (`Type[Exception]` or `Tuple[Type[Exception]]`, *optional*):
            Define which exceptions must be caught to retry the request. Can be a single type or a tuple of types.
            By default, retry on `requests.Timeout`, `requests.ConnectionError` and `requests.exceptions.ChunkedEncodingError`.
        retry_on_status_codes (`int` or `Tuple[int]`, *optional*, defaults to `(500, 502, 503, 504)`):
            Define on which status codes the request must be retried. By default, 5xx errors are retried.
        **kwargs (`dict`, *optional*):
            kwargs to pass to `requests.request`.

    Example:
    ```
    >>> from huggingface_hub.utils import http_backoff

    # Same usage as "requests.request".
    >>> response = http_backoff("GET", "https://www.google.com")
    >>> response.raise_for_status()

    # If you expect a Gateway Timeout from time to time
    >>> http_backoff("PUT", upload_url, data=data, retry_on_status_codes=504)
    >>> response.raise_for_status()
    ```

    > [!WARNING]
    > When using `requests` it is possible to stream data by passing an iterator to the
    > `data` argument. On http backoff this is a problem as the iterator is not reset
    > after a failed call. This issue is mitigated for file objects or any IO streams
    > by saving the initial position of the cursor (with `data.tell()`) and resetting the
    > cursor between each call (with `data.seek()`). For arbitrary iterators, http backoff
    > will fail. If this is a hard constraint for you, please let us know by opening an
    > issue on [Github](https://github.com/huggingface/huggingface_hub).
    r   NÚdatar   )r2   r3   zHTTP Error z thrown while requesting r$   ú'z' thrown while requesting zRetrying in z	s [Retry ú/z].r   )Ú
isinstanceÚtypeÚintÚioÚIOBaser   ÚtellrY   Úseekr5   Ústatus_coder0   ÚwarningÚraise_for_statusr?   ÚConnectionErrorrO   ÚtimeÚsleepÚmin)r2   r3   r]   r^   r_   r`   ra   r6   Znb_triesZ
sleep_timeZio_obj_initial_posrK   ÚresponseÚerrr9   r9   r:   Úhttp_backoffÕ   s<    D





ru   )r3   Úendpointr<   c                 C   sD   |r|  d¡ntj}|tjtjfkr@|  tj|¡} |  tj|¡} | S )z¤Replace the default endpoint in a URL by a custom one.

    This is useful when using a proxy and the Hugging Face Hub returns a URL with the default endpoint.
    rd   )Úrstripr   ZENDPOINTZ_HF_DEFAULT_ENDPOINTZ_HF_DEFAULT_STAGING_ENDPOINTÚreplace)r3   rv   r9   r9   r:   Úfix_hf_endpoint_in_urlP  s
    ry   )rs   Úendpoint_namer<   c              
   C   sŒ  z|   ¡  W �nx tk
�r† } �zV| j d¡}| j d¡}|dkrt| j› d�d d| j› d� }tt|| ƒ|‚�nð|dkr¬| j› d�d d	| j› d� }tt|| ƒ|‚�n¸|d
krä| j› d�d d| j› d� }tt	|| ƒ|‚�n€|dk�r&| j› d�d d| j› d� d d }tt
|| ƒ|‚�n>|dk�st| jdk�r¦|dk�r¦| jdk	�r¦| jjdk	�r¦t | jj¡dk	�r¦| j› d�d d| j› d� d }tt|| ƒ|‚n¾| jdk�rÜ|dk	�rÈd|› d�nd}tt|| ƒ|‚nˆ| jdk�rd| j› d|› d�d| j› d� d }tt|| ƒ|‚nF| jdk�rd| jj d¡}|› d|› d | j d!¡› d�}tt|| ƒ|‚ttt|ƒ| ƒ|‚W 5 d}~X Y nX dS )"a(  
    Internal version of `response.raise_for_status()` that will refine a
    potential HTTPError. Raised exception will be an instance of `HfHubHTTPError`.

    This helper is meant to be the unique method to raise_for_status when making a call
    to the Hugging Face Hub.


    Example:
    ```py
        import requests
        from huggingface_hub.utils import get_session, hf_raise_for_status, HfHubHTTPError

        response = get_session().post(...)
        try:
            hf_raise_for_status(response)
        except HfHubHTTPError as e:
            print(str(e)) # formatted message
            e.request_id, e.server_message # details returned by server

            # Complete the error message with additional information once it's raised
            e.append_to_message("
`create_commit` expects the repository to exist.")
            raise
    ```

    Args:
        response (`Response`):
            Response from the server.
        endpoint_name (`str`, *optional*):
            Name of the endpoint that has been called. If provided, the error message
            will be more complete.

    > [!WARNING]
    > Raises when the request has failed:
    >
    >     - [`~utils.RepositoryNotFoundError`]
    >         If the repository to download from cannot be found. This may be because it
    >         doesn't exist, because `repo_type` is not set correctly, or because the repo
    >         is `private` and you do not have access.
    >     - [`~utils.GatedRepoError`]
    >         If the repository exists but is gated and the user is not on the authorized
    >         list.
    >     - [`~utils.RevisionNotFoundError`]
    >         If the repository exists but the revision couldn't be find.
    >     - [`~utils.EntryNotFoundError`]
    >         If the repository exists but the entry (e.g. the requested file) couldn't be
    >         find.
    >     - [`~utils.BadRequestError`]
    >         If request failed with a HTTP 400 BadRequest error.
    >     - [`~utils.HfHubHTTPError`]
    >         If request failed for a reason not listed above.
    zX-Error-CodeúX-Error-MessageZRevisionNotFoundz Client Error.ú

zRevision Not Found for url: Ú.ZEntryNotFoundzEntry Not Found for url: Z	GatedRepoz!Cannot access gated repo for url z$Access to this resource is disabled.z!Cannot access repository for url Ú
ZRepoNotFoundi‘  z+Invalid credentials in Authorization headerNzRepository Not Found for url: zí
Please make sure you specified the correct `repo_id` and `repo_type`.
If you are trying to access a private or gated repo, make sure you are authenticated. For more details, see https://huggingface.co/docs/huggingface_hub/authenticationi�  z

Bad request for z
 endpoint:z

Bad request:i“  z Forbidden: z
Cannot access content at: z2
Make sure your token has the correct permissions.i   ÚRangez. Requested range: z. Content-Range: zContent-Range)rn   r   r)   r*   rl   r3   Ú_formatr   r   r   r   r5   ÚREPO_API_REGEXÚsearchr   r   r   r,   )rs   rz   rB   Z
error_codeÚerror_messageÚmessageZrange_headerr9   r9   r:   Úhf_raise_for_status]  s€    5ÿ

ÿþýüÿ
ÿþý
üû
ÿþýÿ	ÿÿþÿr…   )Ú
error_typeÚcustom_messagers   r<   c                 C   s   g }|j  d¡}|d k	r"| |¡ zp| ¡ }| d¡}|d k	r^t|tƒrT| |¡ n
| |¡ | d¡}|d k	r�|D ]}d|krt| |d ¡ qtW n@ tk
rÒ   |j  dd¡}|jrÎd| 	¡ krÎ| |j¡ Y nX dd	„ |D ƒ}tt
 |¡ƒ}d
 |¡}	|}
|	�r:|	 	¡ | 	¡ k�r:d|k�r.|
d
|	 7 }
n|
d|	 7 }
d}d}tdftdftdffD ]<\}}|j  |¡}|�rXt|ƒ}d|› d|› d�} �q–�qX|�rè| 	¡ |
 	¡ k�rèd
|
k�rà|
 d
¡}|
d |… | |
|d …  }
n|
|7 }
| |
 ¡ ||	�púd d�S )Nr{   ÚerrorÚerrorsr„   zContent-Typer"   Úhtmlc                 S   s$   g | ]}t |ƒ ¡ rt |ƒ ¡ ‘qS r9   )r,   Ústrip)Ú.0Úliner9   r9   r:   Ú
<listcomp>  s      z_format.<locals>.<listcomp>r~   r|   z
Request IDzAmzn Trace IDz	Amz CF IDz (r#   r%   )rs   Úserver_message)r)   r*   ÚappendÚjsonre   ÚlistÚextendr   ÚtextÚlowerÚdictÚfromkeysÚjoinr+   r(   ÚX_AMZ_CF_IDr,   Úindexr‹   )r†   r‡   rs   Zserver_errorsZfrom_headersrb   rˆ   r‰   Úcontent_typer�   Zfinal_error_messagerC   Zrequest_id_messageÚheaderÚlabelÚvalueZnewline_indexr9   r9   r:   r€   ß  s\    






ý


ÿr€   r;   c                 C   s  dd| j fg}t| j ¡ ƒD ].\}}| ¡ dkr4d}|dd ||¡fg7 }q| jr²| j}t|tƒrr|j	ddd	�}nt
|d
ƒr€d}t|ƒdkrœ|dd… d }|d| dd¡fg7 }|d| jfg7 }g }|D ],\}}|rä| t|ƒ¡ |rÊ| t|ƒ¡ qÊd |¡S )zéConvert a `requests.PreparedRequest` into a curl command (str).

    Used for debug purposes only.

    Implementation vendored from https://github.com/ofw/curlify/blob/master/curlify.py.
    MIT License Copyright (c) 2016 Egor.
    )ZcurlNz-Xr!   z<TOKEN>z-Hz{0}: {1}zutf-8Úignore)r‰   Úreadz<file-like object>iè  Nz ... [truncated]z-dr~   r"   r$   )r2   Úsortedr)   Úitemsr•   ÚformatÚbodyre   ÚbytesÚdecodeÚhasattrr/   rx   r3   r�   r   r˜   )r5   ÚpartsÚkÚvr¤   Z
flat_partsr9   r9   r:   r=   0  s0    	þ

r=   z%^\s*bytes\s*=\s*(\d*)\s*-\s*(\d*)\s*$)Úoriginal_rangeÚresume_sizer<   c                 C   sð   | sd|› d�S d| kr(t d| ›d�ƒ‚t | ¡}|sFtd| ›d�ƒ‚| ¡ \}}|sœ|sjtd| ›d�ƒ‚t|ƒ| }d|› �}|d	kr˜td
|›d�ƒ‚|S t|ƒ}|| }|rät|ƒ}d|› d|› �}||kràtd
|›d�ƒ‚|S d|› d�S )zB
    Adjust HTTP Range header to account for resume position.
    zbytes=ú-ú,zMultiple ranges detected - z, not supported yet.zInvalid range format - r}   zbytes=-r   zEmpty new range - )Ú
ValueErrorÚRANGE_REGEXÚmatchÚRuntimeErrorÚgroupsrg   )r«   r¬   r±   ÚstartÚendZ
new_suffixZ	new_rangeÚ	new_startr9   r9   r:   Ú_adjust_range_header\  s2    

r·   )N)QÚ__doc__rh   rU   ÚrerW   rp   r-   Ú	functoolsr   Úshlexr   Útypingr   r   r   r   r   r	   r
   r?   r   r   Zrequests.adaptersr   Zrequests.modelsr   Zhuggingface_hub.errorsr   r"   r   r‰   r   r   r   r   r   r   r   r   Z_fixesr   Z_lfsr   Z_typingr   Z
get_loggerrD   r0   r(   r+   r™   ÚcompileÚVERBOSEr�   r    rH   rI   rL   ZBACKEND_FACTORY_TrM   Ú__annotations__rP   rY   rO   rg   rT   ÚTimeoutro   Ú
exceptionsÚChunkedEncodingErrorr,   ÚfloatÚ	Exceptionru   ry   r…   r€   r=   Ú
IGNORECASEr°   r·   r9   r9   r9   r:   Ú<module>   s~   $$	
ô$ 	ýôò{ Q)