o
    ưi,                     @   s>  d dl Z d dlZd dlmZ d dl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T d dlmZmZ d d	lmZ d d
lmZ d dlmZ e Zd dlZd dlm Z  de dej!fddZ"de#ee   de#eej!  fddZ$ej%deegedgdej%deegedgdej%deegedgdeedfde
dedede#e& fddZ'ej%deegdgd ej%d!eegdgd ej%d"eegedgdeeededd#d$ededd%d$dfde
deded&e#ee   d'e#ee   d(e#ee   d)e#ee   de#e& fd*d+Z(dS ),    N)List)	APIRouterDependsFileHTTPExceptionRequestResponsestatus)ORJSONResponse)verbose_proxy_logger)get_str_from_messages)*)UserAPIKeyAuthuser_api_key_auth)ProxyBaseLLMRequestProcessing)route_request)ChatCompletionUserMessage)
UploadFileuploadreturnc                    s&   |   I dH }t|}| j|_|S )zz
    Read a FastAPI UploadFile into a BytesIO and set .name so OpenAI SDK
    infers filename/content-type correctly.
    N)readioBytesIOfilenamename)r   databuffer r   ^/home/app/Keep/.python/lib/python3.10/site-packages/litellm/proxy/image_endpoints/endpoints.pyuploadfile_to_bytesio   s
   
r   uploadsc                    s   | sdS dd | D I dH S )zN
    Convert a list of UploadFiles to a list of BytesIO buffers, or None.
    Nc                    s   g | ]	}t |I d H qS )N)r   ).0ur   r   r   
<listcomp>.   s    z$batch_to_bytesio.<locals>.<listcomp>r   )r    r   r   r   batch_to_bytesio&   s   r$   z/v1/images/generationsZimages)dependenciesresponse_classtagsz/images/generationsz3/openai/deployments/{model:path}/images/generationsrequestfastapi_responseuser_api_key_dictmodelc                    s  ddl m}m}m}m}m}m}	m}
 i }z|  I d H }t	
|}||| |||
|dI d H }|p>|dd p>|	p>|dd |d< |	rG|	|d< |d tjv rWtj|d  |d< |d}|d urjd|d}|g|d	< |j||d
dI d H }|d	}t|tr|rt||d< |d	d  t|d||	dI d H }|I d H }t|j|dddd |j|||dI d H }t|di pi }|dd pd}|dd pd}|dd pd}|dd pd}|dd pd}|jtj|||||
|t|dd|||d
 |W S  tyk } z_|j|||dI d H  t d!t"| t#t$%  t|t&rEt't|dt"|t|ddt|ddt|d t(j)d!t"| }t't|d|t|ddt|ddt|d"d t|d d#d$d }~ww )%Nr   )add_litellm_data_to_requestgeneral_settings
llm_routerproxy_configproxy_logging_obj
user_modelversion)r   r(   r-   r*   r2   r/   image_generation_modelr+   promptuser)Zrolecontentmessagesimage_generation)r*   r   Z	call_typeZaimage_generation)r   
route_typer.   r1   litellm_call_id success)r:   r	   )r   r*   responseZ_hidden_paramsmodel_id	cache_keyapi_baseresponse_costZallowed_model_region)
r*   r>   r?   r@   r2   rA   Zmodel_regionZcall_idrequest_datahidden_params)r*   Zoriginal_exceptionrB   zElitellm.proxy.proxy_server.image_generation(): Exception occured - {}messagetypeNoneparamstatus_code)rD   rE   rG   coderI   i  )rD   rE   rG   Zopenai_coderI   )*litellm.proxy.proxy_serverr,   r-   r.   r/   r0   r1   r2   bodyorjsonloadsgetlitellmZmodel_alias_mapZpre_call_hook
isinstancelistr   popr   asynciocreate_taskZupdate_request_statusZpost_call_success_hookgetattrheadersupdater   Zget_custom_headers	ExceptionZpost_call_failure_hookr   errorformatstrdebug	traceback
format_excr   ZProxyExceptionr	   ZHTTP_400_BAD_REQUEST)r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r   rK   Zprompt_valueZuser_messager7   Zllm_callr=   rC   r>   r?   r@   rA   r:   e	error_msgr   r   r   r8   1   s   $

















r8   z/v1/images/edits)r%   r'   z/images/editsz-/openai/deployments/{model:path}/images/editszimage[])aliaszmask[]imageimage_arraymask
mask_arrayc              
      s  |dur|durt ddd|dur|durt ddd|du r'|dur'|}|du r1|dur1|}ddlm}m}	m}
m}m}m}m}m	}m
}m}m}m} || dI dH }t|I dH }t|I dH }|ri||d	< |ro||d
< d|vrwd|d< |p|	ddp|p|dd|d< t|d}z:|jd i d| d|d|ddd|d|
d|	d|d|ddd|d|d|d|d|d|I dH W S  ty } z|j||||dI dH d}~ww )!a  
    Follows the OpenAI Images API spec: https://platform.openai.com/docs/api-reference/images/create

    ```bash
    curl -s -D >(grep -i x-request-id >&2)     -o >(jq -r '.data[0].b64_json' | base64 --decode > gift-basket.png)     -X POST "http://localhost:4000/v1/images/edits"     -H "Authorization: Bearer sk-1234"         -F "model=gpt-image-1"         -F "image[]=@soap.png"         -F 'prompt=Create a studio ghibli image of this'
    ```
    Ni  z)Cannot specify both 'image' and 'image[]')rH   detailz'Cannot specify both 'mask' and 'mask[]'r   )_read_request_bodyr-   r.   r/   r0   select_data_generatoruser_api_baseuser_max_tokensr1   user_request_timeoutuser_temperaturer2   )r(   rb   rd   r4   r3   r+   )r   r(   r)   r*   r9   Zaimage_editr0   r.   r-   r/   rh   r1   rl   rk   rj   ri   r2   )r_   r*   r0   r2   r   )r   rJ   rg   r-   r.   r/   r0   rh   ri   rj   r1   rk   rl   r2   r$   rN   r   Zbase_process_llm_requestrX   Z_handle_llm_api_exception)r(   r)   r*   rb   rc   rd   re   r+   rg   r-   r.   r/   r0   rh   ri   rj   r1   rk   rl   r2   r   Zimage_filesZ
mask_files	processorr_   r   r   r   image_edit_api   s   '8




	
rn   ))rS   r]   typingr   rL   Zfastapir   r   r   r   r   r   r	   Zfastapi.responsesr
   rO   Zlitellm._loggingr   Z8litellm.litellm_core_utils.prompt_templates.common_utilsr   Zlitellm.proxy._typesZ$litellm.proxy.auth.user_api_key_authr   r   Z'litellm.proxy.common_request_processingr   Zlitellm.proxy.route_llm_requestr   Zlitellm.types.llms.openair   Zrouterr   r   r   r   Optionalr$   postr[   r8   rn   r   r   r   r   <module>   s    $

	 	





