o
    ưii                     @   s   d Z ddlZddlmZ ddlmZmZmZ ddlZddlm	Z	m
Z
 ddlmZm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 ddlmZ ddlmZ ddlmZ G dd deeZdS )a  
s3 Bucket Logging Integration

async_log_success_event: Processes the event, stores it in memory for DEFAULT_S3_FLUSH_INTERVAL_SECONDS seconds or until DEFAULT_S3_BATCH_SIZE and then flushes to s3 
async_log_failure_event: Processes the event, stores it in memory for DEFAULT_S3_FLUSH_INTERVAL_SECONDS seconds or until DEFAULT_S3_BATCH_SIZE and then flushes to s3 
NOTE 1: S3 does not provide a BATCH PUT API endpoint, so we create tasks to upload each element individually
    N)datetime)ListOptionalcast)print_verboseverbose_logger)DEFAULT_S3_BATCH_SIZE!DEFAULT_S3_FLUSH_INTERVAL_SECONDS)get_s3_object_key)
safe_dumps)
BaseAWSLLM)_get_httpx_clientget_async_httpx_clienthttpxSpecialProvider)s3BatchLoggingElement)StandardLoggingPayload   )CustomBatchLoggerc                +   @   s  e Zd Zdddddddddddddddeedddddfdee dee dee dee ded	ee d
ee dee dee dee dee dee dee dee dee dee dee dedededef*ddZ																					d5dee dee dee ded	ee d
ee dee dee dee dee dee dee dee dee dee dedededef&ddZ
dd Zdd  Zd!d" Zd#efd$d%Zd&d' Zd(ed)ee d*ee fd+d,Zd#efd-d.Zd/ed*ee fd0d1Zd2ed*ee fd3d4ZdS )6S3LoggerNTFs3_bucket_names3_paths3_region_names3_api_version
s3_use_ssl	s3_verifys3_endpoint_urls3_aws_access_key_ids3_aws_secret_access_keys3_aws_session_tokens3_aws_session_names3_aws_profile_names3_aws_role_names3_aws_web_identity_tokens3_aws_sts_endpoints3_flush_intervals3_batch_sizes3_use_team_prefixs3_strip_base64_filess3_use_key_prefixs3_use_virtual_hosted_stylec              
   K   sV  zt dtj  | jdi d|d|d|d|d|d|d|d	|	d
|
d|d|d|d|d|d|d|d|d|d|d| t d|  t d| j  ttjd| jid| _	t
|   t
 | _t d| d|  tj| | j||d g | _t|  W d S  ty } ztdt|  |d }~ww )Nz'in init s3 logger - s3_callback_params r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   	s3_configr   r&   r'   r(   r)   zs3 logger using endpoint url z8s3_v2 logger creating async httpx client with s3_verify=
ssl_verify)Zllm_providerparamszs3 flush interval: z, s3 batch size: )
flush_lockZflush_interval
batch_sizez Got exception on init s3 client  )r   debuglitellms3_callback_params_init_s3_paramsr   r   r   ZLoggingCallbackasync_httpx_clientasynciocreate_taskZperiodic_flushLockr-   r   __init__	log_queuer   	Exceptionr   str)selfr   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r*   r&   r'   r(   r)   kwargser/   r/   Q/home/app/Keep/.python/lib/python3.10/site-packages/litellm/integrations/s3_v2.pyr8      s   

	


zS3Logger.__init__c                 C   s  t jpi t _t j D ]\}}t|tr!|dr!t |t j|< qt jdp)|| _t jdp2|| _	t jdp;|| _
t jddurLt jddn|| _t jddur]t jdn|| _t jd	pg|| _t jd
pp|| _t jdpy|| _t jdp|	| _t jdp|
| _t jdp|| _t jdp|| _t jdp|| _t jdp|| _t jdp|| _t jdp|| _tt jddp|| _tt jddp|| _tt jddp|| _tt jddp|| _dS )zD
        Initialize the s3 params for this logging callback
        zos.environ/r   r   r   r   NTr   r   r   r   r   r   r    r!   r"   r#   r*   r   r&   Fr(   r'   r)   )r1   r2   items
isinstancer;   
startswithZ
get_secretgetr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r*   r   boolr&   r(   r'   r)   )r<   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r*   r   r&   r'   r(   r)   keyvaluer/   r/   r?   r3   w   sh    zS3Logger._init_s3_paramsc                       | j ||||dI d H  d S N)r=   response_obj
start_timeend_time_async_log_event_baser<   r=   rI   rJ   rK   r/   r/   r?   async_log_success_event   s   z S3Logger.async_log_success_eventc                    rG   rH   rL   rN   r/   r/   r?   async_log_failure_event   s   z S3Logger.async_log_failure_eventc              
      s   z>t d|  | j||dd d}|d u r&t d|dd W d S t d| | j| t dt| j| j W d S  tyb } zt 	d	t
