o
    0=j!  ã                   @  sž   d Z 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
mZmZmZmZmZ ddlZddlZddlZe e¡ZG dd„ dƒZG dd„ dejƒZdS )	zeInternal retry logic module

This module provides utilities for adding retry logic to HTTPX requests
é    )ÚannotationsN)ÚAnyÚCallableÚListÚOptionalÚTupleÚ	Coroutinec                   @  s˜   e Zd ZdZeg d¢ƒZdZdddedddfd4dd„Zd5dd„Zd6dd„Z	d7dd„Z
d8d#d$„Zd9d%d&„Zd'd(„ Zd:d)d*„Zd;d+d,„Z		d<d=d2d3„ZdS )>Ú
HttpxRetryzHTTPX based retry config)i�  i­  é÷  éx   é
   Nr   FÚmax_retriesÚintÚstatus_forcelistúOptional[List[int]]Úbackoff_factorÚfloatÚbackoff_maxÚbackoff_jitterÚhistoryúSOptional[List[Tuple[httpx.Request, Optional[httpx.Response], Optional[Exception]]]]Úrespect_retry_after_headerÚboolÚreturnÚNonec                 C  s:   || _ || _|| _|| _|| _|r|| _ng | _|| _d S ©N)Úretries_leftr   r   r   r   r   r   )Úselfr   r   r   r   r   r   r   © r   ú_C:\Users\psant\Downloads\Anu Raj Backend\school\venv\Lib\site-packages\firebase_admin/_retry.pyÚ__init__*   s   
zHttpxRetry.__init__c                 C  s
   t  | ¡S )z%Creates a deep copy of this instance.N)ÚcopyÚdeepcopy©r   r   r   r   r!   C   s   
zHttpxRetry.copyÚresponseúhttpx.Responsec                 C  sD   | j r|j| j v rdS t|j d¡ƒ}| jr |r |j| jv r dS dS )zODetermine if a response implies that the request should be retried if possible.TúRetry-AfterFN)r   Ústatus_coder   ÚheadersÚgetr   ÚRETRY_AFTER_STATUS_CODES)r   r$   Úhas_retry_afterr   r   r   Úis_retryable_responseG   s   ÿþ
ýz HttpxRetry.is_retryable_responsec                 C  s
   | j dk S )z,Determine if there are anymore more retires.r   N)r   r#   r   r   r   Úis_exhaustedV   s   
