tenacity - Retry Library#

Tenacity is a general-purpose retrying library to simplify the task of adding retry behavior to just about anything.

Exponential Backoff#

Wait 1 se before first retry, then wait 2, 4, 8 seconds before second, third, fourth retry. Stop if the third retry failed (we made 4 attempts in total).

 1# -*- coding: utf-8 -*-
 2
 3import random
 4from datetime import datetime
 5from tenacity import retry, wait_exponential, stop_after_attempt, RetryError
 6
 7
 8class Counter:
 9    def __init__(self):
10        self.i = 0
11
12
13counter = Counter()
14start = datetime.now()
15
16class TaskError(Exception):
17    pass
18
19
20@retry(
21    wait=wait_exponential(multiplier=1, exp_base=2, min=0, max=30),
22    stop=stop_after_attempt(4),
23)
24def run_task():
25    counter.i += 1
26    now = datetime.now()
27    elapsed = f"{(now - start).total_seconds():.4f}"
28    print(f"------ {counter.i} th, elapsed {elapsed} seconds ------")
29    if random.randint(1, 100) <= 100:
30        print("❌ Failed")
31        raise TaskError("random error")
32    else:
33        print("✅ Succeeded")
34
35try:
36    run_task()
37except RetryError as e:
38    print(f"raise RetryError, no more retry")
39    print(f"original error: {e.last_attempt.result()!r}")

Output:

------ 1 th, elapsed 0.0001 seconds ------
❌ Failed
------ 2 th, elapsed 1.0057 seconds ------
❌ Failed
------ 3 th, elapsed 3.0094 seconds ------
❌ Failed
------ 4 th, elapsed 7.0147 seconds ------
❌ Failed
raise RetryError, no more retry

Traceback (most recent call last):
  File "/Users/sanhehu/Documents/GitHub/learn_pylib-project/docs/source/tenacity/test_exponential_backoff.py", line 39, in <module>
    print(f"original error: {e.last_attempt.result()!r}")
  File "/Users/sanhehu/.pyenv/versions/3.8.13/lib/python3.8/concurrent/futures/_base.py", line 437, in result
    return self.__get_result()
  File "/Users/sanhehu/.pyenv/versions/3.8.13/lib/python3.8/concurrent/futures/_base.py", line 389, in __get_result
    raise self._exception
  File "/Users/sanhehu/Documents/GitHub/learn_pylib-project/.venv/lib/python3.8/site-packages/tenacity/__init__.py", line 382, in __call__
    result = fn(*args, **kwargs)
  File "/Users/sanhehu/Documents/GitHub/learn_pylib-project/docs/source/tenacity/test_exponential_backoff.py", line 31, in run_task
    raise TaskError("random error")
__main__.TaskError: random error

Process finished with exit code 1