
    h!                        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j        e          Z G d d          Z G 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                      e Zd ZdZ eg d          ZdZdddedddfd*dZd+dZd,dZ	d-dZ
d.dZd/d Zd! Zd0d"Zd1d#Z	 	 d2d3d)ZdS )4
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                |    || _         || _        || _        || _        || _        |r|| _        ng | _        || _        d S N)retries_leftr   r   r   r   r   r   )selfr   r   r   r   r   r   r   s           Y/var/www/html/e360mart/e360mart_env/lib/python3.11/site-packages/firebase_admin/_retry.py__init__zHttpxRetry.__init__*   sR     ( 0,&, 	"DLLDL*D'''    c                *    t          j        |           S )z%Creates a deep copy of this instance.)copydeepcopyr    s    r!   r%   zHttpxRetry.copyC   s    }T"""r#   responsehttpx.Responsec                    | 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_afters      r!   is_retryable_responsez HttpxRetry.is_retryable_responseG   sp      	X%9T=R%R%R4x/33MBBCC/	#	 (D,III4ur#   c                    | j         dk     S )z,Determine if there are anymore more retires.r   )r   r'   s    r!   is_exhaustedzHttpxRetry.is_exhaustedV   s      1$$r#   retry_after_headerstrfloat | Nonec                J   t          j        d|          rt          |          }nmt          j                            |          }|t          j        d|           t          j                            |          }|t          j	                    z
  }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    r4   secondsretry_date_tuple
retry_dates        r!   _parse_retry_afterzHttpxRetry._parse_retry_after\   s     8%'9:: 	/,--GG${778JKK'/0cOa0c0cddd../?@@J 49;;.Ggq//r#   c                j    |j                             dd          }|r|                     |          S dS )zFDetermine the Retry-After time needed before sending the next request.r+   N)r-   r.   rE   )r    r(   r4   s      r!   get_retry_afterzHttpxRetry.get_retry_aftern   s=    %-11-FF 	?**+=>>>tr#   c           	        t          | j                  }|dk    rdS | j        d|dz
  z  z  }| j        r|t	          j                    | j        z  z  }t          t          dt          | j        |                              S )zBDetermine the backoff time needed before sending the next request.   r      )	lenr   r   r   randomr   rA   minr   )r    attempt_countbackoffs      r!   get_backoff_timezHttpxRetry.get_backoff_timev   s     DL))A1%}Q)?@ 	=v})<<<GSC 0'::;;<<<r#   c                   K   |                                  }t                              d|           t          j        |           d{V  dS )zKDetermine and wait the backoff time needed before sending the next request.z;Sleeping for backoff of %f seconds following failed requestN)rP   loggerdebugasynciosleep)r    rO   s     r!   sleep_for_backoffzHttpxRetry.sleep_for_backoff   sU      ''))RT[\\\mG$$$$$$$$$$$r#   c                   K   | j         rN|                     |          }|r7t                              d|           t	          j        |           d{V  dS |                                  d{V  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   rG   rR   rS   rT   rU   rV   )r    r(   retry_afters      r!   rU   zHttpxRetry.sleep   s      * 	..x88K \   mK000000000$$&&&&&&&&&&&r#   requesthttpx.RequestOptional[httpx.Response]errorOptional[Exception]c                `    | xj         dz  c_         | j                            |||f           dS )z0Update the retry state based on request attempt.rI   N)r   r   append)r    rY   r(   r\   s       r!   	incrementzHttpxRetry.increment   s;     	QWh677777r#   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   )r(   r)   r   r   )r   r   )r4   r5   r   r6   )r(   r)   r   r6   r   r   )r(   r)   r   r   NN)rY   rZ   r(   r[   r\   r]   r   r   )__name__
__module____qualname____doc__	frozensetr/   DEFAULT_BACKOFF_MAXr"   r%   r1   r3   rE   rG   rP   rV   rU   r`    r#   r!   r   r   "   s)       ""(y99   "48$%!4$%
 /4E E E E E2# # # #   % % % %   $   
= 
= 
=% % % %' ' ' '  26)-	8 8 8 8 8 8 8r#   r   c                  V    e Zd ZdZ edddgd          ZefddZddZddZddZ	dS )HttpxRetryTransportz!HTTPX transport with retry logic.   i  r   g      ?)r   r   r   retryr   kwargsr   r   r   c                    || _         |                                }|                    ddd           t          j        di || _        d S )Nr   T)retrieshttp2ri   )_retryr%   updater=   AsyncHTTPTransport_wrapped_transport)r    rm   rn   transport_kwargss       r!   r"   zHttpxRetryTransport.__init__   sU    !;;==A = =>>> #(":"N"N=M"N"Nr#   rY   rZ   r)   c                R   K   |                      || j        j                   d {V S r   )_dispatch_with_retryru   handle_async_request)r    rY   s     r!   ry   z(HttpxRetryTransport.handle_async_request   sP      ..T,AC C C C C C C C 	Cr#   dispatch_method>Callable[[httpx.Request], Coroutine[Any, Any, httpx.Response]]c                p  K   | j                                         }d\  }}|                                s|r|                    |           d{V  d\  }}	 t                              d|            ||           d{V }t                              d|           n9# t          j        $ r'}t                              d|           |}Y d}~nd}~ww xY w|r|                    |          s|S |r||	                    |||           |                                |r|S |r|t          d          )zBSends a request with retry logic using a provided dispatch method.rb   Nz-Sending request in _dispatch_with_retry(): %rzReceived response: %rzReceived error: %rz:_dispatch_with_retry() ended with no response or exception)rr   r%   r3   rU   rR   rS   r=   	HTTPErrorr1   r`   AssertionError)r    rY   rz   rm   r(   r\   errs          r!   rx   z(HttpxRetryTransport._dispatch_with_retry   s        ""$%$$&& 	6  ,kk(+++++++++ )OHeLgVVV!0!9!99999994h?????   13777    ; ;H E E   OOGXu555/ $$&& 	62  	O 	KYZZZs   AB   C/CCc                H   K   | j                                          d {V  d S r   )ru   acloser'   s    r!   r   zHttpxRetryTransport.aclose   s3      %,,...........r#   N)rm   r   rn   r   r   r   )rY   rZ   r   r)   )rY   rZ   rz   r{   r   r)   ra   )
rc   rd   re   rf   r   DEFAULT_RETRYr"   ry   rx   r   ri   r#   r!   rk   rk      s        ++J1SzZ]^^^M+8 O O O O OC C C C)[ )[ )[ )[V/ / / / / /r#   rk   )rf   
__future__r   r%   email.utilsr:   rL   r8   r@   typingr   r   r   r   r   r	   loggingrT   r=   	getLoggerrc   rR   r   AsyncBaseTransportrk   ri   r#   r!   <module>r      s   
 # " " " " "       				  B B B B B B B B B B B B B B B B   		8	$	${8 {8 {8 {8 {8 {8 {8 {8|?/ ?/ ?/ ?/ ?/%2 ?/ ?/ ?/ ?/ ?/r#   