o
    yqi${                     @   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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 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m"Z" ddl#m$Z$ ddl%m&Z& e"'e(Z)dZ*dZ+ej,dej-dZ.dej/ddfddZ0dej/ddfddZ1dej2ddfddZ3dej4fddZ5dej6fddZ7eg ej4f Z8eg ej6f Z9e: Z;e5a<e8e=d < e7a>e9e=d!< da?eej4 e=d"< d#e8ddfd$d%Z@d&e9ddfd'd(ZAdej4fd)d*ZBdej6fd+d,ZCdVd-d.ZDeEeD eFed/rejGeDd0 d1dd2ejHejIfejJd3d4d5e&d6eKd7eLd8eMd9eMd:eeNeO ePeNeO d;f f d<eeLePeLd;f f d=eQdeej2ddf fd>d?ZRd1dd2ejHejIfejJd@d5e&d6eKd7eLd8eMd9eMd:eeNeO ePeNeO d;f f d<eeLePeLd;f f dej2fdAdBZSe
d1dd2ejHejIfejJd@d5e&d6eKd7eLd8eMd9eMd:eeNeO ePeNeO d;f f d<eeLePeLd;f f deej2ddf fdCdDZTd6eKdEeeK deKfdFdGZUdWdej2dHeeK ddfdIdJZVdKeNe dLeKdej2defdMdNZWdej/deKfdOdPZXe,dQejYZZdReeK dSeLdeeK fdTdUZ[dS )Xz>Contains utilities to handle HTTP requests in huggingface_hub.    N)contextmanager)
HTTPStatus)quote)AnyCallable	GeneratorOptionalUnion)OfflineModeIsEnabled   )	constants)BadRequestErrorDisabledRepoErrorGatedRepoErrorHfHubHTTPErrorRemoteEntryNotFoundErrorRepositoryNotFoundErrorRevisionNotFoundError   )logging)SliceFileObj)HTTP_METHOD_TzX-Amzn-Trace-Idzx-request-ida  
        # staging or production endpoint
        ^https://[^/]+
        (
            # on /api/repo_type/repo_id
            /api/(models|datasets|spaces)/(.+)
            |
            # or /repo_id/resolve/revision/...
            /(.+)/resolve/(.+)
        )
    )flagsrequestreturnc              	   C   s   t j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rBt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HF_HUB_OFFLINEr
   urlX_AMZN_TRACE_IDheadersgetX_REQUEST_IDstruuiduuid4loggerdebugmethodZHF_DEBUG_curlify)r   
request_id r)   b/home/app/PaddleOCR-VL/.venv_paddleocr/lib/python3.10/site-packages/huggingface_hub/utils/_http.pyhf_request_event_hookI   s"   	
r+   c                    s
   t | S )z3
    Async version of `hf_request_event_hook`.
    )r+   )r   r)   r)   r*   async_hf_request_event_hookj   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   int
ValueErrorZaread)r-   lengthr)   r)   r*   async_hf_response_event_hookq   s   

r3   c                   C   s"   t jdtgidt jtjdddS )zQ
    Factory function to create a `httpx.Client` with the default transport.
    r   T      N@writeZevent_hooksZfollow_redirectstimeout)httpxClientr+   Timeoutr   DEFAULT_REQUEST_TIMEOUTr)   r)   r)   r*   default_client_factory   s
   r=   c                   C   s&   t jtgtgddt jtjdddS )zV
    Factory function to create a `httpx.AsyncClient` with the default transport.
    )r   r-   Tr4   r5   r7   )r9   AsyncClientr,   r3   r;   r   r<   r)   r)   r)   r*   default_async_client_factory   s
   r?   _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_sessionr@   )rC   r)   r)   r*   set_client_factory   s   "rF   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rA   )rG   r)   r)   r*   set_async_client_factory   s   rI   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)rB   rD   r@   r)   r)   r)   r*   get_session   s   	
rJ   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>
    rH   r)   r)   r)   r*   get_async_session   s   rK   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: )rB   close	Exceptionr$   warning)clienter)   r)   r*   rE      s   	rE   register_at_fork)after_in_child      F)max_retriesbase_wait_timemax_wait_timeretry_on_exceptionsretry_on_status_codesstreamr&   r   rU   rV   rW   rX   .rY   rZ   c                +   s   t |tr	|f}t trfd|}	d}
d|v r+t |d tjtfr+|d  }
t }	 d7 za|
dur?|d |
 dt	j
dtf fdd	}|r~|jdd
|}||sn|V  	 W d   W dS W d   n1 sxw   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 td|	 d d  d t|	 t||	d }	q/)zfInternal implementation of HTTP backoff logic shared between `http_backoff` and `http_stream_backoff`.r   NdataTr   r-   r   c                    sD   | j vrdS td| j  d d   kr t|  dS dS )zNHandle response and return True if should retry, False if should return/yield.FzHTTP Error z thrown while requesting  T)r/   r$   rN   hf_raise_for_status)r-   rU   r&   Znb_triesrY   r   r)   r*   _should_retry&  s   
z)_http_backoff_base.<locals>._should_retry)r&   r   'z' thrown while requesting r\   zRetrying in z	s [Retry /z].r   r)   )
isinstancetyper0   ioIOBaser   tellrJ   seekr9   ResponseboolrZ   r   r$   rN   ZConnectErrorrE   timesleepmin)r&   r   rU   rV   rW   rX   rY   rZ   kwargsZ
sleep_timeZio_obj_initial_posrO   r_   r-   errr)   r^   r*   _http_backoff_base   sX   

 

