o
    iYX                     @   s^  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ZddlZddlZddl	Z	ddl
mZmZmZmZmZm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mZ dd
lmZmZ dedefddZdedefddZ dedede!fddZ"dedefddZ#dedefddZ$de%eef de%eef fddZ&dedefd d!Z'd"edefd#d$Z(d%e%ee)f ddfd&d'Z*d(eddfd)d*Z+defd+d,Z,d-eddfd.d/Z-de%eef ddfd0d1Z.ej/d2d3d(eded fd4d5Z0ej1d2d3d(eded fd6d7Z2G d8d9 d9eZ3G d:d; d;eZ4G d<d= d=eZ5G d>d? d?eZ6G d@d3 d3eZ7dS )AzReplay API client.    N)AnyLiteralOptionalUnionIteratorAsyncIterator   )errors)BaseApiClient)HttpRequest)HttpResponse)	BaseModel)HttpOptionsHttpOptionsOrDictnamereturnc                 C   s2   t | ts	t| } tdd| }tdd| S )z=Converts a string from camelCase or PascalCase to snake_case.z(.)([A-Z][a-z]+)z\1_\2z([a-z0-9])([A-Z]))
isinstancestrresublower)r   s1 r   e/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/google/genai/_replay_api_client.pyto_snake_case'   s   
r   objc                 C   sh   t | trdd |  D S t | trdd | D S t | tjr#| jS t | tr2d| v r2| ddS | S )Nc                 S   s   i | ]\}}t |t|qS r   )r   _normalize_json_case).0kvr   r   r   
<dictcomp>2   s    z(_normalize_json_case.<locals>.<dictcomp>c                 S   s   g | ]}t |qS r   r   )r   itemr   r   r   
<listcomp>7   s    z(_normalize_json_case.<locals>.<listcomp>zdivision by zeroz"integer division or modulo by zero)	r   dictitemslistenumEnumvaluer   replace)r   r   r   r   r   0   s   


r   obj1obj2c                 C   s    t | }t |}||krdS dS )a  Compares two Python objects for equality ignoring key casing.

  Returns:
      bool: True if the two objects are equal regardless of key casing
  (camelCase vs. snake_case). For example, the following are considered equal:

  {'my_key': 'my_value'}
  {'myKey': 'my_value'}

  This also considers enums and strings with the same value as equal.
  For example, the following are considered equal:

  {'type': <Type.STRING: 'STRING'>}}
  {'type': 'STRING'}
  TFr!   )r+   r,   normalized_obj_1normalized_obj_2r   r   r   _equals_ignore_key_caseC   s
   r/   version_stringc                 C      t dd| S )z8Redacts version numbers in the form x.y.z from a string.z\d+\.\d+\.\d+[a-zA-Z0-9]*z{VERSION_NUMBER}r   r   )r0   r   r   r   _redact_version_numbers]      r3   language_labelc                 C   r1   )z;Removed because replay requests are used for all languages.z
gl-python/z{LANGUAGE_LABEL}/r2   )r5   r   r   r   _redact_language_labelb   r4   r6   headersc                 C   s   i }|   D ]?\}}| dkrd||< q| dkr$tt|||< q| dkr3tt|||< q| dkr:q| dkrAq|||< q|S )z,Redacts headers that should not be recorded.zx-goog-api-keyz
{REDACTED}z
user-agentzx-goog-api-clientzx-goog-user-projectauthorization)r%   r   r6   r3   )r7   redacted_headersheader_nameheader_valuer   r   r   _redact_request_headersg   s$   



r<   urlc                 C   s<   t dd| }t dd|}t dd|}t dd|}|S )Nz".*/projects/[^/]+/locations/[^/]+/z{VERTEX_URL_PREFIX}/z#.*-aiplatform.googleapis.com/[^/]+/z".*aiplatform.googleapis.com/[^/]+/z+.*generativelanguage.*.googleapis.com/[^/]+z{MLDEV_URL_PREFIX}r2   )r=   resultr   r   r   _redact_request_url~   s*   r?   pathc                 C   s&   d| v rd| v rt dd| }|S | S )Nz	projects/z
locations/zprojects/[^/]+/locations/[^/]+/z{PROJECT_AND_LOCATION_PATH}/r2   )r@   r>   r   r   r   _redact_project_location_path   s   rA   bodyc                 C   s,   |   D ]\}}t|trt|| |< qdS )z,Redacts fields in the request body in place.N)r%   r   r   rA   )rB   keyr)   r   r   r   _redact_request_body   s
   
