§
    ìXÊjÆ0  ã                   ól  — U 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 d dlZddlmZ dd	lmZmZmZ  ej        d
¦  «        ZdZdZi Zeedf         ed<    ej        ¦   «         Zi Zeeej        f         ed<   dedefd„Z G d„ dee	¦  «        Z ed¬¦  «         G d„ d¦  «        ¦   «         Z  ed¬¦  «         G d„ d¦  «        ¦   «         Z!d3dej"        dedz  de dz  fd„Z#deeef         de!dz  fd„Z$ede deeef         de!fd „¦   «         Z%ed!edeeef         de!fd"„¦   «         Z&d!edeeef         defd#„Z'd$edej        fd%„Z(d&e!defd'„Z)eddd(œd)ed*ed+ed,edz  dedz  defd-„¦   «         Z* G d.„ d/¦  «        Z+ e+¦   «         Z,d0„ Z-deeef         deeef         fd1„Z.d2„ Z/dS )4é    N)ÚMapping)Ú	dataclass)ÚEnum)ÚAnyé   )Ú	constantsé   )Úhf_raise_for_statusÚhttp_backoffÚvalidate_hf_hub_argsz^[0-9a-fA-F]{64}$é<   iè  ÚXetConnectionInfoÚXET_CONNECTION_INFO_CACHEÚ_XET_CONNECTION_INFO_KEY_LOCKSÚxet_hashÚreturnc                 óP   — t          t                               | ¦  «        ¦  «        S )zLReturn whether `xet_hash` looks like a real Xet content hash (64 hex chars).)ÚboolÚ_REGEX_XET_HASHÚ	fullmatch)r   s    úKC:\Projects\Historical\venv\Lib\site-packages\huggingface_hub/utils/_xet.pyÚis_valid_xet_hashr      s   € å•×)Ò)¨(Ñ3Ô3Ñ4Ô4Ð4ó    c                   ó   — e Zd ZdZdZdS )ÚXetTokenTypeÚreadÚwriteN)Ú__name__Ú
__module__Ú__qualname__ÚREADÚWRITE© r   r   r   r      s   € € € € € Ø€DØ€E€E€Er   r   T)Úfrozenc                   ó$   — e Zd ZU eed<   eed<   dS )ÚXetFileDataÚ	file_hashÚrefresh_routeN)r   r   r    ÚstrÚ__annotations__r#   r   r   r&   r&   #   s'   € € € € € € à€N€N�NØÐÐÑÐÐr   r&   c                   ó.   — e Zd ZU eed<   eed<   eed<   dS )r   Úaccess_tokenÚexpiration_unix_epochÚendpointN)r   r   r    r)   r*   Úintr#   r   r   r   r   )   s1   € € € € € € àÐÐÑØÐÐÑØ€M€M�M€M€Mr   Úresponser.   c                 óú  — | €dS 	 | j         t          j                 }t          j        | j        v r| j        t          j                 d         }n| j         t          j                 }n# t          $ r Y dS w xY w|�|nt          j        }|                     t          j	        ¦  «        rF| 
                    t          j	                             d¦  «        |                     d¦  «        ¦  «        }t          ||¬¦  «        S )a_  
    Parse XET file metadata from an HTTP response.

    This function extracts XET file metadata from the HTTP headers or HTTP links
    of a given response object. If the required metadata is not found, it returns `None`.

    Args:
        response (`httpx2.Response`):
            The HTTP response object containing headers dict and links dict to extract the XET metadata from.
    Returns:
        `Optional[XetFileData]`:
            An instance of `XetFileData` containing the file hash and refresh route if the metadata
            is found. Returns `None` if the required metadata is missing.
    NÚurlú/)r'   r(   )Úheadersr   ÚHUGGINGFACE_HEADER_X_XET_HASHÚ$HUGGINGFACE_HEADER_LINK_XET_AUTH_KEYÚlinksÚ&HUGGINGFACE_HEADER_X_XET_REFRESH_ROUTEÚKeyErrorÚENDPOINTÚ