|  | jd
d W Y d }~d S d }~ww )Nz/s3 Logging - Enters logging function for model Zstandard_logging_object)rJ   standard_logging_payloadzHs3 Logging - skipping event, no standard_logging_object for call_type=%sZ	call_typeunknownz!
s3 Logger - Logging payload = %sz*s3 logging: queue length %s, batch size %szs3 Layer Error - r   Zcallback_name)r   r0   create_s3_batch_logging_elementrC   r9   appendlenr.   r:   	exceptionr;   handle_callback_failure)r<   r=   rI   rJ   rK   Zs3_batch_logging_elementr>   r/   r/   r?   rM      s:   


zS3Logger._async_log_event_basebatch_logging_elementc                    sJ  zdd l }dd l}ddlm} ddlm} W n ty"   tdw zddlm} || j	}|| j
| j| j| j| j| j| j| j| jd	I d H }td|j  td| j  d	| j d
| j d|j }	| jr| jr| jr| jd	ddd}
| jd	rd	nd}| | j d|
 d|j }	n| jd | j d |j }	t|j}||d  }d|dd|j! ddd}|j"d|	||d}|# }||j$|j%|j&|j'd}| j(| jd}||d|)| t*|j'+ }| j,j-|	||dI d H }|.  W d S  t/y$ } zt0dt1|  | j2dd W Y d }~d S d }~ww )Nr   	SigV4Auth
AWSRequest7Missing boto3 to call bedrock. Run 'pip install boto3'.asyncify	aws_access_key_idaws_secret_access_keyaws_session_tokenaws_region_nameZaws_session_nameZaws_profile_nameZaws_role_nameZaws_web_identity_tokenZaws_sts_endpoint&s3_v2 logger - uploading data to s3 - z"s3_v2 logger - s3_verify setting: https://.s3..amazonaws.com/ http://./utf-8application/jsoneninline; filename=""0private, immutable, max-age=31536000, s-maxage=0zContent-Typex-amz-content-sha256zContent-LanguagezContent-DispositionzCache-ControlPUTdataheadersmethodurlrx   ry   re   s3Error uploading to s3: r   rS   )3hashlibrequestsbotocore.authr[   botocore.awsrequestr]   ImportError#litellm.litellm_core_utils.asyncifyr`   get_credentialsr   r   r   r   r   r    r!   r"   r#   r   r0   s3_object_keyr   r   r   r)   replacerB   r   payloadsha256encode	hexdigests3_object_download_filenameRequestpreparer{   r|   bodyry   )get_aws_region_name_for_non_llm_api_callsadd_authdictr@   r4   putraise_for_statusr:   rW   r;   rX   )r<   rY   r   r   r[   r]   r`   asyncified_get_credentialscredentialsr|   endpoint_hostprotocoljson_stringcontent_hashry   reqpreppedaws_requestre   signed_headersresponser>   r/   r/   r?   async_upload_data_to_s3  s   



	z S3Logger.async_upload_data_to_s3c                    sB   t dt| j  | jsdS | jD ]
}t| | qdS )z

        Sends runs from self.log_queue

        Returns: None

        Raises: Does not raise an exception, will only verbose_logger.exception()
        z s3_v2 logger - sending batch of N)r   r0   rV   r9   r5   r6   r   )r<   r   r/   r/   r?   async_send_batchw  s   	
zS3Logger.async_send_batchrJ   rQ   returnc           
      C   s  |du rdS | j r| |}g }| jr$|di dd}|r$|| | jr8|di dd}|r8|| d|}|rC|d7 }tj	||pKd}t
d| d| d	|  tttt | jpdd|||d
}t
d|  d|d d|d  d}	tt|||	dS )a  
        Helper function to create an s3BatchLoggingElement.

        Args:
            start_time (datetime): The start time of the logging event.
            standard_logging_payload (Optional[StandardLoggingPayload]): The payload to be logged.
            s3_path (Optional[str]): The S3 path prefix.

        Returns:
            Optional[s3BatchLoggingElement]: The created s3BatchLoggingElement, or None if payload is None.
        NmetadataZuser_api_key_team_aliasuser_api_key_aliasrm   rj   z(Creating s3 file with prefix_components=z,prefix_path=z and )r   prefixrJ   s3_file_namezs3_object_key=ztime-z%Y-%m-%dT%H-%M-%S-%f_idz.json)r   r   r   )r'   Z _strip_base64_from_messages_syncr&   rC   rU   r(   joinr1   utilsZget_logging_idr   r0   r
   r   r   r;   r   strftimer   r   )
