o
    0i                     @   sP  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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mZmZmZmZmZ ddlm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%m&Z& ddlm'Z' ddl(m)Z) ddl*m+Z+ e',e-Z.eddG dd dZ/e0dZ1e0dZ2dee3e3f dee/ fddZ4dZ5dZ6dZ7ej0dej8dZ9ej0dej8dZ:e0d Z;e0d!Z<h d"Z=d#e3de>ee3 ee3 f fd$d%Z?d#e3dee3 fd&d'Z@d(ejAddfd)d*ZBd(ejAddfd+d,ZCd-ejDddfd.d/ZEdejFfd0d1ZGdejHfd2d3ZIeg ejFf ZJeg ejHf ZKeL ZMeGaNeJeOd4< eIaPeKeOd5< daQeejF eOd6< d7eJddfd8d9ZRd:eKddfd;d<ZSdejFfd=d>ZTdejHfd?d@ZUdtdAdBZVeWeV eXedCrzejYeVdD ejZej[fZ\e>e]e^ dEf eOdF< dGZ_e>e`dEf eOdH< dIddJe\e_dKdLdMe+d#e3dNe`dOeadPeadQee]e^ e>e]e^ dEf f dRee`e>e`dEf f dSebdeejDddf fdTdUZcdIddJe\e_dVdMe+d#e3dNe`dOeadPeadQee]e^ e>e]e^ dEf f dRee`e>e`dEf f dejDfdWdXZde
dIddJe\e_dVdMe+d#e3dNe`dOeadPeadQee]e^ e>e]e^ dEf f dRee`e>e`dEf f deejDddf fdYdZZedKd[dMe+d#e3d\ebdejDfd]d^Zfd#e3d_ee3 de3fd`daZgdud-ejDdbee3 ddfdcddZhei Zjd-ejDddfdedfZkedge#dhZldie]el dje3d-ejDdelfdkdlZmd(ejAde3fdmdnZne0doejoZpdpee3 dqe`dee3 fdrdsZqdS )vz>Contains utilities to handle HTTP requests in huggingface_hub.    N)contextmanager)	dataclass)quote)AnyCallable	GeneratorMappingOptionalTypeVarUnion)urlparse)OfflineModeIsEnabled   )	constants)BadRequestErrorBucketNotFoundErrorDisabledRepoErrorGatedRepoErrorHfHubHTTPErrorRemoteEntryNotFoundErrorRepositoryNotFoundErrorRevisionNotFoundError   )logging)SliceFileObj)HTTP_METHOD_TT)frozenc                   @   sJ   e Zd ZU dZeed< eed< eed< dZee ed< dZ	ee ed< dS )RateLimitInfoa  
    Parsed rate limit information from HTTP response headers.

    Attributes:
        resource_type (`str`): The type of resource being rate limited.
        remaining (`int`): The number of requests remaining in the current window.
        reset_in_seconds (`int`): The number of seconds until the rate limit resets.
        limit (`int`, *optional*): The maximum number of requests allowed in the current window.
        window_seconds (`int`, *optional*): The number of seconds in the current window.

    resource_type	remainingreset_in_secondsNlimitwindow_seconds)
__name__
__module____qualname____doc__str__annotations__intr!   r	   r"    r*   r*   U/home/kim/smarthome/.venv/lib/python3.10/site-packages/huggingface_hub/utils/_http.pyr   6   s   
 r   zL\"(?P<resource_type>\w+)\"\s*;\s*r\s*=\s*(?P<r>\d+)\s*;\s*t\s*=\s*(?P<t>\d+)z'q\s*=\s*(?P<q>\d+).*?w\s*=\s*(?P<w>\d+)headersreturnc                 C   s   d}d}| D ]}|  }|dkr| | }q|dkr| | }q|s"dS t|}|s+dS |d}t|d}t|d}d}	d}
