o
    Zh@                  	   @   sj  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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mZmZmZmZmZmZmZ ddlmZ ddlmZm Z m!Z!m"Z"m#Z#m$Z$ d	d
l%m&Z& d	dl'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1m2Z2 erddl3m4Z4m5Z5 ddl6m7Z7 e8Z9ee8ef Z:ee;ef Z<ee<e:e9f Z=ddhZ>e?e@ZAe	G dd dZBdd ZCdd ZDdd ZEdaFeee8ee8 f  eGd< dee8ee8 f fddZHdee dee fdd ZIed!e=dee< fd"d#ZJed!ed deed  fd$d#ZJed!ee= deee< ddf fd%d#ZJd!e=de8fd&d'ZKd(e8dd)fd*d+ZLd!e;defd,d-ZMd!e;defd.d/ZNd!e;dd)fd0d1ZOd2ee; d3ePdeee8 ee2 f fd4d5ZQd2ee; d3ePdeee8 ee2 f fd6d7ZRd8e;d3ePdeee8e2f  fd9d:ZSd;ee2 dee/ fd<d=ZTd;ee2 dee/ fd>d?ZUd@e2dAeVde/fdBdCZWdDee; dee/ fdEdFZXdDee; dee/ fdGdHZYd8e;dee/ fdIdJZZdKdLdMdNdee; fdOdPZ[e\ Z]eee8  eGdQ< dRee8 ddfdSdTZ^dRee8 dePfdUdVZ_e\ Z`ee8 eGdW< dRe8ddfdXdYZadRe8dePfdZd[Zbd\edefd]d^Zcd_ee8 d`ee8 de"fdadbZddS )czEContains utilities used by both the sync and async inference clients.    N)contextmanager)	dataclass)Path)TYPE_CHECKINGAnyAsyncIterableBinaryIOContextManagerDict	GeneratorIterableListLiteralNoReturnOptionalSetUnionoverload)	HTTPError)GenerationErrorIncompleteGenerationErrorOverloadedErrorTextGenerationErrorUnknownErrorValidationError   )ENDPOINT)build_hf_headersget_sessionhf_raise_for_statusis_aiohttp_availableis_numpy_availableis_pillow_available   )ChatCompletionStreamOutput ChatCompletionStreamOutputChoiceChatCompletionStreamOutputDeltaTextGenerationStreamOutput)ClientResponseClientSessionImageztext-to-imagezimage-to-imagec                   @   s2   e Zd ZU dZeed< eed< eed< eed< dS )ModelStatusa  
    This Dataclass represents the the model status in the Hugging Face Inference API.

    Args:
        loaded (`bool`):
            If the model is currently loaded into Hugging Face's InferenceAPI. Models
            are loaded on-demand, leading to the user's first request taking longer.
            If a model is loaded, you can be assured that it is in a healthy state.
        state (`str`):
            The current state of the model. This can be 'Loaded', 'Loadable', 'TooBig'.
            If a model's state is 'Loadable', it's not too big and has a supported
            backend. Loadable models are automatically loaded when the user first
            requests inference on the endpoint. This means it is transparent for the
            user to load a model, except that the first call takes longer to complete.
        compute_type (`Dict`):
            Information about the compute resource the model is using or will use, such as 'gpu' type and number of
            replicas.
        framework (`str`):
            The name of the framework that the model was built with, such as 'transformers'
            or 'text-generation-inference'.
    ZloadedstateZcompute_typeZ	frameworkN)__name__
__module____qualname____doc__bool__annotations__strr
    r5   r5   X/var/www/html/lang_env/lib/python3.10/site-packages/huggingface_hub/inference/_common.pyr,   X   s   
 r,   c                  C   s   t  stddd l} | S )NzMPlease install aiohttp to use `AsyncInferenceClient` (`pip install aiohttp`).r   )r    ImportErroraiohttp)r8   r5   r5   r6   _import_aiohttpy      r9   c                  C   s   t  stdddl} | S )z.Make sure `numpy` is installed on the machine.zGPlease install numpy to use deal with embeddings (`pip install numpy`).r   N)r!   r7   numpy)r;   r5   r5   r6   _import_numpy   r:   r<   c                  C   s   t  stdddlm}  | S )z,Make sure `PIL` is installed on the machine.zPlease install Pillow to use deal with images (`pip install Pillow`). If you don't want the image to be post-processed, use `client.post(...)` and get the raw response from the server.r   r*   )r"   r7   PILr+   r*   r5   r5   r6   _import_pil_image   s   r>   _RECOMMENDED_MODELSreturnc                  C   sB   t d u rt jt dt d} t|  dd |   D a t S )Nz