startswithÚHUGGINGFACE_CO_URL_HOMEÚreplaceÚrstripr&   )r0   r.   r'   r(   s       r   Ú!parse_xet_file_data_from_responser?   0   sý   € ð ÐØˆtðØÔ$¥YÔ%LÔMˆ	åÔ9¸X¼^ÐKÐKØ$œN­9Ô+YÔZÐ[`ÔaˆMˆMà$Ô,­YÔ-]Ô^ˆMøøÝð ð ð Øˆtˆtðøøøà#Ð/ˆxˆxµYÔ5G€HØ×Ò¥	Ô AÑBÔBð sØ%×-Ò-­iÔ.O×.VÒ.VÐWZÑ.[Ô.[Ð]e×]lÒ]lÐmpÑ]qÔ]qÑrÔrˆÝØØ#ðñ ô ð s   †AA& Á&
A4Á3A4r4   c                 óì   — 	 | t           j                 }| t           j                 }t          | t           j                 ¦  «        }n# t
          t          t          f$ r Y dS w xY wt          |||¬¦  «        S )a„  
    Parse XET connection info from the HTTP headers or return None if not found.
    Args:
        headers (`dict`):
           HTTP headers to extract the XET metadata from.
    Returns:
        `XetConnectionInfo` or `None`:
            The information needed to connect to the XET storage service.
            Returns `None` if the headers do not contain the XET connection info.
    N)r.   r,   r-   )	r   Ú!HUGGINGFACE_HEADER_X_XET_ENDPOINTÚ%HUGGINGFACE_HEADER_X_XET_ACCESS_TOKENr/   Ú#HUGGINGFACE_HEADER_X_XET_EXPIRATIONr9   Ú