|rYt|}|rYt|d}	t|d}
t||||	|
d	S )
a*  Parse rate limit information from HTTP response headers.

    Follows IETF draft: https://www.ietf.org/archive/id/draft-ietf-httpapi-ratelimit-headers-09.html
    Only a subset is implemented.

    Example:
    ```python
    >>> from huggingface_hub.utils import parse_ratelimit_headers
    >>> headers = {
    ...     "ratelimit": '"api";r=0;t=55',
    ...     "ratelimit-policy": '"fixed window";"api";q=500;w=300',
    ... }
    >>> info = parse_ratelimit_headers(headers)
    >>> info.remaining
    0
    >>> info.reset_in_seconds
    55
    ```
    N	ratelimitzratelimit-policyr   rtqw)r   r   r    r!   r"   )lower_RATELIMIT_REGEXsearchgroupr)   _RATELIMIT_POLICY_REGEXr   )r,   r.   policykeyZ	lower_keymatchr   r   r    r!   r"   Zpolicy_matchr*   r*   r+   parse_ratelimit_headersR   s>   



r;   zx-request-idzX-Amzn-Trace-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/(.+)
        )
    )flagszz
        # staging or production endpoint
        ^https?://[^/]+
        # on /api/buckets/...
        /api/buckets/
    zA^https?://[^/]+/api/(models|datasets|spaces)/([^/]+)(?:/([^/]+))?z)^https?://[^/]+/api/buckets/([^/]+/[^/]+)>	   commitresolvesettingsrawrefsZblobrevisiontreeZdiscussionsurlc                 C   sh   t | }|s	dS tj|d}|d|d}}|r.|tvr.| d| }||fS |}||fS )a,  Extract (repo_type, repo_id) from an API URL.

    Returns canonical repo_type values: "model", "dataset", "space" (or None).

    Examples:
        >>> _parse_repo_info_from_url("https://huggingface.co/api/models/user/repo")
        ("model", "user/repo")
        >>> _parse_repo_info_from_url("https://huggingface.co/api/datasets/user/repo/resolve/main/data.csv")
        ("dataset", "user/repo")
        >>> _parse_repo_info_from_url("https://huggingface.co/api/models/bert-base-cased/resolve/main/config.json")
        ("model", "bert-base-cased")
    NNr   r      /)_REPO_ID_FROM_URL_REGEXr5   r   ZREPO_TYPES_MAPPINGgetr6   _REPO_URL_SUBPATHS)rD   r:   	repo_typefirstsecondrepo_idr*   r*   r+   _parse_repo_info_from_url   s   
rO   c                 C   s   t | }|r|dS dS )z9Extract bucket_id (namespace/name) from a bucket API URL.r   N)_BUCKET_ID_FROM_URL_REGEXr5   r6   )rD   r:   r*   r*   r+   _parse_bucket_id_from_url   s   
rQ   requestc              	   C   s   t  rtd| j dt| jvr!| jtptt	
 | jt< | jt}td|| j| j| jddu t jrCtdt|  |S )z
    Event hook that will be used to make HTTP requests to the Hugging Face Hub.

    What it does:
    - Block requests if offline mode is enabled
    - Add a request ID to the request headers
    - Log the request if debug mode is enabled
    zCannot reach za: offline mode is enabled. To disable it, please unset the `HF_HUB_OFFLINE` environment variable.z%Request %s: %s %s (authenticated: %s)authorizationNzSend: %s)r   Zis_offline_moder   rD   X_AMZN_TRACE_IDr,   rI   X_REQUEST_IDr'   uuiduuid4loggerdebugmethodZHF_DEBUG_curlify)rR   
request_idr*   r*   r+   hf_request_event_hook   s"   	
r]   c                    s
   t | S )z3
    Async version of `hf_request_event_hook`.
    )r]   )rR   r*   r*   r+   async_hf_request_event_hook   s   r^   responsec                    sd   | j dkr,d| jv r.z	t| jd }W n
 ty   Y d S w |dk r0|  I d H  d S d S d S d S )N  zContent-lengthi@B )status_coder,   r)   