/api/tasks)headersc                 S   s   i | ]\}}|t |d  qS )ZwidgetModels)_first_or_none).0taskdetailsr5   r5   r6   
<dictcomp>   s    z-_fetch_recommended_models.<locals>.<dictcomp>)r?   r   getr   r   r   jsonitems)responser5   r5   r6   _fetch_recommended_models   s   
rK   rI   c                 C   s$   z| d pd W S  t y   Y d S w )Nr   )
IndexError)rI   r5   r5   r6   rB      s
   rB   contentc                 C      d S Nr5   rM   r5   r5   r6   _open_as_binary      rQ   c                 C   rN   rO   r5   rP   r5   r5   r6   rQ      rR   c                 c   s    t | tr2| ds| dr"td|   t | jV  dS t| } | 	 s2t
d|  dt | trZtd|   | d}|V  W d   dS 1 sSw   Y  dS | V  dS )	zOpen `content` as a binary file, either from a URL, a local path, or raw bytes.

    Do nothing if `content` is None,

    TODO: handle a PIL.Image as input
    TODO: handle base64 as input
    zhttps://zhttp://zDownloading content from NzFile not found at z. If `data` is a string, it must either be a URL or a path to a local file. To pass raw content, please encode it as bytes first.zOpening content from rb)
isinstancer4   
startswithloggerdebugr   rG   rM   r   existsFileNotFoundErroropen)rM   fr5   r5   r6   rQ      s"   



"
c                 C   sP   t | }t|tr|n| }t| W  d   S 1 s!w   Y  dS )z[Encode a raw file (image, audio) into base64. Can be byes, an opened file, a path or a URL.N)rQ   rT   bytesreadbase64	b64encodedecode)rM   dataZdata_as_bytesr5   r5   r6   _b64_encode   s   
$rb   encoded_imager+   c                 C   s   t  }|tt| S )z/Parse a base64-encoded string into a PIL Image.)r>   rZ   ioBytesIOr^   	b64decode)rc   r+   r5   r5   r6   _b64_to_image   s   rg   c                 C      t |  S )ac  Parse bytes from a Response object into a Python list.

    Expects the response body to be JSON-encoded data.

    NOTE: This is exactly the same implementation as `_bytes_to_dict` and will not complain if the returned data is a
    dictionary. The only advantage of having both is to help the user (and mypy) understand what kind of data to expect.
    rH   loadsr`   rP   r5   r5   r6   _bytes_to_list      rk   c                 C   rh   )ac  Parse bytes from a Response object into a Python dictionary.

    Expects the response body to be JSON-encoded data.

    NOTE: This is exactly the same implementation as `_bytes_to_list` and will not complain if the returned data is a
    list. The only advantage of having both is to help the user (and mypy) understand what kind of data to expect.
    ri   rP   r5   r5   r6   _bytes_to_dict   rl   rm   c                 C   s   t  }|t| S )zParse bytes from a Response object into a PIL Image.

    Expects the response body to be raw bytes. To deal with b64 encoded images, use `_b64_to_image` instead.
    )r>   rZ   rd   re   )rM   r+   r5   r5   r6   _bytes_to_image  s   rn   bytes_output_as_linesrE   c                 c   s(    | D ]}t ||}|dur|V  qdS )z*Used in `InferenceClient.text_generation`.N%_format_text_generation_stream_outputro   rE   byte_payloadoutputr5   r5   r6    _stream_text_generation_response  s   
ru   c                 C  s2   | 2 z3 dH W }t ||}|dur|V  q6 dS )z/Used in `AsyncInferenceClient.text_generation`.Nrp   rr   r5   r5   r6   &_async_stream_text_generation_response  s   
rv   rs   c                 C   sj   |  dsd S | d}t|dd}|dd ur(t|d |dt	|}|s3|j
jS |S )N   data:utf-8data:/nerror
error_type)rU   r`   rH   rj   lstriprstriprG   _parse_text_generation_errorr'   parse_obj_as_instancetokentext)rs   rE   payloadjson_payloadrt   r5   r5   r6   rq   #  s   


