o
    iK;                     @  s   d dl m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
mZmZmZmZmZ d dlmZmZ d dlmZmZ d dlmZmZ g dZd d	lmZ d d
lmZ d dlmZ dZ dZ!h dZ"eG dd dZ#G dd de$Z%G dd dZ&dS )    )annotationsN)	dataclass)AnyDictMappingOptionalTupleUnion)	HTTPErrorURLError)	urlencodeurljoin)Requesturlopen)
HttpClientHttpResponse	HttpErrorDEFAULT_TIMEOUT)ExponentialWithJitterBackoff)Retry
dummy_failz)HttpClient/1.0 (+https://example.invalid)g      >@>   i  i  i  i  i  c                   @  sN   e Zd ZU ded< ded< ded< ded< ddddZdddZdddZd	S )r   intstatusDict[str, str]headersstrurlbytescontentNencodingOptional[str]returnc                 C  s   |p|   }| jj|ddS )Nreplace)errors)_get_encodingr   decode)selfr    enc r)   M/home/app/Keep/.python/lib/python3.10/site-packages/redis/http/http_client.pytext    s   zHttpResponse.textr   c                 C  s   t | j|  dS )N)r    )jsonloadsr+   r%   r'   r)   r)   r*   r,   $   s   zHttpResponse.jsonc                 C  sT   | j dd}|dD ]}| }| dr'|ddd  p$d  S qdS )Ncontent-type ;zcharset==   utf-8)r   getsplitstriplower
startswith)r'   ctypepartpr)   r)   r*   r%   '   s   zHttpResponse._get_encodingN)r    r!   r"   r   )r"   r   )r"   r   )__name__
__module____qualname____annotations__r+   r,   r%   r)   r)   r)   r*   r      s   
 
