U
    %FZh!                     @  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dddgZdZdddeddd	fd
ddddddddddZd dddZdddddZ	ddddZ
ddddd Zdddd!d"Zd#d$ Zddd%d&Zdddd'd(Zd/d)d*d+dd,d-d.ZdS )0
HttpxRetryzHTTPX based retry configi  i    x   
   Nr   FintzOptional[List[int]]floatzSOptional[List[Tuple[httpx.Request, Optional[httpx.Response], Optional[Exception]]]]boolNone)max_retriesstatus_forcelistbackoff_factorbackoff_maxbackoff_jitterhistoryrespect_retry_after_headerreturnc                 C  s:   || _ || _|| _|| _|| _|r*|| _ng | _|| _d S N)retries_leftr   r   r   r   r   r   )selfr   r   r   r   r   r   r    r   \/home/aprabhat/apps/x.techxrdev.in/venv/lib/python3.8/site-packages/firebase_admin/_retry.py__init__*   s    zHttpxRetry.__init__r   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httpx.Response)responser   c                 C  sD   | j r|j| j krdS t|jd}| jr@|r@|j| jk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strzfloat | None)retry_after_headerr   c                 C  s`   t d|rt|}n<tj|}|dk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      )	lenr   r   r   randomr   r7   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)rC   loggerdebugasynciosleep)r   rB   r   r   r   sleep_for_backoff   s    zHttpxRetry.sleep_for_backoffc                   sF   | j r4| |}|r4t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<   rD   rE   rF   rG   rH   )r   r$   retry_afterr   r   r   rG      s    
zHttpxRetry.sleephttpx.RequestzOptional[httpx.Response]zOptional[Exception])requestr$   errorr   c                 C  s$   |  j d8  _ | j|||f dS )z0Update the retry state based on request attempt.r=   N)r   r   append)r   rK   r$   rL   r   r   r   	increment   s    zHttpxRetry.increment)NN)__name__
__module____qualname____doc__	frozensetr)   DEFAULT_BACKOFF_MAXr   r    r+   r,   r;   r<   rC   rH   rG   rN   r   r   r   r   r	   "   s,     r	   c                   @  sh   e Zd ZdZedddgddZefddd	d
ddZdddddZddddddZd	dddZ	dS )HttpxRetryTransportz!HTTPX transport with retry logic.   i  r
   g      ?)r   r   r   r	   r   r   )retrykwargsr   c                 K  s0   || _ | }|ddd tjf || _d S )Nr   T)retriesZhttp2)_retryr    updater4   ZAsyncHTTPTransport_wrapped_transport)r   rW   rX   Ztransport_kwargsr   r   r   r      s    zHttpxRetryTransport.__init__rJ   r#   )rK   r   c                   s   |  || jjI d H S r   )_dispatch_with_retryr\   handle_async_request)r   rK   r   r   r   r^      s     z(HttpxRetryTransport.handle_async_requestz>Callable[[httpx.Request], Coroutine[Any, Any, httpx.Response]])rK   dispatch_methodr   c              
     s   | j  }d\}}| s|r.||I dH  d\}}z*td| ||I dH }td| W n4 tjk
r } ztd| |}W 5 d}~X Y nX |r||s|S |r||	||| q|r|S |r|t
ddS )zBSends a request with retry logic using a provided dispatch method.)NNNz-Sending request in _dispatch_with_retry(): %rzReceived response: %rzReceived error: %rz:_dispatch_with_retry() ended with no response or exception)rZ   r    r,   rG   rD   rE   r4   	HTTPErrorr+   rN   AssertionError)r   rK   r_   rW   r$   rL   errr   r   r   r]      s.    
z(HttpxRetryTransport._dispatch_with_retryr   c                   s   | j  I d H  d S r   )r\   acloser"   r   r   r   rc      s    zHttpxRetryTransport.acloseN)
rO   rP   rQ   rR   r	   ZDEFAULT_RETRYr   r^   r]   rc   r   r   r   r   rU      s   
+rU   )rR   
__future__r   r    email.utilsr1   r@   r/   r6   typingr   r   r   r   r   r   loggingrF   r4   	getLoggerrO   rD   r	   ZAsyncBaseTransportrU   r   r   r   r   <module>   s    
~