ro   )rU   rV   rW   rX   rY   c                K   s$   t td| ||||||d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 `503`):
            Define on which status codes the request must be retried. By default, only
            HTTP 503 Service Unavailable is retried.
        **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r&   r   rU   rV   rW   rX   rY   rZ   Nr)   )nextro   r&   r   rU   rV   rW   rX   rY   rm   r)   r)   r*   http_backoffQ  s   D	rs   c                k   s,    t d| ||||||dd|E dH  dS )ah  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.Timeout` and `httpx.NetworkError`.
        retry_on_status_codes (`int` or `tuple[int]`, *optional*, defaults to `503`):
            Define on which status codes the request must be retried. By default, only
            HTTP 503 Service Unavailable is retried.
        **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>
    Trp   Nr)   )ro   rr   r)   r)   r*   http_stream_backoff  s   I	rt   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.
    ra   )rstripr   ZENDPOINTZ_HF_DEFAULT_ENDPOINTZ_HF_DEFAULT_STAGING_ENDPOINTreplace)r   ru   r)   r)   r*   fix_hf_endpoint_in_url  s
   rx   endpoint_namec              
   C   sx  z|    W dS  tjy; } z%| jd dkr W Y d}~dS | jd}| jd}|dkrF| j dd d	| j d
 }tt|| ||dkr`| j dd d| j d
 }tt	|| ||dkrz| j dd d| j d
 }tt
|| ||dkr| j dd d| j d
 d d }tt|| ||dks| jdkr|dkr| jdur| jjdurtt| jjdur| j dd d| j d
 d }tt|| || jdkr|durd| dnd}tt|| || jdkrd| j d| d
d| j d
 d }tt|| || jdkr.| jjd }| d!| d"| jd# d
}tt|| |ttt|| |d}~ww )$a  
    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.
    d      Nz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 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.i  Rangez. Requested range: z. Content-Range: zContent-Range)raise_for_statusr9   ZHTTPStatusErrorr/   r   r   r   _formatr   r   r   r   r   REPO_API_REGEXsearchr!   r   r   r   )r-   ry   rP   Z
error_codeerror_messagemessageZrange_headerr)   r)   r*   r]     s~   !



	
r]   
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 }
t|j td}|rd| d}nt|j td}|rd| d}|r	| |
 vr	d
|
v r|
d
}|
d | | |
|d   }
n|
|7 }
| |
 ||	pd dS )Nr|   errorerrorsr   zContent-Type htmlc                 S   s$   g | ]}t | rt | qS r)   )r!   strip).0liner)   r)   r*   
<listcomp>  s   $ z_format.<locals>.<listcomp>r   r}   z (Request ID: )z (Amzn Trace ID: )r-   server_message)r   r   appendjsonr9   ZResponseNotReadreadRuntimeErrorrb   listextendJSONDecodeErrortextlowerdictfromkeysjoinr!   r    r   indexr   )r   r   r-   Zserver_errorsZfrom_headersr[   r   r   content_typer   Zfinal_error_messager(   Zrequest_id_messageZnewline_indexr)   r)   r*   r   x  sl   







r   c                 C   s  dd| j fg}t| j D ]\}}| dkrd}|d| d| fg7 }qd}| jdurF| jjdd	d
}t|dkrE|dd  d}n| jdurMd}|dur\|d|	ddfg7 }|d| j
fg7 }g }|D ]\}}|rw|tt| |r|tt| qhd|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-Xr   z<TOKEN>z-Hz: Nzutf-8ignore)r   i  z ... [truncated]z<streaming body>z-dr   r   r\   )r&   sortedr   itemsr   contentdecodelenrZ   rw   r   r   r   r!   r   )r   partskvbodyZ
flat_partsr)   r)   r*   r'     s4   	


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 - )r1   RANGE_REGEXmatchr   groupsr0   )r   r   r   startendZ
new_suffixZ	new_range	new_startr)   r)   r*   _adjust_range_header  s2   

r   )r   N)N)\__doc__atexitrd   r   osre	threadingrj   r"   
contextlibr   httpr   shlexr   typingr   r   r   r   r	   r9   Zhuggingface_hub.errorsr
   r   r   r   r   r   r   r   r   r   r   r   Z_lfsr   Z_typingr   Z
get_logger__name__r$   r   r    compileVERBOSEr   Requestr+   r,   rh   r3   r:   r=   r>   r?   ZCLIENT_FACTORY_TZASYNC_CLIENT_FACTORY_TLockrD   r@   __annotations__rA   rB   rF   rI   rJ   rK   rE   registerhasattrrQ   ZTimeoutExceptionZNetworkErrorSERVICE_UNAVAILABLEr!   r0   floatrc   rM   tupleri   ro   rs   rt   rx   r]   r   r'   
IGNORECASEr   r   r)   r)   r)   r*   <module>   s   $	
!


Y
SU qV)"