tenacity - Retry Library#
Tenacity is a general-purpose retrying library to simplify the task of adding retry behavior to just about anything.
GitHub: https://github.com/jd/tenacity
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