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      >@>             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.   J/home/ubuntu/.local/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loadsr0   r*   r,   r.   r.   r/   r1   $   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__r0   r1   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"   rG   super__init__)r,   r   r"   rG   	__class__r.   r/   rI   3   s   zHttpError.__init__rB   )r   r   r"   r!   rG   r&   )rC   rD   rE   rI   __classcell__r.   r.   rJ   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.
    r5   Nr8   
   )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.   r=   .0kvr.   r.   r/   
<dictcomp>o       z'HttpClient.__init__.<locals>.<dictcomp>N)endswithrstriprS   items_default_headersrU   rW   update_supported_errorsr
   r   sslSSLErrorrX   rZ   r[   r\   r^   r_   r`   ra   rc   )r,   rS   r    rU   rW   rX   rZ   r[   r\   r^   r_   r`   ra   rc   r.   r.   r/   rI   ?   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rv   r    rU   bodyry   
_json_callr,   ru   rv   r    rU   ry   r.   r.   r/   r:         
zHttpClient.getc              	   C  r{   )NDELETEr}   r   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   r}   r   _prepare_bodyr,   ru   r   r   rv   r    rU   ry   r.   r.   r/   post      zHttpClient.postc              
   C  r   )NPUTr   r}   r   r   r.   r.   r/   put   r   zHttpClient.putc              
   C  r   )NPATCHr   r}   r   r   r.   r.   r/   patch   r   zHttpClient.patchmethodr~   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 )Nr9   )r"   r   r   r    https)cafilecapathcadata)certfilekeyfilepasswordFc                     s   j  dS )N)contextrU   )_make_requestr.   r   reqr,   rU   r.   r/   <lambda>  s    z$HttpClient.request.<locals>.<lambda>c                 S  s   t  S rB   r   )_r.   r.   r/   r     s    c                   s
     | S rB   )_is_retryable_http_error)errorr3   r.   r/   r     s   
     c                 S  rf   r.   rg   rh   r.   r.   r/   rl      rm   z&HttpClient.request.<locals>.<dictcomp>coder   r   r    r"   r$   ) 
_build_url_prepare_headers
isinstancer!   encoder   upperr=   r>   rX   rs   create_default_contextrZ   r[   r\   r^   load_cert_chainr_   r`   check_hostname	CERT_NONEverify_moderW   call_with_retryr
   read	Exceptionr    rp   _maybe_decompressgetattrr   )r,   r   ru   rv   r    r~   rU   r"   all_headersr   e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)rU   r   c                 S  rf   r.   rg   rh   r.   r.   r/   rl   3  rm   z,HttpClient._make_request.<locals>.<dictcomp>r   )	r   rU   r   r    rp   r   r   r   geturl)r,   r   r   rU   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   ru   rv   r    r~   rU      i  )r   r   r   r"   r0   r1   )	r,   r   ru   rv   r    rU   r~   ry   r   r.   r.   r/   r   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)
ValueErrorr1   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 )Nr5   c                 S  s   i | ]\}}|d ur||qS rB   r.   rh   r.   r.   r/   rl   p  s    z)HttpClient._build_url.<locals>.<dictcomp>T)doseq?&)r   rS   r   rp   )r,   ru   rv   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, deflater4   zapplication/json; charset=utf-8authorizationr   r9   asciizBasic )updaterq   
setdefaultrc   r   r!   ra   base64	b64encoder   r+   rp   r=   )	r,   r    r~   prepareduserpwdtokenrj   rk   r.   r.   r/   r   v  s   
 zHttpClient._prepare_headersr   r   c                 C  s   |t v S rB   )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-encodingr5   gzipdeflate)r:   r=   r   
decompresszlib	MAX_WBITSr   r   )r,   r$   r    r%   r.   r.   r/   r     s"   	zHttpClient._maybe_decompress)rS   r!   r    rT   rU   rV   rW   r   rX   rY   rZ   r&   r[   r&   r\   r]   r^   r&   r_   r&   r`   r&   ra   rb   rc   r!   r'   rd   )NNNT)ru   r!   rv   rw   r    rT   rU   rx   ry   rY   r'   rz   )NNNNNT)ru   r!   r   r   r   r   rv   rw   r    rT   rU   rx   ry   rY   r'   rz   )NNNN)r   r!   ru   r!   rv   rw   r    rT   r~   r   rU   rx   r'   r   )NN)r   r   r   r   rU   rx   )r   r   r'   rY   )NNNNT)r   r!   ru   r!   rv   rw   r    rT   rU   rx   r~   r   ry   rY   r'   rz   )r   r   r   r   r'   r   rB   )ru   r!   rv   rw   r'   r!   )r    rT   r~   r   r'   r   )r   r   r'   rY   )r$   r#   r    r   r'   r#   )rC   rD   rE   __doc__r   r   r   DEFAULT_USER_AGENTrI   r:   r   r   r   r   r   r   r   r   r   r   r   r   r   r.   r.   r.   r/   r   :   s    GB


 r   )'
__future__r   r   r   r1   rs   r   dataclassesr   typingr   r   r   r   r   r	   urllib.errorr
   r   urllib.parser   r   urllib.requestr   r   __all__redis.backoffr   redis.retryr   redis.utilsr   r   r   r   r   r   r   r   r.   r.   r.   r/   <module>   s,     