o
    ˷e1                     @   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Z	ddl
mZ ddl
mZ ddlmZ eeZdZdZdZd	Zd
d Zeejejeje	jje	jjejZ	 efddZdddZG dd de Z!dS )ax  Helpers for retrying functions with exponential back-off.

The :class:`Retry` decorator can be used to retry functions that raise
exceptions using exponential backoff. Because a exponential sleep algorithm is
used, the retry is limited by a `deadline`. The deadline is the maxmimum amount
of time a method can block. This is used instead of total number of retries
because it is difficult to ascertain the amount of time a function can block
when using total number of retries and exponential backoff.

By default, this decorator will retry transient
API errors (see :func:`if_transient_error`). For example:

.. code-block:: python

    @retry.Retry()
    def call_flaky_rpc():
        return client.flaky_rpc()

    # Will retry flaky_rpc() if it raises transient API errors.
    result = call_flaky_rpc()

You can pass a custom predicate to retry on different exceptions, such as
waiting for an eventually consistent item to be available:

.. code-block:: python

    @retry.Retry(predicate=if_exception_type(exceptions.NotFound))
    def check_if_exists():
        return client.does_thing_exist()

    is_available = check_if_exists()

Some client library methods apply retry automatically. These methods can accept
a ``retry`` parameter that allows you to configure the behavior:

.. code-block:: python

    my_retry = retry.Retry(deadline=60)
    result = client.some_method(retry=my_retry)

    )unicode_literalsN)datetime_helpers)
exceptionsg      ?g      N@       @g      ^@c                     s    fdd}|S )a9  Creates a predicate to check if the exception is of a given type.

    Args:
        exception_types (Sequence[:func:`type`]): The exception types to check
            for.

    Returns:
        Callable[Exception]: A predicate that returns True if the provided
            exception is of the given type(s).
    c                    s
   t |  S )z/Bound predicate for checking an exception type.)
isinstance)	exceptionexception_types L/var/www/ideatree/venv/lib/python3.10/site-packages/google/api_core/retry.pyif_exception_type_predicateZ   s   
z6if_exception_type.<locals>.if_exception_type_predicater
   )r	   r   r
   r   r   if_exception_typeN   s   r   c                 c   s*    | }	 t td|d |V  || }q)a%  Generates sleep intervals based on the exponential back-off algorithm.

    This implements the `Truncated Exponential Back-off`_ algorithm.

    .. _Truncated Exponential Back-off:
        https://cloud.google.com/storage/docs/exponential-backoff

    Args:
        initial (float): The minimum amount of time to delay. This must
            be greater than 0.
        maximum (float): The maximum amount of time to delay.
        multiplier (float): The multiplier applied to the delay.

    Yields:
        float: successive sleep intervals.
    Tg        r   )minrandomuniform)initialmaximum
