B
    uf%                 @   sx   d Z ddlmZ ddlZddlZddlmZ dZdZdZ	dZ
G dd	 d	eZG d
d deZdd ZG dd deZdS )a  Decorators for applying timeout arguments to functions.

These decorators are used to wrap API methods to apply either a
Deadline-dependent (recommended), constant (DEPRECATED) or exponential
(DEPRECATED) timeout argument.

For example, imagine an API method that can take a while to return results,
such as one that might block until a resource is ready:

.. code-block:: python

    def is_thing_ready(timeout=None):
        response = requests.get('https://example.com/is_thing_ready')
        response.raise_for_status()
        return response.json()

This module allows a function like this to be wrapped so that timeouts are
automatically determined, for example:

.. code-block:: python

    timeout_ = timeout.ExponentialTimeout()
    is_thing_ready_with_timeout = timeout_(is_thing_ready)

    for n in range(10):
        try:
            is_thing_ready_with_timeout({'example': 'data'})
        except:
            pass

In this example the first call to ``is_thing_ready`` will have a relatively
small timeout (like 1 second). If the resource is available and the request
completes quickly, the loop exits. But, if the resource isn't yet available
and the request times out, it'll be retried - this time with a larger timeout.

In the broader context these decorators are typically combined with
:mod:`google.api_core.retry` to implement API methods with a signature that
matches ``api_method(request, timeout=None, retry=None)``.
    )unicode_literalsN)datetime_helpersg      @g      >@g       @c               @   s0   e Zd ZdZdejfddZdd Zdd ZdS )	TimeToDeadlineTimeouta&  A decorator that decreases timeout set for an RPC based on how much time
    has left till its deadline. The deadline is calculated as
    ``now + initial_timeout`` when this decorator is first called for an rpc.

    In other words this decorator implements deadline semantics in terms of a
    sequence of decreasing timeouts t0 > t1 > t2 ... tn >= 0.

    Args:
        timeout (Optional[float]): the timeout (in seconds) to applied to the
            wrapped function. If `None`, the target function is expected to
            never timeout.
    Nc             C   s   || _ || _d S )N)_timeout_clock)selftimeoutclock r
   Y/home/ankuromar296_gmail_com/myenv/lib/python3.7/site-packages/google/api_core/timeout.py__init__T   s    zTimeToDeadlineTimeout.__init__c                s*       t fdd}|S )a  Apply the timeout decorator.

        Args:
            func (Callable): The function to apply the timeout argument to.
                This function must accept a timeout keyword argument.

        Returns:
            Callable: The wrapped function.
        c                 sP   j }|dk	rF  }|  dk r* }|  }tdj | |d< | |S )z#Wrapped function that adds timeout.NgMbP?r   r   )r   r   	timestampmax)argskwargsZremaining_timeoutZnow_timestampZtime_since_first_attempt)first_attempt_timestampfuncr   r
   r   func_with_timeoute   s    z9TimeToDeadlineTimeout.__call__.<locals>.func_with_timeout)r   r   	functoolswraps)r   r   r   r
   )r   r   r   r   __call__X   s    zTimeToDeadlineTimeout.__call__c             C   s   d | jS )Nz&<TimeToDeadlineTimeout timeout={:.1f}>)formatr   )r   r
   r
   r   __str__|   s    zTimeToDeadlineTimeout.__str__)	__name__
__module____qualname____doc__r   utcnowr   r   r   r
   r
   r
   r   r   F   s   $r   c               @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
ConstantTimeouta  A decorator that adds a constant timeout argument.

    DEPRECATED: use ``TimeToDeadlineTimeout`` instead.

    This is effectively equivalent to
    ``functools.partial(func, timeout=timeout)``.

    Args:
        timeout (Optional[float]): the timeout (in seconds) to applied to the
            wrapped function. If `None`, the target function is expected to
            never timeout.
    Nc             C   s
   || _ d S )N)r   )r   r   r
   r
   r   r      s    zConstantTimeout.__init__c                s   t   fdd}|S )a  Apply the timeout decorator.

        Args:
            func (Callable): The function to apply the timeout argument to.
                This function must accept a timeout keyword argument.

        Returns:
            Callable: The wrapped function.
        c                 s   j |d<  | |S )z#Wrapped function that adds timeout.r   )r   )r   r   )r   r   r
   r   r      s    