ValueErrorZaread)r_   lengthr*   r*   r+   async_hf_response_event_hook   s   

rd   c                   C   s   t jdtgidddS )zQ
    Factory function to create a `httpx.Client` with the default transport.
    rR   TNZevent_hooksfollow_redirectstimeout)httpxClientr]   r*   r*   r*   r+   default_client_factory  s
   rj   c                   C   s   t jtgtgddddS )zV
    Factory function to create a `httpx.AsyncClient` with the default transport.
    )rR   r_   TNre   )rh   AsyncClientr^   rd   r*   r*   r*   r+   default_async_client_factory  s
   rl   _GLOBAL_CLIENT_FACTORY_GLOBAL_ASYNC_CLIENT_FACTORY_GLOBAL_CLIENTclient_factoryc                 C   s4   t  t  | aW d   dS 1 sw   Y  dS )a  
    Set the HTTP client factory to be used by `huggingface_hub`.

    The client factory is a method that returns a `httpx.Client` object. On the first call to [`get_client`] the client factory
    will be used to create a new `httpx.Client` object that will be shared between all calls made by `huggingface_hub`.

    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_client`] to get a correctly configured `httpx.Client`.
    N)_CLIENT_LOCKclose_sessionrm   )rp   r*   r*   r+   set_client_factory+  s   "rs   async_client_factoryc                 C   s   | a dS )a  
    Set the HTTP async client factory to be used by `huggingface_hub`.

    The async client factory is a method that returns a `httpx.AsyncClient` object.
    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_async_client`] to get a correctly configured `httpx.AsyncClient`.

    <Tip warning={true}>

    Contrary to the `httpx.Client` that is shared between all calls made by `huggingface_hub`, the `httpx.AsyncClient` is not shared.
    It is recommended to use an async context manager to ensure the client is properly closed when the context is exited.

    </Tip>
    Nrn   )rt   r*   r*   r+   set_async_client_factory<  s   rv   c                   C   s8   t du rt t a W d   t S 1 sw   Y  t S )a  
    Get a `httpx.Client` object, using the transport factory from the user.

    This client is shared between all calls made by `huggingface_hub`. Therefore you should not close it manually.

    Use [`set_client_factory`] to customize the `httpx.Client`.
    N)ro   rq   rm   r*   r*   r*   r+   get_sessionO  s   	
rw   c                   C   s   t  S )a  
    Return a `httpx.AsyncClient` object, using the transport factory from the user.

    Use [`set_async_client_factory`] to customize the `httpx.AsyncClient`.

    <Tip warning={true}>

    Contrary to the `httpx.Client` that is shared between all calls made by `huggingface_hub`, the `httpx.AsyncClient` is not shared.
    It is recommended to use an async context manager to ensure the client is properly closed when the context is exited.

    </Tip>
    ru   r*   r*   r*   r+   get_async_session^  s   rx   c               
   C   sZ   t } da | dur+z|   W dS  ty* } ztd|  W Y d}~dS d}~ww dS )z
    Close the global `httpx.Client` used by `huggingface_hub`.

    If a Client is closed, it will be recreated on the next call to [`get_session`].

    Can be useful if e.g. an SSL certificate has been updated.
    NzError closing client: )ro   close	ExceptionrX   warning)clienter*   r*   r+   rr   n  s   	rr   register_at_fork)after_in_child._DEFAULT_RETRY_ON_EXCEPTIONS)  i  i  i  i  _DEFAULT_RETRY_ON_STATUS_CODES      F)max_retriesbase_wait_timemax_wait_timeretry_on_exceptionsretry_on_status_codesstreamrZ   r   r   r   r   r   r   c                +   s   t |tr	|f}t trfd|}	dd}
