o
    l>j?                     @  sX  d 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mZ ddlmZmZmZ ddlmZ ddlmZ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%m&Z& e'e(Z)ed
e ee"ee&eZ*e
d Z+ee,e,ee-gdf Z.dZ/dddZ0G dd de1Z2G dd de1Z3G dd de1Z4G dd dZ5G dd dZ6g dZ7dS )z)Reusable typed CloudKit container client.    )annotationsN)CallableDictIterableIteratorListLiteralOptionalTypeVar)	urlencodeurlsplit
urlunsplit)ValidationError   )CloudKitExtraMode!resolve_cloudkit_validation_extra)CKDatabaseChangesResponseCKLookupDescriptorCKLookupRequestCKLookupResponseCKModifyOperationCKModifyRequestCKModifyResponseCKQueryObjectCKQueryRequestCKQueryResponseCKZoneChangesRequestCKZoneChangesResponseCKZoneChangesZoneCKZoneChangesZoneReqCKZoneIDReqCKZoneListResponse_ResponseModelT)pythonlowerzHTTP 429: rate limitedurlstrreturnc                 C  s    t | }t|j|j|jddfS )z<Return a CloudKit URL without query parameters or fragments. )r   r   schemenetlocpath)r%   parts r-   T/home/thesage/.local/lib/python3.10/site-packages/pyicloud/common/cloudkit/client.pyredact_cloudkit_url0   s   r/   c                   @  s   e Zd ZdZdS )CloudKitAuthErrorzGRaised when Apple rejects a CloudKit request due to auth/session state.N)__name__
__module____qualname____doc__r-   r-   r-   r.   r0   6   s    r0   c                      s(   e Zd ZdZddd fd
dZ  ZS )CloudKitRateLimitedz1Raised when Apple rate-limits a CloudKit request.Nretry_aftermessager&   r7   float | Noner'   Nonec                     t  | || _d S N)super__init__r7   )selfr8   r7   	__class__r-   r.   r>   =      
zCloudKitRateLimited.__init__)r8   r&   r7   r9   r'   r:   r1   r2   r3   r4   r>   __classcell__r-   r-   r@   r.   r5   :       r5   c                      s(   e Zd ZdZddd
 fdd	Z  ZS )CloudKitApiErrorzCRaised for transport, validation, or server-side CloudKit failures.Npayloadr8   r&   r'   r:   c                  r;   r<   )r=   r>   rH   )r?   r8   rH   r@   r-   r.   r>   E   rB   zCloudKitApiError.__init__)r8   r&   r'   r:   rC   r-   r-   r@   r.   rF   B   rE   rF   c                   @  s   e Zd ZdZdZddddddd8ddZeddd9ddZd:ddZd;d!d"Z	d<d'd(Z
dd)d=d,d-Zd>d/d0Zd1d2d?d6d7ZdS )@_CloudKitHTTPzBMinimal HTTP transport shared by typed CloudKit container clients.)g      $@g      N@Nr#   FTtimeoutbool_param_styleredact_urls
debug_hookhandle_rate_limitsbase_urlr&   base_paramsDict[str, object]rK   tuple[float, float] | NonerL   CloudKitBoolParamStylerM   boolrN   CloudKitDebugHook | NonerO   c          	      C  sH   | d| _|| _| j|pi |d| _|p| j| _|| _|| _|| _	d S )N/rL   )
rstrip	_base_url_session_normalize_params_params_REQUEST_TIMEOUT_timeout_redact_urls_debug_hook_handle_rate_limits)	r?   rP   sessionrQ   rK   rL   rM   rN   rO   r-   r-   r.   r>   O   s   
z_CloudKitHTTP.__init__rX   paramsr'   Dict[str, str]c                C  sJ   i }|   D ]\}}t|tr|dkr|rdnd||< qt|||< q|S )Nr$   truefalse)items
isinstancerU   r&   )rd   rL   outkeyvaluer-   r-   r.   r\   e   s   z_CloudKitHTTP._normalize_paramsr+   c                 C  s,   t | j}| j | |rd|  S d S )N?r(   )r   r]   rZ   )r?   r+   qr-   r-   r.   	build_urls   s   
"z_CloudKitHTTP.build_urlr%   c                 C  s   | j rt|S |S r<   )r`   r/   r?   r%   r-   r-   r.   _display_urlw   s   z_CloudKitHTTP._display_urloprH   r   r:   c                 C  sJ   | j d u rd S z|  |||| W d S  ty$   tjd|dd Y d S w )Nz!CloudKit debug hook failed for %sT)exc_info)ra   	ExceptionLOGGERdebug)r?   rr   r%   rH   responser-   r-   r.   _run_debug_hook|   s   
z_CloudKitHTTP._run_debug_hook)headersry   Dict | Nonec             
   C  s  |  |}|d}| jr| |n|}td| || jd}|d ur(||d< | jj|fi |}t	|dd}	t
