
    j	i'(                         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	e          Z G d
 de          Zd Z G 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                   4    e Zd ZdZdej        fdZd Z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                 "    || _         || _        d S N)_timeout_clock)selftimeoutclocks      O/srv/django_bis/venv311/lib/python3.11/site-packages/google/api_core/timeout.py__init__zTimeToDeadlineTimeout.__init__T   s        c                                                                                        t          j                   fd            }|S )  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                      j         R                                                                }|z
  dk     r}|z
  }j         |z
  }|dk     rj         }||d<    | i |S )#Wrapped function that adds timeout.NgMbP?   r   )r	   r
   	timestamp)argskwargsnow_timestamptime_since_first_attemptremaining_timeoutfirst_attempt_timestampfuncr   s        r   func_with_timeoutz9TimeToDeadlineTimeout.__call__.<locals>.func_with_timeoute   s     }( $ 7 7 9 9
 !#::UBB$;M+8;R+R($(M4L$L! %q(((,%$5y!4((((r   )r
   r   	functoolswraps)r   r   r   r   s   `` @r   __call__zTimeToDeadlineTimeout.__call__X   sa     #'++--"9"9";";				) 	) 	) 	) 	) 	) 
		)< ! r   c                 6    d                     | j                  S )Nz&<TimeToDeadlineTimeout timeout={:.1f}>formatr	   r   s    r   __str__zTimeToDeadlineTimeout.__str__   s    7>>t}MMMr   )	__name__
__module____qualname____doc__r   utcnowr   r!   r&    r   r   r   r   F   sa           $+;+B    ,! ,! ,!\N N N N Nr   r   c                   &    e Zd ZdZddZd Z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                     || _         d S r   r	   )r   r   s     r   r   zConstantTimeout.__init__   s    r   c                 J     t          j                   fd            }|S )r   c                  (    j         |d<    | i |S r   r   r0   )r   r   r   r   s     r   r   z3ConstantTimeout.__call__.<locals>.func_with_timeout   s&     !%F94((((r   )r   r    )r   r   r   s   `` r   r!   zConstantTimeout.__call__   sA     
			) 	) 	) 	) 	) 
		)
 ! r   c                 6    d                     | j                  S )Nz <ConstantTimeout timeout={:.1f}>r#   r%   s    r   r&   zConstantTimeout.__str__   s    188GGGr   r   )r'   r(   r)   r*   r   r!   r&   r,   r   r   r.   r.      sU                ! ! !&H H H H Hr   r.   c              #     K   |*t          j                    t          j        |          z   }nt          j        j        }| }	 t          j                    }t          ||t          ||z
  j                            V  ||z  }A)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	timedeltamaxminfloatr6   )initialmaximum
multiplierdeadlinedeadline_datetimer   nows          r   _exponential_timeout_generatorrB      s       ,3558J9
 9
 9
 
 %-1G
'%''$s*344
 
 	
 	
 	
 J&
'r   c                   4    e Zd ZdZeeeefdZd Z	d Z
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                 >    || _         || _        || _        || _        d S r   )_initial_maximum_multiplier	_deadline)r   r<   r=   r>   r?   s        r   r   zExponentialTimeout.__init__   s%      %!r   c                 F    t          | j        | j        | j        |          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?   )rD   rF   rG   rH   )r   r?   s     r   with_deadlinez ExponentialTimeout.with_deadline   s.     "MM'	
 
 
 	
r   c                     t          | j        | j        | j        | j                  t          j                  fd            }|S )r   c                  8    t                    |d<    | i |S r3   )next)r   r   r   timeoutss     r   r   z6ExponentialTimeout.__call__.<locals>.func_with_timeout  s*     !%XF94((((r   )rB   rF   rG   rH   rI   r   r    )r   r   r   rO   s    ` @r   r!   zExponentialTimeout.__call__
  sd     2M4=$*:DN
 
 
			) 	) 	) 	) 	) 
		)
 ! r   c                 Z    d                     | j        | j        | j        | j                  S )NzW<ExponentialTimeout initial={:.1f}, maximum={:.1f}, multiplier={:.1f}, deadline={:.1f}>)r$   rF   rG   rH   rI   r%   s    r   r&   zExponentialTimeout.__str__   s-    228&t}d.>3 3	
r   N)r'   r(   r)   r*   _DEFAULT_INITIAL_TIMEOUT_DEFAULT_MAXIMUM_TIMEOUT_DEFAULT_TIMEOUT_MULTIPLIER_DEFAULT_DEADLINEr   rK   r!   r&   r,   r   r   rD   rD      sm         8 )(."
" 
" 
" 
"
 
 
 ! ! !,
 
 
 
 
r   rD   )r*   
__future__r   r7   r   google.api_corer   rQ   rR   rS   rT   objectr   r.   rB   rD   r,   r   r   <module>rX      s!  & &P ( ' ' ' ' '      , , , , , ,  !   AN AN AN AN ANF AN AN ANH%H %H %H %H %Hf %H %H %HP' ' 'BS
 S
 S
 S
 S
 S
 S
 S
 S
 S
r   