zHttpxRetry.is_exhaustedÚretry_after_headerÚstrúfloat | Nonec                 C  s`   t  d|¡rt|ƒ}ntj |¡}|du rt d|› �¡‚tj |¡}|t	 	¡  }t
|dƒ}|S )z9Parses Retry-After string into a float with unit seconds.z^\s*[0-9]+\s*$NzInvalid Retry-After header: r   )ÚreÚmatchr   ÚemailÚutilsÚparsedate_tzÚhttpxZRemoteProtocolErrorÚ	mktime_tzÚtimeÚmax)r   r.   ÚsecondsÚretry_date_tupleÚ
retry_dater   r   r   Ú_parse_retry_after\   s   

zHttpxRetry._parse_retry_afterc                 C  s    |j  dd¡}|r|  |¡S dS )zFDetermine the Retry-After time needed before sending the next request.r&   N)r(   r)   r=   )r   r$   r.   r   r   r   Úget_retry_aftern   s   
zHttpxRetry.get_retry_afterc                 C  sV   t | jƒ}|dkrdS | jd|d   }| jr |t ¡ | j 7 }ttdt| j|ƒƒƒS )zBDetermine the backoff time needed before sending the next request.é   r   é   N)	Úlenr   r   r   Úrandomr   r9   Úminr   )r   Zattempt_countÚbackoffr   r   r   Úget_backoff_timev   s   
zHttpxRetry.get_backoff_timec                 Ã  s*   �|   ¡ }t d|¡ t |¡I dH  dS )zKDetermine and wait the backoff time needed before sending the next request.z;Sleeping for backoff of %f seconds following failed requestN)rE   ÚloggerÚdebugÚasyncioÚsleep)r   rD   r   r   r   Úsleep_for_backoff‚   s   €zHttpxRetry.sleep_for_backoffc                 Ã  sH   �| j r|  |¡}|rt d|¡ t |¡I dH  dS |  ¡ I dH  dS )zCDetermine and wait the time needed before sending the next request.zFSleeping for Retry-After header of %f seconds following failed requestN)r   r>   rF   rG   rH   rI   rJ   )r   r$   Úretry_afterr   r   r   rI   ˆ   s   €
þzHttpxRetry.sleepÚrequestúhttpx.RequestúOptional[httpx.Response]ÚerrorúOptional[Exception]c                 C  s$   |  j d8  _ | j |||f¡ dS )z0Update the retry state based on request attempt.r?   N)r   r   Úappend)r   rL   r$   rO   r   r   r   Ú	increment•   s   zHttpxRetry.increment)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   r0   )r$   r%   r   r0   ©r   r   )r$   r%   r   r   ©NN)rL   rM   r$   rN   rO   rP   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	frozensetr*   ZDEFAULT_BACKOFF_MAXr    r!   r,   r-   r=   r>   rE   rJ   rI   rR   r   r   r   r   r	   "   s.    ô






ür	   c                   @  sN   e Zd ZdZedddgdd�Zefddd„Zddd„Zddd„Zddd„Z	dS )ÚHttpxRetryTransportz!HTTPX transport with retry logic.é   iô  r
   g      à?)r   r   r   Úretryr	   Úkwargsr   r   r   c                 K  s4   || _ | ¡ }| dddœ¡ tjdi |¤Ž| _d S )Nr   T)ÚretriesZhttp2r   )Ú_retryr!   Úupdater6   ZAsyncHTTPTransportÚ_wrapped_transport)r   r\   r]   Ztransport_kwargsr   r   r   r    ¥   s   zHttpxRetryTransport.__init__rL   rM   r%   c                 Ã  s   �|   || jj¡I d H S r   )Ú_dispatch_with_retryra   Úhandle_async_request)r   rL   r   r   r   rc   ¯   s   €
ÿz(HttpxRetryTransport.handle_async_requestÚdispatch_methodú>Callable[[httpx.Request], Coroutine[Any, Any, httpx.Response]]c              
   Ã  sâ   �| j  ¡ }d\}}| ¡ se|r| |¡I dH  d\}}zt d|¡ ||ƒI dH }t d|¡ W n tjyL } zt d|¡ |}W Y d}~nd}~ww |rV| |¡sV|S |rZ|‚| 	|||¡ | ¡ r|ri|S |rm|‚t
dƒ‚)zBSends a request with retry logic using a provided dispatch method.rT   Nz-Sending request in _dispatch_with_retry(): %rzReceived response: %rzReceived error: %rz:_dispatch_with_retry() ended with no response or exception)r_   r!   r-   rI   rF   rG   r6   Ú	HTTPErrorr,   rR   ÚAssertionError)r   rL   rd   r\   r$   rO   Úerrr   r   r   rb   ³   s6   €
€þéz(HttpxRetryTransport._dispatch_with_retryc                 Ã  s   �| j  ¡ I d H  d S r   )ra   Úacloser#   r   r   r   ri   Þ   s   €zHttpxRetryTransport.acloseN)r\   r	   r]   r   r   r   )rL   rM   r   r%   )rL   rM   rd   re   r   r%   rS   )
rU   rV   rW   rX   r	   ZDEFAULT_RETRYr    rc   rb   ri   r   r   r   r   rZ       s    


+rZ   )rX   Ú
__future__r   r!   Úemail.utilsr3   rB   r1   r8   Útypingr   r   r   r   r   r   ÚloggingrH   r6   Ú	getLoggerrU   rF   r	   ZAsyncBaseTransportrZ   r   r   r   r   Ú<module>   s    
~