d|v r-t |d tjtfr-|d  }
t }	 d7 dzb|
durC|d |
 dt	j
dtf fdd	}|r|jdd
|}||ss|V  	 W d   W dS W d   n1 s}w   Y  n|jdd
|}||s|V  W dS W n/ |y } z#td| d d  t |t	jrt   kr|W Y d}~nd}~ww durtd }td| d d  d n|	}td| d d  d t| t||	d }	q1)zfInternal implementation of HTTP backoff logic shared between `http_backoff` and `http_stream_backoff`.r   NdataTr   r_   r-   c                    sf   | j vrdS td| j  d d   kr t|  dS | j dkr1t| j}|dur1|jdS )zNHandle response and return True if should retry, False if should return/yield.FzHTTP Error z thrown while requesting  r   NT)ra   rX   r{   hf_raise_for_statusr;   r,   r    )r_   ratelimit_infor   rZ   Znb_triesZratelimit_resetr   rD   r*   r+   _should_retry  s   


z)_http_backoff_base.<locals>._should_retryrZ   rD   'z' thrown while requesting r   zRate limited. Waiting zs before retry [Retry rG   z].zRetrying in z	s [Retry r   r*   )
isinstancetyper)   ioIOBaser   tellrw   seekrh   Responseboolr   rR   rX   r{   ZConnectErrorrr   floattimesleepmin)rZ   rD   r   r   r   r   r   r   kwargsZ
sleep_timeZio_obj_initial_posr|   r   r_   errZactual_sleepr*   r   r+   _http_backoff_base  sd   

"	 
r   )r   r   r   r   r   c                K   s$   t td| ||||||dd|S )a0  Wrapper around httpx 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 `httpx.TimeoutException` and `httpx.NetworkError`.
        retry_on_status_codes (`int` or `tuple[int]`, *optional*, defaults to `(429, 500, 502, 503, 504)`):
            Define on which status codes the request must be retried. By default, retries
            on rate limit (429) and server errors (5xx).
        **kwargs (`dict`, *optional*):
            kwargs to pass to `httpx.request`.

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

    # Same usage as "httpx.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).
    FrZ   rD   r   r   r   r   r   r   Nr*   )nextr   rZ   rD   r   r   r   r   r   r   r*   r*   r+   http_backoff  s   A	r   c                k   s,    t d| ||||||dd|E dH  dS )a  Wrapper around httpx 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 `httpx.TimeoutException` and `httpx.NetworkError`.
        retry_on_status_codes (`int` or `tuple[int]`, *optional*, defaults to `(429, 500, 502, 503, 504)`):
            Define on which status codes the request must be retried. By default, retries
            on rate limit (429) and server errors (5xx).
        **kwargs (`dict`, *optional*):
            kwargs to pass to `httpx.request`.

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

    # Same usage as "httpx.stream".
    >>> with http_stream_backoff("GET", "https://www.google.com") as response:
    ...     for chunk in response.iter_bytes():
    ...         print(chunk)

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

    <Tip warning={true}>

    When using `httpx` 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).

    </Tip>
    Tr   Nr*   )r   r   r*   r*   r+   http_stream_backoff>  s   F	r   )retry_on_errorsr   c                K   s   |ri nddd}	 t d| |d|ddi|}t| d|j  kr)dkrEn 	 |S t|jd	 }|jd
krEt|j|jd }q		 |S )aF  Perform an HTTP request with backoff and follow relative redirects only.

    Used to fetch HEAD /resolve on repo or bucket files.

    This is useful to follow a redirection to a renamed repository without following redirection to a CDN.

    A backoff mechanism retries the HTTP call on errors (429, 5xx, timeout, network errors).

    Args:
        method (`str`):
            HTTP method, such as 'GET' or 'HEAD'.
        url (`str`):
            The URL of the resource to fetch.
        retry_on_errors (`bool`, *optional*, defaults to `False`):
            Whether to retry on errors. If False, no retry is performed (fast fallback to local cache).
            If True, uses default retry behavior (429, 5xx, timeout, network errors).
        **httpx_kwargs (`dict`, *optional*):
            Params to pass to `httpx.request`.
    r*   )r   r   Tr   rf   Fi,  i  ZLocation )path)	r   r   ra   r   r,   netloc_replacer   geturl)rZ   rD   r   Zhttpx_kwargsZno_retry_kwargsr_   Zparsed_targetr*   r*   r+   -_httpx_follow_relative_redirects_with_backoff  s.   
