o
    è’Ojn9  ã                   @   s   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
 e e¡Zdeee
e	giZdd„ Zdd„ Zd%d	d
„Zd%dd„Zd%dd„Zdd„ Zdd„ Zdd„ ZG dd„ dƒZG dd„ dƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd „ d eƒZG d!d"„ d"eƒZG d#d$„ d$eƒZdS )&é    N)Úcrc32)ÚChecksumErrorÚConnectionClosedErrorÚConnectionErrorÚEndpointConnectionErrorÚReadTimeoutErrorÚGENERAL_CONNECTION_ERRORc                 C   s<   | dkr	t   ¡ } n| dkrtd| › �ƒ‚| ||d   }|S )a1  Calculate time to sleep based on exponential function.

    The format is::

        base * growth_factor ^ (attempts - 1)

    If ``base`` is set to 'rand' then a random number between
    0 and 1 will be used as the base.
    Base must be greater than 0, otherwise a ValueError will be
    raised.

    Úrandr   z.The 'base' param must be greater than 0, got: é   )ÚrandomÚ
ValueError)ÚbaseÚgrowth_factorÚattemptsÚtime_to_sleep© r   ú[/var/www/html/pharmsmart-cdr-gen/venv/lib/python3.10/site-packages/botocore/retryhandler.pyÚdelay_exponential+   s   
ÿr   c                 C   s   t jt| |d�S )z§Create an exponential delay function based on the attempts.

    This is used so that you only have to pass it the attempts
    parameter to calculate the delay.

    ©r   r   )Ú	functoolsÚpartialr   r   r   r   r   Ú!create_exponential_delay_functionB   s   ÿr   c                 C   s$   t | |d�}t| |d�}t||d�S )N)Úoperation_name)ÚcheckerÚaction)Ú create_checker_from_retry_configÚcreate_retry_action_from_configÚRetryHandler)Úconfigr   r   r   r   r   r   Úcreate_retry_handlerN   s   ÿÿr   c                 C   s0   | d d }|d dkrt |d |d d�S d S )NÚ__default__ÚdelayÚtypeÚexponentialr   r   r   )r   )r   r   Údelay_configr   r   r   r   X   s   þÿr   c                 C   sü   g }d }g }d| v r5| d   dg ¡}| d d }|D ]}|| }| t|ƒ¡ t|ƒ}|d ur4| |¡ q|d urc|   |¡d urc| | d }	|	D ]}| t|	| ƒ¡ t|	| ƒ}|d urb| |¡ qHt|ƒdkrqt|d |d�S t|ƒ}
t|
|t|ƒd�S )Nr    ÚpoliciesÚmax_attemptsr
   r   )r&   )r&   Úretryable_exceptions)	ÚgetÚappendÚ_create_single_checkerÚ_extract_retryable_exceptionÚextendÚlenÚMaxAttemptsDecoratorÚMultiCheckerÚtuple)r   r   Úcheckersr&   r'   r%   ÚkeyÚcurrent_configÚretry_exceptionÚoperation_policiesÚmulti_checkerr   r   r   r   e   s>   
€ÿ
€ýr   c                 C   s2   d| d v rt | d d ƒS d| d v rtƒ S d S )NÚresponseÚapplies_whenÚsocket_errors)Ú_create_single_response_checkerÚExceptionRaiser)r   r   r   r   r*   ‡   s   
ÿÿr*   c                 C   s\   d| v rt | d | d d�}|S d| v rt| d d�}|S d| v r*t| d d�}|S tdƒ‚)NÚservice_error_codeÚhttp_status_code)Ústatus_codeÚ
error_code)r>   Ú	crc32body)ÚheaderzUnknown retry policy)ÚServiceErrorCodeCheckerÚHTTPStatusCodeCheckerÚCRC32Checkerr   )r7   r   r   r   r   r:   �   s   þ÷ÿûÿr:   c                 C   sN   | d }d|  di ¡v rtgS d|v r%g }|d D ]	}| t| ¡ q|S d S )Nr8   r@   r7   r9   )r(   r   r,   ÚEXCEPTION_MAP)r   r8   Ú
exceptionsÚnamer   r   r   r+   ¢   s   ür+   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )r   a¯  Retry handler.

    The retry handler takes two params, ``checker`` object
    and an ``action`` object.

    The ``checker`` object must be a callable object and based on a response
    and an attempt number, determines whether or not sufficient criteria for
    a retry has been met.  If this is the case then the ``action`` object
    (which also is a callable) determines what needs to happen in the event
    of a retry.

    c                 C   ó   || _ || _d S ©N)Ú_checkerÚ_action)Úselfr   r   r   r   r   Ú__init__»   ó   