rD   http_requestc                 C   s6   t | j| _t| j| _t| jtst| j d S d S N)r<   r7   r?   r=   r   databytesrD   )rE   r   r   r   redact_http_request   s
   rI   c                  C   sR   t  } | dur'| jdur'| jjdur'| jj}t |}|j}d| d| S dS )z-Prints the current file path and line number.NzFile: z, Line:  )inspectcurrentframef_backgetfilef_lineno)current_frameframefilepathlinenor   r   r   _current_file_path_and_line   s   

rT   messagec                 C   s    t dtjddt d|  d S )NzDEBUG (testPYTEST_CURRENT_TEST)z:
    )printosenvirongetrT   )rU   r   r   r   _debug_print   s   
r\   c                 C   s   |  dd |  dd dS )z*Remove headers that are not deterministic.DateNzServer-Timing)pop)r7   r   r   r   pop_undeterministic_headers   s   r_   clientReplayApiClientc              
   c   s:    zd V  W d S  t jy } z| || |d }~ww rF   r	   APIError_record_interactionr`   rE   er   r   r   _record_on_api_error      rg   c              
   C  s:   zd V  W d S  t jy } z| || |d }~ww rF   rb   re   r   r   r   _async_record_on_api_error   rh   ri   c                   @   sF   e Zd ZU dZeed< eed< eeef ed< eeeef  ed< dS )ReplayRequestz(Represents a single request in a replay.methodr=   r7   body_segmentsN)	__name__
__module____qualname____doc__r   __annotations__r$   r&   objectr   r   r   r   rj      s   
 rj   c                   @   s|   e Zd ZU dZdZeed< eeef ed< e	eee
f  ed< dZee	e  ed< e	eee
f  ed< d	ed
dfddZdS )ReplayResponsez)Represents a single response in a replay.   status_coder7   rl   Nbyte_segmentssdk_response_segments_ReplayResponse__contextr   c                 C   s   t | j d S rF   )r_   r7   )selfrx   r   r   r   model_post_init   s   zReplayResponse.model_post_init)rm   rn   ro   rp   ru   intrq   r$   r   r&   rr   rv   r   rH   r   rz   r   r   r   r   rs      s   
 rs   c                   @   s"   e Zd ZU dZeed< eed< dS )ReplayInteractionzBRepresents a single interaction, request and response in a replay.requestresponseN)rm   rn   ro   rp   rj   rq   rs   r   r   r   r   r|      s   
 r|   c                   @   s&   e Zd ZU dZeed< ee ed< dS )
ReplayFilezRepresents a recorded session.	replay_idinteractionsN)rm   rn   ro   rp   r   rq   r&   r|   r   r   r   r   r     s   
 r   c                       s\  e Zd ZdZ								dAded dedee ded	ee d
eej	j
j dee dee dee def fddZdeddfddZdefddZdefddZdefddZdBddZdBddZdee dedefdd ZdBd!d"Zd#ed$eeejef ddfd%d&Zd#ed'eddfd(d)Zd#edefd*d+Zd,e ddfd-d.Z!		dCd#edee" d/edef fd0d1Z#		dCd#edee" d/edef fd2d3Z$dd4d5eee%j&f d6ed7e'dee" def
 fd8d9Z(dd4d5eee%j&f d6ed7e'dee" def
 fd:d;Z)dd4d<edee" deeee*f f fd=d>Z+dd4d<edee" de*f fd?d@Z,  Z-S )Dra   zFFor integration testing, send recorded response or records a response.NFmode)recordreplayautoapir   replays_directoryvertexaiapi_keycredentialsprojectlocationhttp_optionsprivatec                    sP   t  j||||||	d || _| jstjdd | _d | _|| _|| _|
| _	d S )N)r   r   r   r   r   r   GOOGLE_GENAI_REPLAYS_DIRECTORY)
super__init__r   rY   rZ   r[   replay_session_mode
_replay_id_private)ry   r   r   r   r   r   r   r   r   r   r   	__class__r   r   r     s"   
zReplayApiClient.__init__r   c                 C   s   || _ |   d S rF   )r   _initialize_replay_session)ry   r   r   r   r   initialize_replay_session+  s   z)ReplayApiClient.initialize_replay_sessionc                 C   s   |  | j| jS rF   )"_generate_file_path_from_replay_idr   r   ry   r   r   r   _get_replay_file_path/  s   z%ReplayApiClient._get_replay_file_pathc                 C   s&   | j dv p| j dkotj|   S )N)r   r   r   )r   rY   r@   isfiler   r   r   r   r   _should_call_api4  s   

z ReplayApiClient._should_call_apic                 C   s   |   o| jdkS )Nr   )r   r   r   r   r   r   _should_update_replay:  s   z%ReplayApiClient._should_update_replayc                 C   s   | j s	|   d S d S rF   )r   r   r   r   r   r   (_initialize_replay_session_if_not_loaded=  s   z8ReplayApiClient._initialize_replay_session_if_not_loadedc                 C   s   t d| j  d| _d| _|  }tj|}| jdkr%|s%t	d| j | jdv rL|rLt
|d}tt| | _W d    n1 sGw   Y  |  rZt| jg d| _d S d S )NzTest is using replay id: r   r   z)Replay files do not exist for replay id: )r   r   r)r   r   )r\   r   _replay_index_sdk_response_indexr   rY   r@   r   r   
ValueErroropenr   model_validatejsonloadsreadr   r   )ry   replay_file_pathreplay_file_existsfr   r   r   r   A  s$   z*ReplayApiClient._initialize_replay_sessionreplay_directoryc                 C   sR   | d}t|dk rt| d|d u rg }n|g}|| tjj| d S )N/   zD: Session ID must be in the format of module/function/[vertex|mldev]z.json)splitlenr   extendrY   r@   join)ry   r   r   session_parts
path_partsr   r   r   r   V  s   

z2ReplayApiClient._generate_file_path_from_replay_idc                 C   sz   |   r| js	d S |  }tjtj|dd t|d}|| jj	ddd W d    n1 s3w   Y  d | _d S )NT)exist_okw   )exclude_unsetindent)
r   r   r   rY   makedirsr@   dirnamer   writemodel_dump_json)ry   r   r   r   r   r   closed  s   
zReplayApiClient.closerE   http_responsec                 C   s   |   sd S t| t|j|j|j|jgd}t|tr5t	t
|jt| dd | D |jg d}n0t|tjrLt	t
|jj| g|jg d}nt|tr[t	i g |gg d}n
tdtt| | jd u rntd| jjt||d	 d S )
N)rk   r=   r7   rl   c                 S   s   g | ]
}|d d d qS )Nd   s   ...r   )r   segr   r   r   r#     s    z7ReplayApiClient._record_interaction.<locals>.<listcomp>)r7   rl   rv   ru   rw   )r7   rl   ru   rw   )r7   rl   rv   rw   z Unsupported http_response type: No replay session found.)r}   r~   )r   rI   rj   rk   r=   r7   rG   r   r   rs   r$   r&   segmentsrv   ru   r	   rc   r~   _to_replay_recordcoderH   r   r   typer   r   appendr|   )ry   rE   r   r}   r~   r   r   r   rd   m  sR   

	



z#ReplayApiClient._record_interactioninteractionc                 C   s   t d|j  t d|jj  |j|jjksJ |j|jjks.J d|j d|jj |j|jjks7J t|j}t|t	sFt
| |g}|jj}t||s\J d| d| d S )Nzhttp_request.url: zinteraction.request.url: z"Request headers mismatch:
Actual: 
Expected: zRequest body mismatch:
Actual: )r\   r=   r}   r7   rk   copydeepcopyrG   r   rH   rD   rl   r/   )ry   rE   r   request_data_copyactual_request_bodyexpected_request_bodyr   r   r   _match_request  s.   
zReplayApiClient._match_requestc                 C   s   t | | jd u rtd| jj| j }| || |  jd7  _d| _tj	|j
 t|j
jdd |j
jD |j
jd}|jdgkrGdg|_|S )	Nr   r   r   c                 S   s   g | ]}t |qS r   )r   dumps)r   segmentr   r   r   r#     s    z?ReplayApiClient._build_response_from_replay.<locals>.<listcomp>)r7   response_streambyte_streamz{}rJ   )rI   r   r   r   r   r   r   r	   rc   raise_for_responser~   r   r7   rl   rv   r   )ry   rE   r   r   r   r   r   _build_response_from_replay  s$   
z+ReplayApiClient._build_response_from_replayresponse_modelc                 C   s  | j dkrd S | jstd| jj| jd  }|  rIt|tr$|d }t|dd }|r<|d ur<t|dd }|r<t	| |j
j|jdd d S t|trR|d }td	|jdd  |jdd
d}|j
j| j }t|trd|v rt|d trd|d v r|d d }tdt|  td|  t|tr|dkrt|}t|}||d d< | js||ksJ d| d| n
td| d|  |  jd7  _d S )Nr   r   r   r   sdk_http_responser7   T)exclude_nonezresponse_model: r   )r   r   rB   zraw_body length: z
raw_body: rJ   zSDK response mismatch:
Actual: r   z(Expected SDK response mismatch:
Actual: )r   r   r   r   r   r   r   r&   getattrr_   r~   rw   r   
model_dumpr\   r   r$   r   r   r   r   r   r   )ry   r   r   sdk_response_responser7   actualexpectedraw_bodyr   r   r   _verify_response  s^   








z ReplayApiClient._verify_responsestreamc                    s   |    |  rZtd|  t| | t |||}W d    n1 s&w   Y  |rKg }| D ]
}|t	| q3t
|j|}| || n| || td|j  |S | |S Nzapi mode request: %szapi mode result: %s)r   r   r\   rg   r   _requestr   r   r   r   r   r7   rd   r   ry   rE   r   r   r>   result_segmentsr   r   r   r   r   	  s    
zReplayApiClient._requestc              	      s   |    |  rmtd|  t| |4 I d H  t |||I d H }W d   I d H  n1 I d H s4w   Y  |r^g }| 2 z3 d H W }|t	| qA6 t
|j|}| || n| || td|j  |S | |S r   )r   r   r\   ri   r   _async_requestasync_segmentsr   r   r   r   r7   rd   r   r   r   r   r   r   #  s(   (
zReplayApiClient._async_requestr   	file_path
upload_urlupload_sizec          	         s   t |tjr&| }| }||tj tdddt	
|dii d}n
tddd|ii d}|  r[t| | t j||||d}W d    n1 sNw   Y  | || |S | |S NPOSTrJ   rH   zutf-8)rk   r=   rG   r7   r   r   )r   ioIOBasetellr   seekrY   SEEK_SETr   base64	b64encodedecoder   rg   r   upload_filerd   r   	ry   r   r   r   r   offsetcontentr}   r>   r   r   r   r   ?  s,   
zReplayApiClient.upload_filec          	   	      s   t |tjr'| }| }||tj tdddt	
|dii d}n
tddd|ii d}|  rit| |4 I d H  t j||||dI d H }W d   I d H  n1 I d H s\w   Y  | || |S | |S r   )r   r   r   r   r   r   rY   r   r   r   r   r   r   ri   r   async_upload_filerd   r   r   r   r   r   r   `  s.   (
z!ReplayApiClient.async_upload_filer@   c                   s|   |    | jd|i |d}|  r6t| | t j||d}W d    n1 s)w   Y  | || |S | |jd S Nr[   )r@   request_dictr   r   r   )	r   _build_requestr   rg   r   download_filerd   r   r   ry   r@   r   r}   r>   r   r   r   r     s   zReplayApiClient.download_filec             	      s   |    | jd|i |d}|  rDt| |4 I d H  t j||dI d H }W d   I d H  n1 I d H s7w   Y  | || |S | |jd S r   )	r   r   r   ri   r   async_download_filerd   r   r   r   r   r   r   r     s   (z#ReplayApiClient.async_download_file)NFNNNNNF)r   N)NF).rm   rn   ro   rp   r   r   r   boolgoogleauthr   Credentialsr   r   r   r   r   r   r   r   r   r   r   r   r   r	   rc   rH   rd   r|   r   r   r   r   r   r   r   r   r   r{   r   r   r   r   r   __classcell__r   r   r   r   ra     s    	
 


	
0
:"'")8rp   r   r   
contextlibr'   rK   r   r   rY   r   typingr   r   r   r   r   r   google.authr  rJ   r	   _api_clientr
   r   r   _commonr   typesr   r   r   r   r   r  r/   r3   r6   r$   r<   r?   rA   rr   rD   rI   rT   r\   r_   contextmanagerrg   asynccontextmanagerri   rj   rs   r|   r   ra   r   r   r   r   <module>   sP    	"	