r   endpointc                 C   sD   |r| dntj}|tjtjfvr | tj|} | tj|} | S )zReplace 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.
    rG   )rstripr   ZENDPOINTZ_HF_DEFAULT_ENDPOINTZ_HF_DEFAULT_STAGING_ENDPOINTreplace)rD   r   r*   r*   r+   fix_hf_endpoint_in_url  s
   r   endpoint_namec                 C   s2  zt |  W n ty   tjddd Y nw z|   W dS  tjy } z| jd dkr7W Y d}~dS | j	d}| j	d}| j
durT| j
jdurTt| j
jnd}|r\t|nd	\}}|d
kr| j dd d| j d }tt|| }	||	_||	_|	||dkr| j dd d| j d }tt|| }
||
_||
_|
||dkr| j dd d| j d }tt|| }||_||_|||dkr| j dd d| j d d d }tt|| ||dkr|durt|dur| j dd d| j d d d }tt|| }t||_|||dks4| jdkrT|dkrT|durTt|durT| j dd d| j d d }tt|| }||_||_||| jdkrn|dured| d nd!}tt|| || jd"krd| j d#| dd$| j d d% }tt|| || jd&krt| j}|durd'|j d(}|d)|j  d*7 }|j!dur|j"dur|d+|j# d,|j! d-|j" d.7 }n|d7 }|d/| j d7 }nd0| j d}tt|| || jd1kr| j
j	d2}| d3| d4| j	d5 d}tt|| |ttt|| |d}~ww )6a  
    Internal version of `response.raise_for_status()` that will refine a potential HTTPError.
    Raised exception will be an instance of [`~errors.HfHubHTTPError`].

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

    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 found.
    >     - [`~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Failed to parse warning headersT)exc_infod   rF   NzX-Error-CodeX-Error-MessagerE   Z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RepoNotFoundzBucket Not Found for url: zG
Please make sure you specified the correct bucket id (namespace/name).z;
If the bucket is private, make sure you are authenticated.i  z+Invalid credentials in Authorization headerz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/authenticationr`   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.r   z0

429 Too Many Requests: you have reached your 'z' rate limit.z
Retry after z seconds (rG   z requests remaining in current z
s window).z
Url: z!

429 Too Many Requests for url: i  Rangez. Requested range: z. Content-Range: zContent-Range)$_warn_on_warning_headersrz   rX   rY   raise_for_statusrh   ZHTTPStatusErrorra   r,   rI   rR   rD   r'   rO   _formatr   rK   rN   r   r   r   BUCKET_API_REGEXr5   r   rQ   Z	bucket_idREPO_API_REGEXr   r   r   r;   r   r    r!   r"   r   )r_   r   r}   Z
error_codeerror_messagerequest_urlrK   rN   messageZrevision_errZ	entry_errZ	gated_errZ
bucket_errZrepo_errr   Zrange_headerr*   r*   r+   r     s   !$








	

r   c                 C   sj   | j d}|D ]*}d|v r|ddnd|f\}}| }|tvr2| }|r2t| t| qdS )a  
    Emit warnings if warning headers are present in the HTTP response.

    Expected header format: 'X-HF-Warning: topic; message'

    Only the first warning for each topic will be shown. Topic is optional and can be empty. Note that several warning
    headers can be present in a single response.

    Args:
        response (`httpx.Response`):
            The HTTP response to check for warning headers.
    zX-HF-Warning;r   r   N)r,   Zget_listsplitstrip_WARNED_TOPICSaddrX   r{   )r_   Zserver_warningsZserver_warningZtopicr   r*   r*   r+   r     s    

