U
    di=                     @   sf  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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!m"Z"m#Z#m$Z$ d
dl%m&Z&m'Z' erddl(m)Z)m*Z* ddl+m,Z, e-Z.ee-e	f Z/ee0ee/e.de1e2f Z3ddhZ4e5e6Z7eG dd dZ8G dd de0Z9dd Z:dd Z;dd Z<ee3e9dddZ=eed ed dddZ=ee3 ee9 dddZ=e3e-dd d!Z>e3e-e-d"d#d$Z?e-dd%d&d'Z@e0edd(d)ZAe0edd*d+ZBe0ddd,d-ZCee0ef ed.d/d0ZDee0 eEeee- ee' f d1d2d3ZFee0 eEeee- ee' f d1d4d5ZGe0eEeee-e'f  d6d7d8ZHee0 ee& d9d:d;ZIee0 ee& d9d<d=ZJe0ee& d>d?d@ZKdAdBee0 dCdDdEZLi ZMeee- ee- f eNdF< ee- ee- ddGdHdIZOee- ee- dJdKdLZPeedMdNdOZQee- ee- edPdQdRZRdS )SzEContains utilities used by both the sync and async inference clients.    N)	dataclass)Path)TYPE_CHECKINGAnyAsyncIterableBinaryIODictIterableListLiteralNoReturnOptionalUnionoverload)	HTTPError)GenerationErrorIncompleteGenerationErrorOverloadedErrorTextGenerationErrorUnknownErrorValidationError   )get_sessionis_aiohttp_availableis_numpy_availableis_pillow_available   )ChatCompletionStreamOutputTextGenerationStreamOutput)ClientResponseClientSessionImager"   ztext-to-imagezimage-to-imagec                   @   s\   e Zd ZU eed< eed< ee ed< eeeeef  ed< ee	 ed< eee
f ed< dS )RequestParametersurlZtaskmodeljsondataheadersN)__name__
__module____qualname__str__annotations__r   r   r   r
   bytesr    r/   r/   E/tmp/pip-unpacked-wheel-ohruig0i/huggingface_hub/inference/_common.pyr#   E   s   
r#   c                       s<   e Zd ZU dZee ed< deee d fddZ  Z	S )	MimeBytesa&  
    A bytes object with a mime type.
    To be returned by `_prepare_payload_open_as_mime_bytes` in subclasses.

    Example:
    ```python
        >>> b = MimeBytes(b"hello", "text/plain")
        >>> isinstance(b, bytes)
        True
        >>> b.mime_type
        'text/plain'
    ```
    	mime_typeN)r'   r2   c                    s2   t  | |}||_t|tr.|d kr.|j|_|S N)super__new__r2   
isinstancer1   )clsr'   r2   obj	__class__r/   r0   r5   `   s
    zMimeBytes.__new__)N)
r)   r*   r+   __doc__r   r,   r-   r.   r5   __classcell__r/   r/   r9   r0   r1   O   s   
r1   c                  C   s   t  stddd l} | S )NzMPlease install aiohttp to use `AsyncInferenceClient` (`pip install aiohttp`).r   )r   ImportErroraiohttp)r>   r/   r/   r0   _import_aiohttpk   s    r?   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   r=   numpy)r@   r/   r/   r0   _import_numpyt   s    rA   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   r=   PILr"   r!   r/   r/   r0   _import_pil_image}   s    rC   )contentreturnc                 C   s   d S r3   r/   rD   r/   r/   r0   _open_as_mime_bytes   s    rG   c                 C   s   d S r3   r/   rF   r/   r/   r0   rG      s    c                 C   s  | dkrdS t | trt| S t | ttfr8tt| S t| drtd |  }t| drnt	
| jd nd}t |trtdt||dS t | tr| ds| d	rtd
|   t | }|jd}|dkrt	
| d }t|j|dS t| } |  std|  dt | trTtd|   t|  t	
| d dS t rddlm} t | |jrtd t }| jpd}| j||d t| d|  dS tdt |  ddS )zOpen `content` as a binary file, either from a URL, a local path, raw bytes, or a PIL Image.

    Do nothing if `content` is None.
    NreadzReading content from BinaryIOnamer   z3Expected binary stream (bytes), but got text stream)r2   https://http://zDownloading content from zContent-Typez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 r!   zConverting PIL Image to bytesZPNG)formatzimage/zUnsupported content type: zl. Expected one of: bytes, bytearray, BinaryIO, memoryview, Path, str (URL or file path), or PIL.Image.Image.)!r6   r.   r1   	bytearray