zRetryHandler.__init__c                 K   sr   |||dœ}t | jtƒr|d d  d¡}| d|i¡ | jd
i |¤Žr2| j|d�}t d|¡ |S t d¡ d	S )z›Handler for a retry.

        Intended to be hooked up to an event handler (hence the **kwargs),
        this will process retries appropriately.

        )Úattempt_numberr7   Úcaught_exceptionÚrequest_dictÚcontextÚretriesÚretries_context)r   zRetry needed, action of: %szNo retry needed.Nr   )Ú
isinstancerJ   r.   r(   ÚupdaterK   ÚloggerÚdebug)rL   r   r7   rP   ÚkwargsÚchecker_kwargsrT   Úresultr   r   r   Ú__call__¿   s   ýzRetryHandler.__call__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rM   r\   r   r   r   r   r   ­   s    r   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚBaseCheckerz Base class for retry checkers.

    Each class is responsible for checking a single criteria that determines
    whether or not a retry should not happen.

    c                 C   s0   |dur
|   ||¡S |dur|  ||¡S tdƒ‚)aÄ  Determine if retry criteria matches.

        Note that either ``response`` is not None and ``caught_exception`` is
        None or ``response`` is None and ``caught_exception`` is not None.

        :type attempt_number: int
        :param attempt_number: The total number of times we've attempted
            to send the request.

        :param response: The HTTP response (if one was received).

        :type caught_exception: Exception
        :param caught_exception: Any exception that was caught while trying to
            send the HTTP response.

        :return: True, if the retry criteria matches (and therefore a retry
            should occur.  False if the criteria does not match.

        Nz,Both response and caught_exception are None.)Ú_check_responseÚ_check_caught_exceptionr   )rL   rO   r7   rP   r   r   r   r\   Þ   s   ÿzBaseChecker.__call__c                 C   ó   d S rI   r   ©rL   rO   r7   r   r   r   rb   ý   ó   zBaseChecker._check_responsec                 C   rd   rI   r   ©rL   rO   rP   r   r   r   rc      rf   z#BaseChecker._check_caught_exceptionN)r]   r^   r_   r`   r\   rb   rc   r   r   r   r   ra   Ö   s
    ra   c                   @   s*   e Zd ZdZd	dd„Zdd„ Zdd„ ZdS )
r.   a“  Allow retries up to a maximum number of attempts.

    This will pass through calls to the decorated retry checker, provided
    that the number of attempts does not exceed max_attempts.  It will
    also catch any retryable_exceptions passed in.  Once max_attempts has
    been exceeded, then False will be returned or the retryable_exceptions
    that was previously being caught will be raised.

    Nc                 C   s   || _ || _|| _d S rI   )rJ   Ú_max_attemptsÚ_retryable_exceptions)rL   r   r&   r'   r   r   r   rM     s   
zMaxAttemptsDecorator.__init__c                 C   st   |rt | dd¡| jƒ|d< |  |||¡}|r8|| jkr6|d ur.d|d v r.d|d d d< t d|¡ dS |S dS )	NÚmaxr   ÚResponseMetadatar
   TÚMaxAttemptsReachedz0Reached the maximum number of retry attempts: %sF)rj   r(   rh   Ú_should_retryrW   rX   )rL   rO   r7   rP   rT   Úshould_retryr   r   r   r\     s&   ÿÿ