ValueErrorÚ	TypeErrorr   )r4   r.   r,   r-   s       r   Ú&parse_xet_connection_info_from_headersrF   S   s…   € ðØ�9ÔFÔGˆØ�yÔNÔOˆÝ # G­IÔ,YÔ$ZÑ [Ô [ÐÐøÝ•j¥)Ð,ð ð ð Øˆtˆtðøøøõ ØØ!Ø3ðñ ô ð s   ‚AA ÁA!Á A!Ú	file_datac                 óX   — | j         €t          d¦  «        ‚t          | j         |¦  «        S )a  
    Utilizes the information in the parsed metadata to request the Hub xet connection information.
    This includes the access token, expiration, and XET service URL.
    Args:
        file_data: (`XetFileData`):
            The file data needed to refresh the xet connection information.
        headers (`dict[str, str]`):
            Headers to use for the request, including authorization headers and user agent.
    Returns:
        `XetConnectionInfo`:
            The connection information needed to make the request to the xet storage service.
    Raises:
        [`~utils.HfHubHTTPError`]
            If the Hub API returned an error.
        [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
            If the Hub API response is improperly formatted.
    Nz>The provided xet metadata does not contain a refresh endpoint.)r(   rD   Ú#_fetch_xet_connection_info_with_url)rG   r4   s     r   Úrefresh_xet_connection_inforJ   l   s/   € ð. ÔÐ&ÝÐYÑZÔZÐZÝ.¨yÔ/FÈÑPÔPÐPr   r2   c           	      óz  — t          | |¦  «        }t                               |¦  «        }|�t          |¦  «        s|S t	          |¦  «        5  t                               |¦  «        }|�t          |¦  «        s|cddd¦  «         S t          d| |¬¦  «        }t          |¦  «         t          |j        ¦  «        }|€t          d¦  «        ‚t          5  t          t                               ¦   «         ¦  «        D ]/\  }}t          |¦  «        rt                               |d¦  «         Œ0t          t          ¦  «        t          k    r9t                               t!          t#          t          ¦  «        ¦  «        ¦  «         |t          |<   ddd¦  «         n# 1 swxY w Y   |cddd¦  «         S # 1 swxY w Y   dS )a  
    Requests the xet connection info from the supplied URL. This includes the
    access token, expiration time, and endpoint to use for the xet storage service.

    Result is cached to avoid redundant requests.

    Args:
        url: (`str`):
            The access token endpoint URL.
        headers (`dict[str, str]`):
            Headers to use for the request, including authorization headers and user agent.
    Returns:
        `XetConnectionInfo`:
            The connection information needed to make the request to the xet storage service.
    Raises:
        [`~utils.HfHubHTTPError`]
            If the Hub API returned an error.
        [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
            If the Hub API response is improperly formatted.
    NÚGET©r4   z6Xet headers have not been correctly set by the server.)Ú
_cache_keyr   ÚgetÚ_is_expiredÚ	_key_lockr   r
   rF   r4   rD   Ú_XET_CONNECTION_INFO_LOCKÚlistÚitemsÚpopÚlenÚXET_CONNECTION_INFO_CACHE_SIZEÚnextÚiter)r2   r4   Ú	cache_keyÚcached_infoÚrespÚmetadataÚkÚvs           r   rI   rI   ˆ   sE  € õ4 ˜3 Ñ(Ô(€IÝ+×/Ò/°	Ñ:Ô:€KØÐÝ˜;Ñ'Ô'ð 	ØÐõ 
�9Ñ	Ô	ð ð Ý/×3Ò3°IÑ>Ô>ˆØÐ"­;°{Ñ+CÔ+CÐ"Øðð ð ð ñ ô ð ð õ ˜E 3°Ð8Ñ8Ô8ˆÝ˜DÑ!Ô!Ð!å9¸$¼,ÑGÔGˆØÐÝÐUÑVÔVÐVå&ð 	<ð 	<åÕ6×<Ò<Ñ>Ô>Ñ?Ô?ð ;ð ;‘��1Ý˜q‘>”>ð ;Ý-×1Ò1°!°TÑ:Ô:Ð:øõ Õ,Ñ-Ô-Õ1OÒOÐOÝ)×-Ò-­dµ4Õ8QÑ3RÔ3RÑ.SÔ.SÑTÔTÐTð 4<Õ% iÑ0ð	<ð 	<ð 	<ñ 	<ô 	<ð 	<ð 	<ð 	<ð 	<ð 	<ð 	<øøøð 	<ð 	<ð 	<ð 	<ð ð5ð ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ð s>   Á-F0ÂAF0ÃB7FÆF0ÆF	ÆF0ÆF	ÆF0Æ0F4Æ7F4c                 óx   — d„ |                      ¦   «         D ¦   «         }|                     dd¦  «        }| › d|› �S )z;Return a unique cache key for the given request parameters.c                 ó>   — i | ]\  }}|                      ¦   «         |“ŒS r#   ©Úlower)Ú.0r^   r_   s      r   ú
<dictcomp>z_cache_key.<locals>.<dictcomp>É   s&   € Ð>Ð>Ð>¡d a¨�Q—W’W‘Y”Y Ð>Ð>Ð>r   ÚauthorizationÚ ú|)rT   rO   )r2   r4   Úlower_headersÚauth_headers       r   rN   rN   Ç   sF   € à>Ð>¨g¯mªm©o¬oÐ>Ñ>Ô>€MØ×#Ò# O°RÑ8Ô8€KØÐ!Ð!�KÐ!Ð!Ð!r   rZ   c                 óœ   — t           5  t                               | t          j        ¦   «         ¦  «        cddd¦  «         S # 1 swxY w Y   dS )zNReturn the lock guarding token fetches for `cache_key`, creating it if needed.N)rR   r   Ú
setdefaultÚ	threadingÚLock)rZ   s    r   rQ   rQ   Î   s›   € å	"ð Vð VÝ-×8Ò8¸ÅIÄNÑDTÔDTÑUÔUðVð Vð Vð Vñ Vô Vð Vð Vð Vð Vð Vð Vøøøð Vð Vð Vð Vð Vð Vs   ˆ,AÁAÁAÚconnection_infoc                 ód   — | j         t          t          j        ¦   «         ¦  «        t          z   k    S )z2Check if the given XET connection info is expired.)r-   r/   ÚtimeÚ!XET_CONNECTION_INFO_SAFETY_PERIOD)ro   s    r   rP   rP   Ô   s$   € àÔ0µC½¼	¹¼Ñ4DÔ4DÕGhÑ4hÒhÐhr   )Úrevisionr.   Ú
token_typeÚrepo_idÚ	repo_typers   c                 ól   — |�|nt           j        }|› d|› d|› d| j        › d�}|dk    s|�|d|› �z  }|S )a×  
    Build the URL used to fetch or refresh a Xet access token for a given repo.
    Args:
        token_type (`XetTokenType`):
            Type of the token to request: `"read"` or `"write"`.
        repo_id (`str`):
            A namespace (user or an organization) and a repo name separated by a `/`.
        repo_type (`str`):
            Type of the repo (e.g. `"model"`, `"dataset"`, `"space"`, `"bucket"`).
        revision (`str`, `optional`):
            The revision of the repo to get the token for.
        endpoint (`str`, `optional`):
            The endpoint to use for the request. Defaults to the Hub endpoint.
    Returns:
        `str`:
            The fully-qualified URL of the token refresh endpoint.
    Nz/api/zs/z/xet-z-tokenÚbucketr3   )r   r:   Úvalue)rt   ru   rv   rs   r.   r2   s         r   Úxet_connection_info_refresh_urlrz   Ù   se   € ð4 $Ð/ˆxˆxµYÔ5G€HØÐ
