o
     i!                     @  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historySOptional[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   u/var/www/snowflake_co_dev_github/snow_flake_back_end_deploy/env/lib/python3.10/site-packages/firebase_admin/_retry.py__init__*   s   
zHttpxRetry.__init__c                 C  s
   t | S )z%Creates a deep copy of this instance.)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-AfterF)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   )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httpx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      )	lenr   r   r   randomr   r:   minr   )r   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)rG   loggerdebugasynciosleep)r   rF   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?   rH   rI   rJ   rK   rL   )r   r$   retry_afterr   r   r   rK      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   rN   r$   rQ   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)rN   rO   r$   rP   rQ   rR   r   r   )__name__
__module____qualname____doc__	frozensetr*   DEFAULT_BACKOFF_MAXr    r!   r,   r-   r>   r?   rG   rL   rK   rT   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)retrieshttp2r   )_retryr!   updater6   AsyncHTTPTransport_wrapped_transport)r   r_   r`   transport_kwargsr   r   r   r       s   zHttpxRetryTransport.__init__rN   rO   r%   c                   s   |  || jjI d H S r   )_dispatch_with_retryrf   handle_async_request)r   rN   r   r   r   ri      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.rV   Nz-Sending request in _dispatch_with_retry(): %rzReceived response: %rzReceived error: %rz:_dispatch_with_retry() ended with no response or exception)rc   r!   r-   rK   rH   rI   r6   	HTTPErrorr,   rT   AssertionError)r   rN   rj   r_   r$   rQ   errr   r   r   rh      s6   
z(HttpxRetryTransport._dispatch_with_retryc                   s   | j  I d H  d S r   )rf   acloser#   r   r   r   ro      s   zHttpxRetryTransport.acloseN)r_   r	   r`   r   r   r   )rN   rO   r   r%   )rN   rO   rj   rk   r   r%   rU   )
rW   rX   rY   rZ   r	   DEFAULT_RETRYr    ri   rh   ro   r   r   r   r   r]      s    


+r]   )rZ   
__future__r   r!   email.utilsr3   rC   r1   r9   typingr   r   r   r   r   r   loggingrJ   r6   	getLoggerrW   rH   r	   AsyncBaseTransportr]   r   r   r   r   <module>   s    
~