Tenacity
========
.. image:: https://img.shields.io/pypi/v/tenacity.svg
    :target: https://pypi.python.org/pypi/tenacity

.. image:: https://circleci.com/gh/jd/tenacity.svg?style=svg
    :target: https://circleci.com/gh/jd/tenacity

.. image:: https://img.shields.io/endpoint.svg?url=https://api.mergify.com/badges/jd/tenacity&style=flat
   :target: https://mergify.io
   :alt: Mergify Status

Tenacity is an Apache 2.0 licensed general-purpose retrying library, written in
Python, to simplify the task of adding retry behavior to just about anything.
It originates from `a fork of retrying
<https://github.com/rholder/retrying/issues/65>`_ which is sadly no longer
`maintained <https://julien.danjou.info/python-tenacity/>`_. Tenacity isn't
api compatible with retrying but adds significant new functionality and
fixes a number of longstanding bugs.

The simplest use case is retrying a flaky function whenever an `Exception`
occurs until a value is returned.

.. testcode::

    import random
    from tenacity import retry

    @retry
    def do_something_unreliable():
        if random.randint(0, 10) > 1:
            raise IOError("Broken sauce, everything is hosed!!!111one")
        else:
            return "Awesome sauce!"

    print(do_something_unreliable())

.. testoutput::
   :hide:

   Awesome sauce!


.. toctree::
    :hidden:
    :maxdepth: 2

    changelog
    api


Features
--------

- Generic Decorator API
- Specify stop condition (i.e. limit by number of attempts)
- Specify wait condition (i.e. exponential backoff sleeping between attempts)
- Customize retrying on Exceptions
- Customize retrying on expected returned result
- Retry on coroutines
- Retry code block with context manager


Installation
------------

To install *tenacity*, simply:

.. code-block:: bash

    $ pip install tenacity


Examples
----------

Basic Retry
~~~~~~~~~~~

.. testsetup:: *

    import logging
    #
    # Note the following import is used for demonstration convenience only.
    # Production code should always explicitly import the names it needs.
    #
    from tenacity import *

    class MyException(Exception):
        pass

As you saw above, the default behavior is to retry forever without waiting when
an exception is raised.

.. testcode::

    @retry
    def never_gonna_give_you_up():
        print("Retry forever ignoring Exceptions, don't wait between retries")
        raise Exception

Stopping
~~~~~~~~

Let's be a little less persistent and set some boundaries, such as the number
of attempts before giving up.

.. testcode::

    @retry(stop=stop_after_attempt(7))
    def stop_after_7_attempts():
        print("Stopping after 7 attempts")
        raise Exception

We don't have all day, so let's set a boundary for how long we should be
retrying stuff.

.. testcode::

    @retry(stop=stop_after_delay(10))
    def stop_after_10_s():
        print("Stopping after 10 seconds")
        raise Exception

You can combine several stop conditions by using the `|` operator:

.. testcode::

    @retry(stop=(stop_after_delay(10) | stop_after_attempt(5)))
    def stop_after_10_s_or_5_retries():
        print("Stopping after 10 seconds or 5 retries")
        raise Exception

Waiting before retrying
~~~~~~~~~~~~~~~~~~~~~~~

Most things don't like to be polled as fast as possible, so let's just wait 2
seconds between retries.

.. testcode::

    @retry(wait=wait_fixed(2))
    def wait_2_s():
        print("Wait 2 second between retries")
        raise Exception

Some things perform best with a bit of randomness injected.

.. testcode::

    @retry(wait=wait_random(min=1, max=2))
    def wait_random_1_to_2_s():
        print("Randomly wait 1 to 2 seconds between retries")
        raise Exception

Then again, it's hard to beat exponential backoff when retrying distributed
services and other remote endpoints.

.. testcode::

    @retry(wait=wait_exponential(multiplier=1, min=4, max=10))
    def wait_exponential_1():
        print("Wait 2^x * 1 second between each retry starting with 4 seconds, then up to 10 seconds, then 10 seconds afterwards")
        raise Exception