r<   rJ   rQ   Zprefix_componentsZ
team_aliasr   prefix_pathr   r   r   r/   r/   r?   rT     s@   



z(S3Logger.create_s3_batch_logging_elementc              
   C   s*  zdd l }dd l}ddlm} ddlm} ddlm} W n ty'   tdw zt	
d|j  | j| j| j| j| jd}d| j d	| j d
|j }| jr| jr| jrz| jdddd}	| jdridnd}
|
 | j d|	 d|j }n| jd | j d |j }t|j}||d }d|dd|j ddd}|jd|||d}| }||j|j|j |j!d}| j"| jd}||d|#| t$|j!% }t&| j'd urd| j'ind d}|j(|||d}|)  W d S  t*y } zt	+dt,|  | j-dd W Y d }~d S d }~ww ) Nr   rZ   r\   )Credentialsr^   rf   )rb   rc   rd   re   rg   rh   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   rv   rw   rz   r}   r~   r+   )r,   r   r   rS   ).r   r   r   r[   r   r]   Zbotocore.credentialsr   r   r   r0   r   r   r   r   r   r   r   r   r)   r   rB   r   r   r   r   r   r   r   r   r{   r|   r   ry   r   r   r   r@   r   r   r   r   r:   rW   r;   rX   )r<   rY   r   r   r[   r]   r   r   r|   r   r   r   r   ry   r   r   r   re   r   Zhttpx_clientr   r>   r/   r/   r?   upload_data_to_s3  s   

	zS3Logger.upload_data_to_s3r   c                    s  zddl }ddl}ddlm} ddlm} W n ty"   tdw zddlm} || j	}|| j
| j| j| j| j| j| j| j| jd	I dH }td|  d	| j d
| j d| }	| jr| jr| jr| jd	ddd}
| jd	ryd	nd}| | j d|
 d| }	n| jd | j d | }	|d }d|i}|jd|	|d}| }||j|j|j d}||d| j!| t"|j # }| j$j%|	|dI dH }|j&dkrt'd|j( W dS |) W S  t*y } zt'dt+|  W Y d}~dS d}~ww )z
        Download and parse JSON object from S3.

        Args:
            s3_object_key: The S3 object key to download

        Returns:
            Optional[dict]: The parsed JSON object or None if not found/error
        r   NrZ   r\   z2Missing boto3 to call S3. Run 'pip install boto3'.r_   ra   z*s3_v2 logger - downloading data from s3 - rg   rh   ri   rj   rk   rl   rm       ru   GET)ry   )r{   r|   ry   r~      z"S3 object not found, saw response=zError downloading from S3: ),r   r   r   r[   r   r]   r   r   r`   r   r   r   r   r   r   r    r!   r"   r#   r   r0   r   r   r)   r   rB   r   r   r   r   r{   r|   ry   r   r   r@   r4   rC   status_coderW   textjsonr:   r;   )r<   r   r   r   r[   r]   r`   r   r   r|   r   r   Zempty_string_hashry   r   r   r   r   r   r>   r/   r/   r?   _download_object_from_s3  s   




z!S3Logger._download_object_from_s3
object_keyc              
      sZ   z|  |I dH }|W S  ty, } ztd| dt|  W Y d}~dS d}~ww )a  
        Get the proxy server request from cold storage

        Allows fetching a dict of the proxy server request from s3 or GCS bucket.

        Args:
            request_id: The unique request ID to search for
            start_time: The start time of the request (datetime or ISO string)

        Returns:
            Optional[dict]: The request data dictionary or None if not found
        NzError retrieving object z from cold storage: )r   r:   r   rW   r;   )r<   r   Zdownloaded_objectr>   r/   r/   r?   :get_proxy_server_request_from_cold_storage_with_object_keyx  s   zCS3Logger.get_proxy_server_request_from_cold_storage_with_object_key)NNNTNNNNNNNNNNNNFFFF)__name__
__module____qualname__r	   r   r   r;   rD   intr8   r3   rO   rP   rM   r   r   r   r   r   rT   r   r   r   r   r/   r/   r/   r?   r      s$   	

Z	

o	"
^
;R_r   )__doc__r5   r   typingr   r   r   r1   Zlitellm._loggingr   r   Zlitellm.constantsr   r	   Zlitellm.integrations.s3r
   Z*litellm.litellm_core_utils.safe_json_dumpsr   Z!litellm.llms.bedrock.base_aws_llmr   Z&litellm.llms.custom_httpx.http_handlerr   r   r   Z litellm.types.integrations.s3_v2r   Zlitellm.types.utilsr   Zcustom_batch_loggerr   r   r/   r/   r/   r?   <module>   s    