ÿþzMaxAttemptsDecorator.__call__c              
   C   sh   | j r-|| jk r-z|  |||¡W S  | j y, } ztjd|dd� W Y d }~dS d }~ww |  |||¡S )Nz,retry needed, retryable exception caught: %sT)Úexc_info)ri   rh   rJ   rW   rX   )rL   rO   r7   rP   Úer   r   r   rm   0  s   ÿý€ú
z"MaxAttemptsDecorator._should_retryrI   )r]   r^   r_   r`   rM   r\   rm   r   r   r   r   r.     s
    

r.   c                   @   ó   e Zd Zdd„ Zdd„ ZdS )rC   c                 C   ó
   || _ d S rI   )Ú_status_code)rL   r>   r   r   r   rM   D  ó   
zHTTPStatusCodeChecker.__init__c                 C   s&   |d j | jkrt d| j¡ dS dS )Nr   z5retry needed: retryable HTTP status code received: %sTF)r>   rs   rW   rX   re   r   r   r   rb   G  s   þz%HTTPStatusCodeChecker._check_responseN©r]   r^   r_   rM   rb   r   r   r   r   rC   C  ó    rC   c                   @   rq   )rB   c                 C   rH   rI   )rs   Ú_error_code)rL   r>   r?   r   r   r   rM   S  rN   z ServiceErrorCodeChecker.__init__c                 C   sJ   |d j | jkr#|d  di ¡ d¡}|| jkr#t d| j| j¡ dS dS )Nr   r
   ÚErrorÚCodez>retry needed: matching HTTP status and error code seen: %s, %sTF)r>   rs   r(   rw   rW   rX   )rL   rO   r7   Úactual_error_coder   r   r   rb   W  s   
üz'ServiceErrorCodeChecker._check_responseNru   r   r   r   r   rB   R  ó    rB   c                   @   rq   )r/   c                 C   rr   rI   ©Ú	_checkers)rL   r1   r   r   r   rM   f  rt   zMultiChecker.__init__c                 C   s(   | j D ]}||||ƒ}|r|  S qdS )NFr|   )rL   rO   r7   rP   r   Úchecker_responser   r   r   r\   i  s   
ÿÿzMultiChecker.__call__N)r]   r^   r_   rM   r\   r   r   r   r   r/   e  rv   r/   c                   @   rq   )rD   c                 C   rr   rI   )Ú_header_name)rL   rA   r   r   r   rM   t  s   
zCRC32Checker.__init__c                 C   sv   |d }|j  | j¡}|d u rt d| j¡ d S t|d jƒd@ }|t|ƒks9t dt|ƒ|¡ tdt|ƒ|d�‚d S )Nr   z?crc32 check skipped, the %s header is not in the http response.l   ÿÿ z>retry needed: crc32 check failed, expected != actual: %s != %sr   )Úchecksum_typeÚexpected_checksumÚactual_checksum)	Úheadersr(   r   rW   rX   r   ÚcontentÚintr   )rL   rO   r7   Úhttp_responseÚexpected_crcÚactual_crc32r   r   r   rb   x  s(   ýüýùzCRC32Checker._check_responseNru   r   r   r   r   rD   s  r{   rD   c                   @   s   e Zd ZdZdd„ ZdS )r;   z`Raise any caught exceptions.

    This class will raise any non None ``caught_exception``.

    c                 C   s   |‚rI   r   rg   r   r   r   rc   ˜  s   z'ExceptionRaiser._check_caught_exceptionN)r]   r^   r_   r`   rc   r   r   r   r   r;   ‘  s    r;   rI   )r   Úloggingr   Úbinasciir   Úbotocore.exceptionsr   r   r   r   r   Ú	getLoggerr]   rW   rE   r   r   r   r   r   r*   r:   r+   r   ra   r.   rC   rB   r/   rD   r;   r   r   r   r   Ú<module>   s:   
üÿ




"	).?