Then again, it's also hard to beat combining fixed waits and jitter (to
help avoid thundering herds) when retrying distributed services and other
remote endpoints.

.. testcode::

    @retry(wait=wait_fixed(3) + wait_random(0, 2))
    def wait_fixed_jitter():
        print("Wait at least 3 seconds, and add up to 2 seconds of random delay")
        raise Exception

When multiple processes are in contention for a shared resource, exponentially
increasing jitter helps minimise collisions.

.. testcode::

    @retry(wait=wait_random_exponential(multiplier=1, max=60))
    def wait_exponential_jitter():
        print("Randomly wait up to 2^x * 1 seconds between each retry until the range reaches 60 seconds, then randomly up to 60 seconds afterwards")
        raise Exception


Sometimes it's necessary to build a chain of backoffs.

.. testcode::

    @retry(wait=wait_chain(*[wait_fixed(3) for i in range(3)] +
                           [wait_fixed(7) for i in range(2)] +
                           [wait_fixed(9)]))
    def wait_fixed_chained():
        print("Wait 3s for 3 attempts, 7s for the next 2 attempts and 9s for all attempts thereafter")
        raise Exception

Whether to retry
~~~~~~~~~~~~~~~~

We have a few options for dealing with retries that raise specific or general
exceptions, as in the cases here.

.. testcode::

    class ClientError(Exception):
        """Some type of client error."""

    @retry(retry=retry_if_exception_type(IOError))
    def might_io_error():
        print("Retry forever with no wait if an IOError occurs, raise any other errors")
        raise Exception

    @retry(retry=retry_if_not_exception_type(ClientError))
    def might_client_error():
        print("Retry forever with no wait if any error other than ClientError occurs. Immediately raise ClientError.")
        raise Exception

We can also use the result of the function to alter the behavior of retrying.

.. testcode::

    def is_none_p(value):
        """Return True if value is None"""
        return value is None

    @retry(retry=retry_if_result(is_none_p))
    def might_return_none():
        print("Retry with no wait if return value is None")

See also these methods:

.. testcode::

    retry_if_exception
    retry_if_exception_type
    retry_if_not_exception_type
    retry_unless_exception_type
    retry_if_result
    retry_if_not_result
    retry_if_exception_message
    retry_if_not_exception_message
    retry_any
    retry_all

We can also combine several conditions:

.. testcode::

    def is_none_p(value):
        """Return True if value is None"""
        return value is None

    @retry(retry=(retry_if_result(is_none_p) | retry_if_exception_type()))
    def might_return_none():
        print("Retry forever ignoring Exceptions with no wait if return value is None")

Any combination of stop, wait, etc. is also supported to give you the freedom
to mix and match.

It's also possible to retry explicitly at any time by raising the `TryAgain`
exception:

.. testcode::

   @retry
   def do_something():
       result = something_else()
       if result == 23:
          raise TryAgain

Error Handling
~~~~~~~~~~~~~~

Normally when your function fails its final time (and will not be retried again based on your settings),
a `RetryError` is raised. The exception your code encountered will be shown somewhere in the *middle*
of the stack trace.

If you would rather see the exception your code encountered at the *end* of the stack trace (where it
is most visible), you can set `reraise=True`.

.. testcode::

    @retry(reraise=True, stop=stop_after_attempt(3))
    def raise_my_exception():
        raise MyException("Fail")

    try:
        raise_my_exception()
    except MyException:
        # timed out retrying
        pass

Before and After Retry, and Logging
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It's possible to execute an action before any attempt of calling the function
by using the before callback function:

.. testcode::

    import logging
    import sys

    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)

    logger = logging.getLogger(__name__)

    @retry(stop=stop_after_attempt(3), before=before_log(logger, logging.DEBUG))
    def raise_my_exception():
        raise MyException("Fail")

In the same spirit, It's possible to execute after a call that failed:

.. testcode::

    import logging
    import sys

    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)

    logger = logging.getLogger(__name__)

    @retry(stop=stop_after_attempt(3), after=after_log(logger, logging.DEBUG))
    def raise_my_exception():
        raise MyException("Fail")

It's also possible to only log failures that are going to be retried. Normally
retries happen after a wait interval, so the keyword argument is called
``before_sleep``:

.. testcode::

    import logging
    import sys

    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)

    logger = logging.getLogger(__name__)

    @retry(stop=stop_after_attempt(3),
           before_sleep=before_sleep_log(logger, logging.DEBUG))
    def raise_my_exception():
        raise MyException("Fail")


Statistics
~~~~~~~~~~

You can access the statistics about the retry made over a function by using the
`retry` attribute attached to the function and its `statistics` attribute:

.. testcode::

    @retry(stop=stop_after_attempt(3))
    def raise_my_exception():
        raise MyException("Fail")

    try:
        raise_my_exception()
    except Exception:
        pass

    print(raise_my_exception.retry.statistics)

.. testoutput::
   :hide:

   ...

Custom Callbacks
~~~~~~~~~~~~~~~~

You can also define your own callbacks. The callback should accept one
parameter called ``retry_state`` that contains all information about current
retry invocation.

For example, you can call a custom callback function after all retries failed,
without raising an exception (or you can re-raise or do anything really)

.. testcode::

    def return_last_value(retry_state):
        """return the result of the last call attempt"""
        return retry_state.outcome.result()

    def is_false(value):
        """Return True if value is False"""
        return value is False

    # will return False after trying 3 times to get a different result
    @retry(stop=stop_after_attempt(3),
           retry_error_callback=return_last_value,
           retry=retry_if_result(is_false))
    def eventually_return_false():
        return False

RetryCallState
~~~~~~~~~~~~~~

``retry_state`` argument is an object of `RetryCallState` class:

.. autoclass:: tenacity.RetryCallState

   Constant attributes:

   .. autoattribute:: start_time(float)
      :annotation:

   .. autoattribute:: retry_object(BaseRetrying)
      :annotation:

   .. autoattribute:: fn(callable)
      :annotation:

   .. autoattribute:: args(tuple)
      :annotation:

   .. autoattribute:: kwargs(dict)
      :annotation:

   Variable attributes:

   .. autoattribute:: attempt_number(int)
      :annotation:

   .. autoattribute:: outcome(tenacity.Future or None)
      :annotation:

   .. autoattribute:: outcome_timestamp(float or None)
      :annotation:

   .. autoattribute:: idle_for(float)
      :annotation:

   .. autoattribute:: next_action(tenacity.RetryAction or None)
      :annotation:

Other Custom Callbacks
~~~~~~~~~~~~~~~~~~~~~~

It's also possible to define custom callbacks for other keyword arguments.

.. function:: my_stop(retry_state)

   :param RetryState retry_state: info about current retry invocation
   :return: whether or not retrying should stop
   :rtype: bool

.. function:: my_wait(retry_state)

   :param RetryState retry_state: info about current retry invocation
   :return: number of seconds to wait before next retry
   :rtype: float

.. function:: my_retry(retry_state)

   :param RetryState retry_state: info about current retry invocation
   :return: whether or not retrying should continue
   :rtype: bool

.. function:: my_before(retry_state)

   :param RetryState retry_state: info about current retry invocation

.. function:: my_after(retry_state)

   :param RetryState retry_state: info about current retry invocation

.. function:: my_before_sleep(retry_state)

   :param RetryState retry_state: info about current retry invocation

Here's an example with a custom ``before_sleep`` function:

.. testcode::

    import logging

    logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)

    logger = logging.getLogger(__name__)

    def my_before_sleep(retry_state):
        if retry_state.attempt_number < 1:
            loglevel = logging.INFO
        else:
            loglevel = logging.WARNING
        logger.log(
            loglevel, 'Retrying %s: attempt %s ended with: %s',
            retry_state.fn, retry_state.attempt_number, retry_state.outcome)

    @retry(stop=stop_after_attempt(3), before_sleep=my_before_sleep)
    def raise_my_exception():
        raise MyException("Fail")

    try:
        raise_my_exception()
    except RetryError:
        pass