OÐ
O˜IÐ
OÐ
O¨Ð
OÐ
O°zÔ7GÐ
OÐ
OÐ
O€CØ�HÒÐ Ð 4ð
 	ˆ~�8ˆ~ˆ~ÑˆØ€Jr   c                   ó&   — e Zd ZdZdd„Zd„ Zd„ ZdS )ÚXetSessionHoldera7  Holds an optional XetSession; supports safe re-creation after sigint_abort or fork.

    Thread-safe: a ``threading.Lock`` guards all state mutations, which matters
    for free-threaded Python (3.14t) where multiple threads can race on ``get()``
    or ``sigint_abort()`` without the GIL serialising them.
    r   Nc                 óR   — t          j        ¦   «         | _        d | _        d | _        d S ©N)rm   rn   Ú_lockÚ_sessionÚ_session_pid©Úselfs    r   Ú__init__zXetSessionHolder.__init__  s&   € Ý”^Ñ%Ô%ˆŒ
Ø!ˆŒØ(,ˆÔÐÐr   c                 óð   — | j         5  t          j        ¦   «         }| j        �| j        |k    rd| _        | j        €ddlm}  |¦   «         | _        || _        | j        cddd¦  «         S # 1 swxY w Y   dS )a  Return the current session, creating one if needed.

        Fork-safe: if the current process PID differs from the PID that created
        the session (i.e. we are in a forked child), the old session is discarded
        and a fresh session is created for this process.
        Nr   )Ú