memoryviewhasattrloggerdebugrH   	mimetypes
guess_typerI   r,   	TypeError
startswithr   getr(   rD   r   existsFileNotFoundError
read_bytesr   rB   r"   ioBytesIOrL   savegetvaluelowertype)rD   r'   r2   responser"   bufferrL   r/   r/   r0   rG      sP    






c                 C   s   t | }t| S )z\Encode a raw file (image, audio) into base64. Can be bytes, an opened file, a path or a URL.)rG   base64	b64encodedecode)rD   	raw_bytesr/   r/   r0   _b64_encode   s    rf   )rD   default_mime_typerE   c                 C   sH   t | tr| dr| S t| }|jp(|}t| }d| d| S )N)rK   rJ   data:rh   z;base64,)r6   r,   rU   rG   r2   rb   rc   rd   )rD   rg   re   r2   Zencoded_datar/   r/   r0   _as_url   s    
ri   )encoded_imagerE   c                 C   s   t  }|tt| S )z/Parse a base64-encoded string into a PIL Image.)rC   openrZ   r[   rb   	b64decode)rj   r"   r/   r/   r0   _b64_to_image   s    rm   c                 C   s   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.
    r&   loadsrd   rF   r/   r/   r0   _bytes_to_list   s    rp   c                 C   s   t |  S )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.
    rn   rF   r/   r/   r0   _bytes_to_dict   s    rq   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.
    )rC   rk   rZ   r[   )rD   r"   r/   r/   r0   _bytes_to_image	  s    rr   )r`   rE   c                 C   s   t | trt| S | S r3   )r6   r.   r&   ro   )r`   r/   r/   r0   _as_dict  s    rs   )bytes_output_as_linesdetailsrE   c              	   c   sF   | D ]<}zt ||}W n tk
r0   Y  qBY nX |dk	r|V  qdS )z*Used in `InferenceClient.text_generation`.N%_format_text_generation_stream_outputStopIterationrt   ru   byte_payloadoutputr/   r/   r0    _stream_text_generation_response  s    r|   c              	   C  sP   | 2 zD3 dH W }zt ||}W n tk
r8   Y  qLY nX |dk	r|V  q6 dS )z/Used in `AsyncInferenceClient.text_generation`.Nrv   ry   r/   r/   r0   &_async_stream_text_generation_response'  s    r}   )rz   ru   rE   c                 C   s~   |  dsd S |  dkr"td| d}t|dd}|dd k	rdt	|d |dt
|}|sz|jjS |S 	Ns   data:s   data: [DONE]z[DONE] signal received.zutf-8rh   z/nerror
error_type)rU   striprx   rd   r&   ro   lstriprstriprV   _parse_text_generation_errorr   parse_obj_as_instancetokentext)rz   ru   payloadjson_payloadr{   r/   r/   r0   rw   5  s    


rw   )bytes_linesrE   c              	   c   sD   | D ]:}zt |}W n tk
r.   Y  q@Y nX |dk	r|V  qdS )zFUsed in `InferenceClient.chat_completion` if model is served with TGI.N%_format_chat_completion_stream_outputrx   r   itemr{   r/   r/   r0    _stream_chat_completion_responseK  s    r   c              	   C  sN   | 2 zB3 dH W }zt |}W n tk
r6   Y  qJY nX |dk	r|V  q6 dS )z/Used in `AsyncInferenceClient.chat_completion`.Nr   r   r/   r/   r0   &_async_stream_chat_completion_responseX  s    r   )rz   rE   c                 C   sn   |  dsd S |  dkr"td| d}t|dd}|dd k	rdt	|d |dt
|S r~   )rU   r   rx   rd   r&   ro   r   r   rV   r   r   r   )rz   r   r   r/   r/   r0   r   e  s    

r   r    r   )clientr`   rE   c                 C  s:   z$|j2 z3 d H W }| V  q6 W 5 |   I d H  X d S r3   )closerD   r   )r   r`   rz   r/   r/   r0   _async_yield_fromz  s    r   #_UNSUPPORTED_TEXT_GENERATION_KWARGS)r%   unsupported_kwargsrE   c                 C   s   t | g | d S r3   )r   
setdefaultextend)r%   r   r/   r/   r0   '_set_unsupported_text_generation_kwargs  s    r   )r%   rE   c                 C   s   t | g S r3   )r   rV   )r%   r/   r/   r0   '_get_unsupported_text_generation_kwargs  s    r   )
http_errorrE   c                 C   sh   z.t | ddp| j }|d}|d}W n tk
rF   | Y nX |dk	r`t||}|| | dS )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   )getattrr`   r&   rV   	Exceptionr   )r   r   r   r   	exceptionr/   r/   r0   raise_text_generation_error  s    



r   )r   r   rE   c                 C   sH   |dkrt | S |dkr t| S |dkr0t| S |dkr@t| S t| S )NZ
generationZincomplete_generationZ
overloadedZ
validation)r   r   r   r   r   )r   r   r/   r/   r0   r     s    r   )Sr;   rb   rZ   r&   loggingrR   Zdataclassesr   pathlibr   typingr   r   r   r   r   r	   r
   r   r   r   r   r   requestsr   Zhuggingface_hub.errorsr   r   r   r   r   r   utilsr   r   r   r   Z_generated.typesr   r   r>   r   r    Z	PIL.Imager"   r,   ZUrlTZPathTr.   rM   rN   ZContentTZTASKS_EXPECTING_IMAGES	getLoggerr)   rP   r#   r1   r?   rA   rC   rG   rf   ri   rm   rp   rq   rr   rs   boolr|   r}   rw   r   r   r   r   r   r-   r   r   r   r   r/   r/   r/   r0   <module>   s   8 	
			B	   