8,818
stars
+0+1+17
403
forks
46
watchers
342
prs
296
issues
12
releases
–
discussions
README
Tenacity
========
.. image:: https://img.shields.io/pypi/v/tenacity.svg
:target: https://pypi.org/project/tenacity
.. image:: https://img.shields.io/pypi/pyversions/tenacity.svg
:target: https://pypi.org/project/tenacity
.. image:: https://github.com/jd/tenacity/actions/workflows/ci.yaml/badge.svg?branch=main
:target: https://github.com/jd/tenacity/actions/workflows/ci.yaml
.. image:: https://img.shields.io/endpoint.svg?url=https://api.mergify.com/badges/jd/tenacity&style=flat
:target: https://mergify.io
:alt: Mergify Status
Please refer to the tenacity documentation _ for a better experience.
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
_ which is sadly no longer
maintained _. 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():