r   c                      s    e Zd Zd
d fdd	Z  ZS )r   Nr   r   r   r   messager!   c                   s4   || _ || _|pd| d| | _t | j d S )NzHTTP z for )r   r   rB   super__init__)r'   r   r   rB   	__class__r)   r*   rD   3   s   zHttpError.__init__r=   )r   r   r   r   rB   r!   )r>   r?   r@   rD   __classcell__r)   r)   rE   r*   r   2   s    r   c                   @  s4  e Zd ZdZddeeedddddd	dddddddefdXd!d"Z					dYdZd)d*Z						dYdZd+d,Z
							d[d\d1d2Z							d[d\d3d4Z							d[d\d5d6Z				d]d^d:d;Z		d_d`d@dAZdadDdEZ						dbdcdFdGZ	d_dddHdIZ	dedfdJdKZdgdMdNZdhdQdRZdidVdWZdS )jr   z7
    A lightweight HTTP client for REST API calls.
    r0   Nr3   
   )basecap   )backoffretriesTbase_urlr   r   Optional[Mapping[str, str]]timeoutfloatretryr   
verify_tlsboolca_filer!   ca_pathca_dataOptional[Union[str, bytes]]client_cert_fileclient_key_fileclient_key_password
auth_basicOptional[Tuple[str, str]]
user_agentr"   Nonec                 C  s   |r| ds| d n|| _dd |pi  D | _|| _|| _| jtt	t
jf || _|| _|| _|| _|	| _|
| _|| _|| _|| _dS )a  
        Initialize a new HTTP client instance.

        Args:
            base_url: Base URL for all requests. Will be prefixed to all paths.
            headers: Default headers to include in all requests.
            timeout: Default timeout in seconds for requests.
            retry: Retry configuration for failed requests.
            verify_tls: Whether to verify TLS certificates.
            ca_file: Path to CA certificate file for TLS verification.
            ca_path: Path to a directory containing CA certificates.
            ca_data: CA certificate data as string or bytes.
            client_cert_file: Path to client certificate for mutual TLS.
            client_key_file: Path to a client private key for mutual TLS.
            client_key_password: Password for an encrypted client private key.
            auth_basic: Tuple of (username, password) for HTTP basic auth.
            user_agent: User-Agent header value for requests.

        The client supports both regular HTTPS with server verification and mutual TLS
        authentication. For server verification, provide CA certificate information via
        ca_file, ca_path or ca_data. For mutual TLS, additionally provide a client
        certificate and key via client_cert_file and client_key_file.
        /c                 S     i | ]	\}}|  |qS r)   r8   .0kvr)   r)   r*   
<dictcomp>o       z'HttpClient.__init__.<locals>.<dictcomp>N)endswithrstriprN   items_default_headersrP   rR   Zupdate_supported_errorsr
   r   sslSSLErrorrS   rU   rV   rW   rY   rZ   r[   r\   r^   )r'   rN   r   rP   rR   rS   rU   rV   rW   rY   rZ   r[   r\   r^   r)   r)   r*   rD   ?   s&   -
zHttpClient.__init__pathparamsGOptional[Mapping[str, Union[None, str, int, float, bool, list, tuple]]]Optional[float]expect_jsonUnion[HttpResponse, Any]c              	   C     | j d||||d |dS )NGETrp   r   rP   bodyrs   
_json_callr'   ro   rp   r   rP   rs   r)   r)   r*   r5         
zHttpClient.getc              	   C  ru   )NDELETErw   ry   r{   r)   r)   r*   delete   r|   zHttpClient.delete	json_bodyOptional[Any]dataOptional[Union[bytes, str]]c              
   C  "   | j d||||| j||d|dS )NPOSTr   r   rw   rz   _prepare_bodyr'   ro   r   r   rp   r   rP   rs   r)   r)   r*   post      zHttpClient.postc              
   C  r   )NPUTr   rw   r   r   r)   r)   r*   put   r   zHttpClient.putc              
   C  r   )NPATCHr   rw   r   r   r)   r)   r*   patch   r   zHttpClient.patchmethodrx   r   c                   sd   ||}||}t|tr|dn|}	t|| |	|dd  | drSj	rHt
jjjjd jrG jjjjd nt
  d _t
j _zj fddd	d fd
dW S  ty }
 z<d}z|
 }W n	 ty   Y nw dd |
jpi  D }||}t|
ddpd}t||||d}|W  Y d }
~
S d }
~
ww )Nr4   )r   r   r   r   https)cafilecapathcadata)certfilekeyfilepasswordFc                     s   j  dS )N)contextrP   )_make_requestr)   r   reqr'   rP   r)   r*   <lambda>  s    z$HttpClient.request.<locals>.<lambda>c                 S  s   t  S r=   r   )_r)   r)   r*   r     s    c                   s
     | S r=   )_is_retryable_http_error)errorr.   r)   r*   r     s   
     c                 S  ra   r)   rb   rc   r)   r)   r*   rg      rh   z&HttpClient.request.<locals>.<dictcomp>coder   r   r   r   r   ) 
_build_url_prepare_headers
isinstancer   encoder   upperr8   r9   rS   rm   create_default_contextrU   rV   rW   rY   load_cert_chainrZ   r[   check_hostname	CERT_NONEverify_moderR   Zcall_with_retryr
   read	Exceptionr   rk   _maybe_decompressgetattrr   )r'   r   ro   rp   r   rx   rP   r   Zall_headersr   eZerr_bodyheaders_mapr   responser)   r   r*   request   s^   
zHttpClient.requestr   r   r   Optional[ssl.SSLContext]c                 C  sv   t ||p| j|d'}| }dd |j D }| ||}t|j|| |dW  d    S 1 s4w   Y  d S )N)rP   r   c                 S  ra   r)   rb   rc   r)   r)   r*   rg   3  rh   z,HttpClient._make_request.<locals>.<dictcomp>r   )	r   rP   r   r   rk   r   r   r   geturl)r'   r   r   rP   resprawr   r)   r)   r*   r   +  s   $zHttpClient._make_requestr   r   c                 C  s   t |tr| |jS dS )NF)r   r
   _should_retry_statusr   )r'   r   r)   r)   r*   r   <  s   
z#HttpClient._is_retryable_http_errorc           	      C  sR   | j ||||||d}d|j  krdk s!n t|j|j| |r'| S |S )N)r   ro   rp   r   rx   rP      i  )r   r   r   r   r+   r,   )	r'   r   ro   rp   r   rP   rx   rs   r   r)   r)   r*   rz   B  s   zHttpClient._json_callc                 C  s4   |d ur|d urt d|d urtj|dddS |S )Nz+Provide either json_body or data, not both.F),:)ensure_ascii
separators)
ValueErrorr,   dumps)r'   r   r   r)   r)   r*   r   \  s
   zHttpClient._prepare_bodyc                 C  sZ   t | jpd|}|r+tdd | D dd}d|v rdnd}|r)| | | n|}|S )Nr0   c                 S  s   i | ]\}}|d ur||qS r=   r)   rc   r)   r)   r*   rg   p  s    z)HttpClient._build_url.<locals>.<dictcomp>T)doseq?&)r   rN   r   rk   )r'   ro   rp   r   query	separatorr)   r)   r*   r   e  s   zHttpClient._build_urlr   c           	      C  s   i }| | j |dd |d| j |dd |d ur*t|tr*|dd | jrMd|vrM| j\}}t| d	| 	d

d}d| |d< |r^| D ]
\}}||| < qS|S )Nacceptzapplication/jsonz
user-agentzaccept-encodingzgzip, deflater/   zapplication/json; charset=utf-8authorizationr   r4   asciizBasic )updaterl   
setdefaultr^   r   r   r\   base64	b64encoder   r&   rk   r8   )	r'   r   rx   prepareduserpwdtokenre   rf   r)   r)   r*   r   v  s   
 zHttpClient._prepare_headersr   r   c                 C  s   |t v S r=   )RETRY_STATUS_CODES)r'   r   r)   r)   r*   r     s   zHttpClient._should_retry_statusr   r   Mapping[str, str]c                 C  s   |s|S | dp
d }z,d|v rt|W S d|v r7z
t|tj W W S  tjy6   t| Y W S w W |S  tyD   | Y S w )Nzcontent-encodingr0   gzipdeflate)r5   r8   r   
decompresszlib	MAX_WBITSr   r   )r'   r   r   r    r)   r)   r*   r     s"   	zHttpClient._maybe_decompress)rN   r   r   rO   rP   rQ   rR   r   rS   rT   rU   r!   rV   r!   rW   rX   rY   r!   rZ   r!   r[   r!   r\   r]   r^   r   r"   r_   )NNNT)ro   r   rp   rq   r   rO   rP   rr   rs   rT   r"   rt   )NNNNNT)ro   r   r   r   r   r   rp   rq   r   rO   rP   rr   rs   rT   r"   rt   )NNNN)r   r   ro   r   rp   rq   r   rO   rx   r   rP   rr   r"   r   )NN)r   r   r   r   rP   rr   )r   r   r"   rT   )NNNNT)r   r   ro   r   rp   rq   r   rO   rP   rr   rx   r   rs   rT   r"   rt   )r   r   r   r   r"   r   r=   )ro   r   rp   rq   r"   r   )r   rO   rx   r   r"   r   )r   r   r"   rT   )r   r   r   r   r"   r   )r>   r?   r@   __doc__r   r   r   DEFAULT_USER_AGENTrD   r5   r~   r   r   r   r   r   r   rz   r   r   r   r   r   r)   r)   r)   r*   r   :   s    GB


 r   )'
__future__r   r   r   r,   rm   r   dataclassesr   typingr   r   r   r   r   r	   urllib.errorr
   r   urllib.parser   r   urllib.requestr   r   __all__Zredis.backoffr   Zredis.retryr   Zredis.utilsr   r   r   r   r   r   r   r   r)   r)   r)   r*   <module>   s,     