XetSession)r   ÚosÚgetpidr€   r�   Úhf_xetr†   )rƒ   Úcurrent_pidr†   s      r   rO   zXetSessionHolder.get  sÍ   € ð ŒZð 	!ð 	!Ýœ)™+œ+ˆKàŒ}Ð(¨TÔ->À+Ò-MÐ-Mð !%�”àŒ}Ð$Ø-Ð-Ð-Ð-Ð-Ð-à * 
¡¤�”Ø$/�Ô!à”=ð	!ð 	!ð 	!ð 	!ñ 	!ô 	!ð 	!ð 	!ð 	!ð 	!ð 	!ð 	!øøøð 	!ð 	!ð 	!ð 	!ð 	!ð 	!s   ˆAA+Á+A/Á2A/c                 óÆ   — | j         5  | j        �9	 | j                             ¦   «          n# t          $ r Y nw xY wd| _        d| _        ddd¦  «         dS # 1 swxY w Y   dS )zMAbort the current session and clear it so the next get() creates a fresh one.N)r   r€   Úsigint_abortÚ	Exceptionr�   r‚   s    r   rŒ   zXetSessionHolder.sigint_abort#  sÁ   € àŒZð 	)ð 	)ØŒ}Ð(ðØ”M×.Ò.Ñ0Ô0Ð0Ð0øÝ ð ð ð Ø�Dðøøøà $�”Ø$(�Ô!ð	)ð 	)ð 	)ñ 	)ô 	)ð 	)ð 	)ð 	)ð 	)ð 	)ð 	)ð 	)øøøð 	)ð 	)ð 	)ð 	)ð 	)ð 	)s,   ˆA‘+ªA«
8µA·8¸AÁAÁA)r   N)r   r   r    Ú__doc__r„   rO   rŒ   r#   r   r   r|   r|   þ   sP   € € € € € ðð ð-ð -ð -ð -ð
!ð !ð !ð0	)ð 	)ð 	)ð 	)ð 	)r   r|   c                  ó4   — t                                ¦   «         S )a*  Return the global :class:`hf_xet.XetSession`, creating it on first call.

    The session is shared across all calls within a process, just as the HTTP
    client returned by :func:`~huggingface_hub.utils._http.get_session` is shared.
    It is created lazily and is fork-safe and thread-safe.
    )Ú_GLOBAL_XET_HOLDERrO   r#   r   r   Úget_xet_sessionr‘   2  s   € õ ×!Ò!Ñ#Ô#Ð#r   c                 ó>   — d„ |                       ¦   «         D ¦   «         S )zßReturn a copy of headers with the authorization header removed.

    Xet storage requests use a short-lived xet access token for auth, so the
    Hub authorization header must not be forwarded to xet storage endpoints.
    c                 óJ   — i | ] \  }}|                      ¦   «         d k    ¯||“Œ!S )rf   rb   )rd   Úkeyry   s      r   re   z,xet_headers_without_auth.<locals>.<dictcomp>B  s0   € Ð[Ð[Ð[™:˜3 ¸C¿IºI¹K¼KÈ?Ò<ZÐ<ZˆC�Ð<ZÐ<ZÐ<Zr   )rT   rM   s    r   Úxet_headers_without_authr•   <  s!   € ð \Ð[¨¯ª©¬Ð[Ñ[Ô[Ð[r   c                  ó8   — t                                ¦   «          dS )zÏAbort the global xet session after a KeyboardInterrupt.

    Cancels any in-flight Rust operation and clears the session so the next
    call to :func:`get_xet_session` starts fresh (notebook-friendly).
    N)r�   rŒ   r#   r   r   Úabort_xet_sessionr—   E  s   € õ ×#Ò#Ñ%Ô%Ð%Ð%Ð%r   r~   )0r‡   Úrerm   rq   Úcollections.abcr   Údataclassesr   Úenumr   Útypingr   Úhttpx2rg   r   r
   r   r   Úcompiler   rr   rW   r   Údictr)   r*   rn   rR   r   r   r   r   r&   r   ÚResponser?   rF   rJ   rI   rN   rQ   rP   rz   r|   r�   r‘   r•   r—   r#   r   r   ú<module>r¡      s}  ðØ 	€	€	€	€	Ø 	€	€	€	Ø Ð Ð Ð Ø €€€Ø #Ð #Ð #Ð #Ð #Ð #Ø !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à €€€à Ð Ð Ð Ð Ð Ø EÐ EÐ EÐ EÐ EÐ EÐ EÐ EÐ EÐ Eð �"”*Ð1Ñ2Ô2€à$&Ð !Ø!&Ð Ø<>Ð ˜4 Ð%8Ð 8Ô9Ð >Ð >Ñ >Ø*˜IœNÑ,Ô,Ð Ø<>Ð   S¨)¬.Ð%8Ô 9Ð >Ð >Ñ >ð5 ð 5¨ð 5ð 5ð 5ð 5ð
ð ð ð ð �3˜ñ ô ð ð
 €�$ÐÑÔðð ð ð ð ñ ô ñ Ôðð
 €�$ÐÑÔðð ð ð ð ñ ô ñ Ôðð ð  °´ð  È3ÐQUÉ:ð  ÐalÐosÑasð  ð  ð  ð  ðF°G¸CÀ¸HÔ4Eð ÐJ[Ð^bÑJbð ð ð ð ð2 ðQàðQð �#�s�(Œ^ðQð ð	Qð Qð Qñ ÔðQð6 ð;Ø	ð;à�#�s�(Œ^ð;ð ð;ð ;ð ;ñ Ôð;ð|"�Cð " $ s¨C x¤.ð "°Sð "ð "ð "ð "ðV˜ð V ¤ð Vð Vð Vð VðiÐ!2ð i°tð ið ið ið ið
 ð  Øð!ð !ð !àð!ð ð!ð ð	!ð
 �D‰jð!ð �D‰jð!ð 	ð!ð !ð !ñ Ôð!ðH.)ð .)ð .)ð .)ð .)ñ .)ô .)ð .)ðb &Ð%Ñ'Ô'Ð ð$ð $ð $ð\ d¨3°¨8¤nð \¸¸cÀ3¸h¼ð \ð \ð \ð \ð&ð &ð &ð &ð &r   