|	ts?d}	|	dv rS| |||| td	|	 d
|	dkr| jr| |||| d }
z|jd}|rqt|}
W n ty}   d }
Y nw tt|
d|	dkr| |||| z| }W n ty   t	|dd }Y nw td	|	 |dz| W S  ty } z| |||| tdt	|dd d|d }~ww )NrW   zCloudKit POST %s)jsonrK   ry   status_coder      i  i  HTTP : unauthorized  Retry-Afterr6     textrG   zInvalid JSON response)ro   stripr`   rq   ru   rv   r_   r[   postgetattrri   intrx   r0   rb   ry   getfloatrt   r5   _RATE_LIMITEDr{   rF   )r?   r+   rH   ry   r%   rr   display_urlkwargsrespcoder7   hdrbodyexcr-   r-   r.   r      sd   




z_CloudKitHTTP.postbytesc                 C  s:  t d | jj|| jd}t|dd}t|tsd}|dv r/| d|i | t	d| d	|d
kr`| j
r`| d|i | d }z|jd}|rMt|}W n tyY   d }Y nw tt|d|dkrz| d|i | td| dt|dd dt|dd }t|tr|S t|dd }t|tr|dS td|d)NzCloudKit asset GET <redacted>)rK   r|   r   r}   r~   	asset_getr   r   r   r   r6   r    on asset GETr   rG   contentzutf-8zInvalid asset response)ru   rv   r[   r   r_   r   ri   r   rx   r0   rb   ry   r   rt   r5   r   rF   r   r&   encode)r?   r%   r   r   r7   r   r   r   r-   r-   r.   	get_bytes   sB   






z_CloudKitHTTP.get_bytes   
chunk_sizer   r   Iterator[bytes]c          	      c  s   t d| | | jj|d| jd}zt|dd}t|ts"d}|dv r6| 	d|i | t
d	| d
|dkrg| jrg| 	d|i | d }z|jd}|rTt|}W n ty`   d }Y nw tt|d|dkr| 	d|i | td	| dt|dd d|j|dD ]}|r|V  qW t|dd }t|rz|  W d S  ty   Y d S w d S t|dd }t|rz|  W w  ty   Y w w w )NzCloudKit asset stream GET %sT)streamrK   r|   r   r}   r~   r   r   r   r   r   r6   r   r   r   rG   r   close)ru   rv   rq   r[   r   r_   r   ri   r   rx   r0   rb   ry   r   rt   r5   r   rF   iter_contentcallable)	r?   r%   r   r   r   r7   r   chunkr   r-   r-   r.   
get_stream   sb   



z_CloudKitHTTP.get_stream)rP   r&   rQ   rR   rK   rS   rL   rT   rM   rU   rN   rV   rO   rU   )rd   rR   rL   rT   r'   re   )r+   r&   r'   r&   r%   r&   r'   r&   )rr   r&   r%   r&   rH   r   r'   r:   )r+   r&   rH   r   ry   rz   r'   r   r%   r&   r'   r   r%   r&   r   r   r'   r   )r1   r2   r3   r4   r^   r>   staticmethodr\   ro   rq   rx   r   r   r   r-   r-   r-   r.   rI   J   s$    



