o
    "`^hn9                     @   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   S/home/air/shanriGPT/back/venv/lib/python3.10/site-packages/botocore/retryhandler.pydelay_exponential+   s   
r   c                 C   s   t jt| |dS )zCreate 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 )zHandler 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 )	BaseCheckerzBase 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:   





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