Changing Arguments at Run Time
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can change the arguments of a retry decorator as needed when calling it by
using the `retry_with` function attached to the wrapped function:

.. testcode::

    @retry(stop=stop_after_attempt(3))
    def raise_my_exception():
        raise MyException("Fail")

    try:
        raise_my_exception.retry_with(stop=stop_after_attempt(4))()
    except Exception:
        pass

    print(raise_my_exception.retry.statistics)

.. testoutput::
   :hide:

   ...

If you want to use variables to set up the retry parameters, you don't have
to use the `retry` decorator - you can instead use `Retrying` directly:

.. testcode::

    def never_good_enough(arg1):
        raise Exception('Invalid argument: {}'.format(arg1))

    def try_never_good_enough(max_attempts=3):
        retryer = Retrying(stop=stop_after_attempt(max_attempts), reraise=True)
        retryer(never_good_enough, 'I really do try')

Retrying code block
~~~~~~~~~~~~~~~~~~~

Tenacity allows you to retry a code block without the need to wraps it in an
isolated function. This makes it easy to isolate failing block while sharing
context. The trick is to combine a for loop and a context manager.

.. testcode::

   from tenacity import Retrying, RetryError, stop_after_attempt

   try:
       for attempt in Retrying(stop=stop_after_attempt(3)):
           with attempt:
               raise Exception('My code is failing!')
   except RetryError:
       pass

You can configure every details of retry policy by configuring the Retrying
object.

With async code you can use AsyncRetrying.

.. testcode::

   from tenacity import AsyncRetrying, RetryError, stop_after_attempt

   async def function():
      try:
          async for attempt in AsyncRetrying(stop=stop_after_attempt(3)):
              with attempt:
                  raise Exception('My code is failing!')
      except RetryError:
          pass

In both cases, you may want to set the result to the attempt so it's available
in retry strategies like ``retry_if_result``. This can be done accessing the
``retry_state`` property:

.. testcode::

    from tenacity import AsyncRetrying, retry_if_result

    async def function():
       async for attempt in AsyncRetrying(retry=retry_if_result(lambda x: x < 3)):
           with attempt:
               result = 1  # Some complex calculation, function call, etc.
           if not attempt.retry_state.outcome.failed:
               attempt.retry_state.set_result(result)
       return result

Async and retry
~~~~~~~~~~~~~~~

Finally, ``retry`` works also on asyncio and Tornado (>= 4.5) coroutines.
Sleeps are done asynchronously too.

.. code-block:: python

    @retry
    async def my_async_function(loop):
        await loop.getaddrinfo('8.8.8.8', 53)

.. code-block:: python

    @retry
    @tornado.gen.coroutine
    def my_async_function(http_client, url):
        yield http_client.fetch(url)

You can even use alternative event loops such as `curio` or `Trio` by passing the correct sleep function:

.. code-block:: python

    @retry(sleep=trio.sleep)
    async def my_async_function(loop):
        await asks.get('https://example.org')

Contribute
----------

#. Check for open issues or open a fresh issue to start a discussion around a
   feature idea or a bug.
#. Fork `the repository`_ on GitHub to start making your changes to the
   **master** branch (or branch off of it).
#. Write a test which shows that the bug was fixed or that the feature works as
   expected.
#. Add a `changelog <#Changelogs>`_
#. Make the docs better (or more detailed, or more easier to read, or ...)

.. _`the repository`: https://github.com/jd/tenacity

Changelogs
~~~~~~~~~~

`reno`_ is used for managing changelogs. Take a look at their usage docs.

The doc generation will automatically compile the changelogs. You just need to add them.

.. code-block:: sh

    # Opens a template file in an editor
    tox -e reno -- new some-slug-for-my-change --edit

.. _`reno`: https://docs.openstack.org/reno/latest/user/usage.html