multiplierdelayr
   r
   r   exponential_sleep_generator}   s   r   c                 C   s   |durt  tj|d }nd}d}|D ]Y}z|  W   S  ty> } z||s* |}|dur4|| W Y d}~nd}~ww t  }	|dur`||	krUtd|||||	  }
t	|
|}t
d|| t| qtd)aF  Call a function and retry if it fails.

    This is the lowest-level retry helper. Generally, you'll use the
    higher-level retry helper :class:`Retry`.

    Args:
        target(Callable): The function to call and retry. This must be a
            nullary function - apply arguments with `functools.partial`.
        predicate (Callable[Exception]): A callable used to determine if an
            exception raised by the target should be considered retryable.
            It should return True to retry or False otherwise.
        sleep_generator (Iterable[float]): An infinite iterator that determines
            how long to sleep between retries.
        deadline (float): How long to keep retrying the target. The last sleep
            period is shortened as necessary, so that the last retry runs at
            ``deadline`` (and not considerably beyond it).
        on_error (Callable[Exception]): A function to call while processing a
            retryable exception.  Any error raised by this function will *not*
            be caught.

    Returns:
        Any: the return value of the target function.

    Raises:
        google.api_core.RetryError: If the deadline is exceeded while retrying.
        ValueError: If the sleep generator stops yielding values.
        Exception: If the target raises a method that isn't retryable.
    N)secondsz:Deadline of {:.1f}s exceeded while calling target functionz(Retrying due to {}, sleeping {:.1f}s ...z.Sleep generator stopped yielding sleep values.)r   utcnowdatetime	timedelta	Exceptionr   
RetryErrorformattotal_secondsr   _LOGGERdebugtimesleep
ValueError)target	predicatesleep_generatordeadlineon_errordeadline_datetimelast_excr!   excnowtime_to_deadliner
   r
   r   retry_target   sF   



r-   c                   @   s^   e Zd ZdZeeeeedfddZ	dddZ
edd Zd	d
 Zdd ZdddZdd ZdS )Retryam  Exponential retry decorator.

    This class is a decorator used to add exponential back-off retry behavior
    to an RPC call.

    Although the default behavior is to retry transient API errors, a
    different predicate can be provided to retry other exceptions.

    Args:
        predicate (Callable[Exception]): A callable that should return ``True``
            if the given exception is retryable.
        initial (float): The minimum amount of time to delay in seconds. This
            must be greater than 0.
        maximum (float): The maximum amount of time to delay in seconds.
        multiplier (float): The multiplier applied to the delay.
        deadline (float): How long to keep retrying in seconds. The last sleep
            period is shortened as necessary, so that the last retry runs at
            ``deadline`` (and not considerably beyond it).
    Nc                 C   s(   || _ || _|| _|| _|| _|| _d S N)
_predicate_initial_multiplier_maximum	_deadline	_on_error)selfr$   r   r   r   r&   r'   r
   r
   r   __init__   s   	
zRetry.__init__c                    s.   j durj t  fdd}|S )a  Wrap a callable with retry behavior.

        Args:
            func (Callable): The callable to add retry behavior to.
            on_error (Callable[Exception]): A function to call while processing
                a retryable exception. Any error raised by this function will
                *not* be caught.

        Returns:
            Callable: A callable that will invoke ``func`` with retry
                behavior.
        Nc                     sB   t j g| R i |}tjjjd}t|j|jdS )z0A wrapper that calls target function with retry.)r   )r'   )		functoolspartialr   r1   r3   r2   r-   r0   r4   )argskwargsr#   r%   funcr'   r6   r
   r   retry_wrapped_func  s   z*Retry.__call__.<locals>.retry_wrapped_func)r5   r8   wraps)r6   r=   r'   r>   r
   r<   r   __call__  s
   
zRetry.__call__c                 C   s   | j S r/   )r4   r6   r
   r
   r   r&   %  s   zRetry.deadlinec                 C   s   t | j| j| j| j|| jdS )zReturn a copy of this retry with the given deadline.

        Args:
            deadline (float): How long to keep retrying.

        Returns:
            Retry: A new retry instance with the given deadline.
        r$   r   r   r   r&   r'   )r.   r0   r1   r3   r2   r5   )r6   r&   r
   r
   r   with_deadline)  s   	zRetry.with_deadlinec                 C   s   t || j| j| j| j| jdS )a*  Return a copy of this retry with the given predicate.

        Args:
            predicate (Callable[Exception]): A callable that should return
                ``True`` if the given exception is retryable.

        Returns:
            Retry: A new retry instance with the given predicate.
        rB   )r.   r1   r3   r2   r4   r5   )r6   r$   r
   r
   r   with_predicate;  s   
zRetry.with_predicatec                 C   sD   t | j|dur	|n| j|dur|n| j|dur|n| j| j| jdS )a  Return a copy of this retry with the given delay options.

        Args:
            initial (float): The minimum amount of time to delay. This must
                be greater than 0.
            maximum (float): The maximum amount of time to delay.
            multiplier (float): The multiplier applied to the delay.

        Returns:
            Retry: A new retry instance with the given predicate.
        NrB   )r.   r0   r1   r3   r2   r4   r5   )r6   r   r   r   r
   r
   r   
with_delayN  s   zRetry.with_delayc                 C   s    d | j| j| j| j| j| jS )Nze<Retry predicate={}, initial={:.1f}, maximum={:.1f}, multiplier={:.1f}, deadline={:.1f}, on_error={}>)r   r0   r1   r3   r2   r4   r5   rA   r
   r
   r   __str__c  s   zRetry.__str__r/   )NNN)__name__
__module____qualname____doc__if_transient_error_DEFAULT_INITIAL_DELAY_DEFAULT_MAXIMUM_DELAY_DEFAULT_DELAY_MULTIPLIER_DEFAULT_DEADLINEr7   r@   propertyr&   rC   rD   rE   rF   r
   r
   r
   r   r.      s     

!

r.   r/   )"rJ   
__future__r   r   r8   loggingr   r    requests.exceptionsrequestsgoogle.api_corer   r   google.authauth_exceptions	getLoggerrG   r   rL   rM   rN   rO   r   InternalServerErrorTooManyRequestsServiceUnavailableConnectionErrorChunkedEncodingErrorTransportErrorrK   r   r-   objectr.   r
   r
   r
   r   <module>   s:   *

I