.!rI   c                   @  s   e Zd ZdZdddddddd^ddZd_ddZdddddd d`d-d.Zdd/dad4d5Zdd6dbd:d;Zdd6dcd=d>Z	dd?dddEdFZ
dedHdIZddJdfdMdNZdgdQdRZdSdTdhdXdYZdZd6did\d]ZdS )jCloudKitContainerClientz?Typed CloudKit client for a single container/environment/scope.Nr#   FT)validation_extrarK   rL   rM   rN   rO   rP   r&   rQ   rR   r   CloudKitExtraMode | NonerK   rS   rL   rT   rM   rU   rN   rV   rO   c          
   
   C  s$   t ||||||||	d| _|| _d S )NrJ   )rI   _http_validation_extra)
r?   rP   rc   rQ   r   rK   rL   rM   rN   rO   r-   r-   r.   r>      s   

z CloudKitContainerClient.__init__	model_clstype[_ResponseModelT]datar   r'   r"   c                 C  s   |j |t| jdS )N)extra)model_validater   r   )r?   r   r   r-   r-   r.   _validate_response  s   z*CloudKitContainerClient._validate_response)zone_iddesired_keysresults_limitcontinuation	zone_widequeryr   r   Optional[CKZoneIDReq]r   Optional[List[str]]r   Optional[int]r   Optional[str]r   r   c          
   
   C  s   |r
|d ur
t d|s|d u rt dt||||||r|nd djddd}| jd|}z| t|W S  tyH }	 ztd|d	|	d }	~	ww )
Nz+zone_id must be omitted when zone_wide=Truez)zone_id is required unless zone_wide=True)r   zoneIDdesiredKeysresultsLimitcontinuationMarkerzoneWider{   Tmodeexclude_none/records/queryz Query response validation failedrG   )	
ValueErrorr   
model_dumpr   r   r   r   r   rF   )
r?   r   r   r   r   r   r   rH   r   r   r-   r-   r.   r     s4   

zCloudKitContainerClient.query)r   record_namesIterable[str]r    r   c             
   C  sf   t dd |D ||djddd}| jd|}z| t|W S  ty2 } ztd|d	|d }~ww )
Nc                 S  s   g | ]	}t t|d qS ))
recordName)r   r&   ).0namer-   r-   r.   
<listcomp>F  s    z2CloudKitContainerClient.lookup.<locals>.<listcomp>)recordsr   r   r{   Tr   z/records/lookupz!Lookup response validation failedrG   )r   r   r   r   r   r   r   rF   )r?   r   r   r   rH   r   r   r-   r-   r.   lookup>  s&   zCloudKitContainerClient.lookup)r   zone_reqr   Iterator[CKZoneChangesZone]c          	   
   c  s    t |g|d}	 |jddd}| jd|}z| t|}W n ty2 } ztd|d|d }~ww |jr;|jd nd }|d u rCd S |V  |j	sKd S |j
|jd _
q	)	Nzonesr   Tr{   r   /changes/zone"Changes response validation failedrG   r   )r   r   r   r   r   r   r   rF   r   
moreComing	syncToken)	r?   r   r   reqrH   r   enveloper   zoner-   r-   r.   iter_changesS  s6   z$CloudKitContainerClient.iter_changesr   c             
   C  s\   t |g|djddd}| jd|}z| t|W S  ty- } ztd|d|d }~ww )Nr   r{   Tr   r   r   rG   )r   r   r   r   r   r   r   rF   )r?   r   r   rH   r   r   r-   r-   r.   changeso  s$   zCloudKitContainerClient.changes)atomic
operationsList[CKModifyOperation]r   Optional[bool]r   c             
   C  s\   t |||djddd}| jd|}z| t|W S  ty- } ztd|d|d }~ww )N)r   r   r   r{   Tr   z/records/modifyz!Modify response validation failedrG   )r   r   r   r   r   r   r   rF   )r?   r   r   r   rH   r   r   r-   r-   r.   modify  s&   zCloudKitContainerClient.modifyr!   c              
   C  sD   | j di }z| t|W S  ty! } ztd|d|d }~ww )Nz/zones/listz%Zones list response validation failedrG   )r   r   r   r!   r   rF   )r?   r   r   r-   r-   r.   
zones_list  s   z"CloudKitContainerClient.zones_list)
sync_tokenr   r   c             
   C  sT   i }|r||d< | j d|}z| t|W S  ty) } ztd|d|d }~ww )Nr   z/changes/databasez+Database changes response validation failedrG   )r   r   r   r   r   rF   )r?   r   rH   r   r   r-   r-   r.   database_changes  s   z(CloudKitContainerClient.database_changesr%   r   c                 C  s   | j |S r<   )r   r   rp   r-   r-   r.   download_asset_bytes  s   z,CloudKitContainerClient.download_asset_bytesr   r   r   r   r   c                c  s    | j j||dE d H  d S )Nr   )r   r   )r?   r%   r   r-   r-   r.   download_asset_stream  s   z-CloudKitContainerClient.download_asset_streamr   
str | Nonec             
   C  sx   t |||djddd}| jd|}z| t|}W n ty. } ztd|d|d }~ww t|dd r:t	|j
S d S )	N)r   r   r   r{   Tr   r   z+Sync token query response validation failedrG   r   )r   r   r   r   r   r   r   rF   r   r&   r   )r?   r   r   r   rH   r   rw   r   r-   r-   r.   query_sync_token  s,   
z(CloudKitContainerClient.query_sync_token)rP   r&   rQ   rR   r   r   rK   rS   rL   rT   rM   rU   rN   rV   rO   rU   )r   r   r   r   r'   r"   )r   r   r   r   r   r   r   r   r   r   r   rU   r'   r   )r   r   r   r    r   r   r'   r   )r   r   r   r   r'   r   )r   r   r   r   r'   r   )r   r   r   r    r   r   r'   r   )r'   r!   )r   r   r'   r   r   r   )r   r   r   r    r   r   r'   r   )r1   r2   r3   r4   r>   r   r   r   r   r   r   r   r   r   r   r   r-   r-   r-   r.   r      s@    
$ 

r   )rF   r0   r   r5   r/   r   )8r4   
__future__r   loggingtypingr   r   r   r   r   r   r	   r
   urllib.parser   r   r   pydanticr   baser   r   modelsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   	getLoggerr1   ru   r"   rT   r&   objectCloudKitDebugHookr   r/   rt   r0   r5   rF   rI   r   __all__r-   r-   r-   r.   <module>   s<    (H
	
 0 ^