r   _HfHubHTTPErrorT)bound
error_typecustom_messagec                 C   s:  g }|j d}|d ur|| z[z| }W n  tjy8   z
|  | }W n ty5   i }Y nw Y nw |d}|d urRt|t	rM|
| n|| |d}|d urk|D ]}d|v rj||d  q]W n  tjy   |j dd}|jrd| vr||j Y nw dd	 |D }t	t|}d
|}	|}
|	r|	 | vrd|v r|
d
|	 7 }
n|
d|	 7 }
d}d}tdftdftdffD ]\}}|j |}|rt|}d| d| d} nq|r| |
 vrd
|
v 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 r*   )r'   r   ).0liner*   r*   r+   
<listcomp>  s   $ z_format.<locals>.<listcomp>r   r   z
Request IDzAmzn Trace IDz	Amz CF IDr   : ))r_   server_message)r,   rI   appendjsonrh   ZResponseNotReadreadRuntimeErrorr   listextendJSONDecodeErrortextr3   dictfromkeysjoinrU   rT   X_AMZ_CF_IDr'   indexr   )r   r   r_   Zserver_errorsZfrom_headersr   r   r   content_typer   Zfinal_error_messager\   Zrequest_id_messageheaderlabelvalueZnewline_indexr*   r*   r+   r     sx   







r   c                 C   s  dd| j fg}t| j D ]\}}| dkrd}|d| d| fg7 }qd}z| jdurF| jjdd	d
}t|dkrF|dd  d}W n tj	yS   d}Y nw |durc|d|
ddfg7 }|d| jfg7 }g }|D ]\}}|r~|tt| |r|tt| qod|S )zConvert a `httpx.Request` 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-XrS   z<TOKEN>z-Hr   Nzutf-8ignore)r   i  z ... [truncated]z<streaming body>z-dr   r   r   )rZ   sortedr,   itemsr3   contentdecodelenrh   ZRequestNotReadr   rD   r   r   r'   r   )rR   partskvbodyZ
flat_partsr*   r*   r+   r[     s8   	

r[   z%^\s*bytes\s*=\s*(\d*)\s*-\s*(\d*)\s*$original_rangeresume_sizec                 C   s   | sd| dS d| v rt d| dt| }|s#td| d| \}}|sN|s5td| dt|| }d| }|d	krLtd
|d|S t|}|| }|rrt|}d| d| }||krpt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 - )rb   RANGE_REGEXr:   r   groupsr)   )r   r   r:   startendZ
new_suffixZ	new_range	new_startr*   r*   r+   _adjust_range_header$  s2   

r   )r-   N)N)rr&   atexitr   r   osre	threadingr   rV   
contextlibr   dataclassesr   shlexr   typingr   r   r   r   r	   r
   r   urllib.parser   rh   Zhuggingface_hub.errorsr   r   r   r   r   r   r   r   r   r   r   r   r   Z_lfsr   Z_typingr   Z
get_loggerr#   rX   r   compiler4   r7   r'   r;   rU   rT   r   VERBOSEr   r   rH   rP   rJ   tuplerO   rQ   Requestr]   r^   r   rd   ri   rj   rk   rl   ZCLIENT_FACTORY_TZASYNC_CLIENT_FACTORY_TLockrq   rm   r(   rn   ro   rs   rv   rw   rx   rr   registerhasattrr~   ZTimeoutExceptionZNetworkErrorr   r   rz   r   r)   r   r   r   r   r   r   r   r   setr   r   r   r   r[   
IGNORECASEr   r   r*   r*   r*   r+   <module>   s4  $(



=

"!

 	
e

P
S
3 , ]*"