rq   text_generation_outputc                 c   s(    t t }| D ]}t||V  q	dS )z*Used in `InferenceClient.chat_completion`.Ninttime:_format_chat_completion_stream_output_from_text_generationr   createditemr5   r5   r6   5_stream_chat_completion_response_from_text_generation6  s
   r   c                 C  s2   t t }| 2 z3 dH W }t||V  q	6 dS z/Used in `AsyncInferenceClient.chat_completion`.Nr   r   r5   r5   r6   ;_async_stream_chat_completion_response_from_text_generation?  s
   r   r   r   c                 C   sL   | j d u rtttd| jjdd ddg|dS ttt | j jddg|dS )NZ	assistant)ZrolerM   r   )deltafinish_reasonindex)choicesr   )rE   r$   r%   r&   r   r   r   )r   r   r5   r5   r6   r   H  s,   

r   bytes_linesc                 c   s&    | D ]}t |}|dur|V  qdS )zFUsed in `InferenceClient.chat_completion` if model is served with TGI.NE_format_chat_completion_stream_output_from_text_generation_from_bytesr   r   rt   r5   r5   r6   +_stream_chat_completion_response_from_bytesh  s   r   c                 C  s0   | 2 z3 dH W }t |}|dur|V  q6 dS r   r   r   r5   r5   r6   1_async_stream_chat_completion_response_from_bytesr  s   r   c                 C   s8   |  dsd S | d}t|dd}t|S )Nrw   rx   ry   rz   )rU   r`   rH   rj   r}   r~   r$   r   )rs   r   r   r5   r5   r6   r   |  s
   


r   clientr)   rJ   r(   c                 C  s0   |j 2 z	3 d H W }|V  q6 |  I d H  d S rO   )rM   close)r   rJ   rs   r5   r5   r6   _async_yield_from  s
   r   _NON_TGI_SERVERSmodelc                 C   s   t |  d S rO   )r   addr   r5   r5   r6   _set_as_non_tgi  s   r   c                 C      | t vS rO   )r   r   r5   r5   r6   _is_tgi_server     r   _NON_CHAT_COMPLETION_SERVERc                 C   s   t d|  t|  d S )NzSet as non chat completion)printr   r   r   r5   r5   r6   "_set_as_non_chat_completion_server  s   
r   c                 C   r   rO   )r   r   r5   r5   r6   _is_chat_completion_server  r   r   
http_errorc                 C   s^   zt | ddp| j }|d}|d}W n	 ty    | w |dur-t||}|| | )z
    Try to parse text-generation-inference error message and raise HTTPError in any case.

    Args:
        error (`HTTPError`):
            The HTTPError that have been raised.
    Zresponse_error_payloadNr{   r|   )getattrrJ   rH   rG   	Exceptionr   )r   r   r{   r|   	exceptionr5   r5   r6   raise_text_generation_error  s   


r   r{   r|   c                 C   sH   |dkrt | S |dkrt| S |dkrt| S |dkr t| S t| S )NZ
generationZincomplete_generationZ
overloadedZ
validation)r   r   r   r   r   )r{   r|   r5   r5   r6   r     s   r   )er1   r^   rd   rH   loggingr   
contextlibr   dataclassesr   pathlibr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   requestsr   Zhuggingface_hub.errorsr   r   r   r   r   r   	constantsr   utilsr   r   r   r    r!   r"   Z_generated.typesr$   r%   r&   r'   r8   r(   r)   r=   r+   r4   ZUrlTZPathTr\   ZBinaryTZContentTZTASKS_EXPECTING_IMAGES	getLoggerr.   rV   r,   r9   r<   r>   r?   r3   rK   rB   rQ   rb   rg   rk   rm   rn   r2   ru   rv   rq   r   r   r   r   r   r   r   r   setr   r   r   r   r   r   r   r   r5   r5   r5   r6   <module>   s   D 	 
 		

&



	
	
 




"