z3ConstantTimeout.__call__.<locals>.func_with_timeout)r   r   )r   r   r   r
   )r   r   r   r      s    zConstantTimeout.__call__c             C   s   d | jS )Nz <ConstantTimeout timeout={:.1f}>)r   r   )r   r
   r
   r   r      s    zConstantTimeout.__str__)N)r   r   r   r   r   r   r   r
   r
   r
   r   r      s   
r   c             c   s\   |dk	rt  tj|d }ntjj}| }x,t  }t||t|| jV  || }q,W dS )aV  A generator that yields exponential timeout values.

    Args:
        initial (float): The initial timeout.
        maximum (float): The maximum timeout.
        multiplier (float): The multiplier applied to the timeout.
        deadline (float): The overall deadline across all invocations.

    Yields:
        float: A timeout value.
    N)seconds)r   r   datetime	timedeltar   minfloatr   )initialmaximum
multiplierdeadlineZdeadline_datetimer   nowr
   r
   r   _exponential_timeout_generator   s    
r)   c               @   s:   e Zd ZdZeeeefddZdd Z	dd Z
dd	 Zd
S )ExponentialTimeoutaT  A decorator that adds an exponentially increasing timeout argument.

    DEPRECATED: the concept of incrementing timeout exponentially has been
    deprecated. Use ``TimeToDeadlineTimeout`` instead.

    This is useful if a function is called multiple times. Each time the
    function is called this decorator will calculate a new timeout parameter
    based on the the number of times the function has been called.

    For example

    .. code-block:: python

    Args:
        initial (float): The initial timeout to pass.
        maximum (float): The maximum timeout for any one call.
        multiplier (float): The multiplier applied to the timeout for each
            invocation.
        deadline (Optional[float]): The overall deadline across all
            invocations. This is used to prevent a very large calculated
            timeout from pushing the overall execution time over the deadline.
            This is especially useful in conjunction with
            :mod:`google.api_core.retry`. If ``None``, the timeouts will not
            be adjusted to accommodate an overall deadline.
    c             C   s   || _ || _|| _|| _d S )N)_initial_maximum_multiplier	_deadline)r   r$   r%   r&   r'   r
   r
   r   r      s    zExponentialTimeout.__init__c             C   s   t | j| j| j|dS )zReturn a copy of this timeout with the given deadline.

        Args:
            deadline (float): The overall deadline across all invocations.

        Returns:
            ExponentialTimeout: A new instance with the given deadline.
        )r$   r%   r&   r'   )r*   r+   r,   r-   )r   r'   r
   r
   r   with_deadline   s
    	z ExponentialTimeout.with_deadlinec                s2   t | j| j| j| jt  fdd}|S )a  Apply the timeout decorator.

        Args:
            func (Callable): The function to apply the timeout argument to.
                This function must accept a timeout keyword argument.

        Returns:
            Callable: The wrapped function.
        c                 s   t |d<  | |S )z#Wrapped function that adds timeout.r   )next)r   r   )r   timeoutsr
   r   r     s    z6ExponentialTimeout.__call__.<locals>.func_with_timeout)r)   r+   r,   r-   r.   r   r   )r   r   r   r
   )r   r1   r   r      s    
zExponentialTimeout.__call__c             C   s   d | j| j| j| jS )NzW<ExponentialTimeout initial={:.1f}, maximum={:.1f}, multiplier={:.1f}, deadline={:.1f}>)r   r+   r,   r-   r.   )r   r
   r
   r   r     s    zExponentialTimeout.__str__N)r   r   r   r   _DEFAULT_INITIAL_TIMEOUT_DEFAULT_MAXIMUM_TIMEOUT_DEFAULT_TIMEOUT_MULTIPLIER_DEFAULT_DEADLINEr   r/   r   r   r
   r
   r
   r   r*      s   r*   )r   
__future__r   r    r   Zgoogle.api_corer   r2   r3   r4   r5   objectr   r   r)   r*   r
   r
   r
   r   <module>5   s   :(!