# Tenacity — Robust Retry Library for Python > A general-purpose Python retrying library that simplifies adding retry behavior to any function or code block with configurable backoff strategies. ## Install Save in your project root: # Tenacity — Robust Retry Library for Python ## Quick Use ```bash pip install tenacity ``` ```python from tenacity import retry, stop_after_attempt, wait_exponential @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, max=10)) def call_api(): response = requests.get('https://api.example.com/data') response.raise_for_status() return response.json() ``` ## Introduction Tenacity is a Python library that provides a clean decorator-based API for retrying operations that may fail transiently. It is the actively maintained fork of the retrying library, offering more features and better composability for production retry logic. ## What Tenacity Does - Retries any callable with a simple @retry decorator - Supports exponential backoff, fixed delay, and random jitter wait strategies - Lets you stop retrying after N attempts, a time limit, or a custom condition - Filters which exceptions trigger a retry and which propagate immediately - Provides callbacks for logging, metrics, or side effects on each retry ## Architecture Overview Tenacity wraps the decorated function in a retry controller that catches specified exceptions and re-invokes the function according to the configured wait and stop policies. Each retry attempt is tracked in a RetryCallState object that carries attempt count, elapsed time, and the last result or exception. The library is fully synchronous by default but also supports asyncio, Tornado, and trio coroutines. ## Self-Hosting & Configuration - Install from PyPI with pip install tenacity - Apply the @retry decorator to any function or method - Combine stop, wait, and retry conditions using the | and & operators - Use before_sleep callbacks to log retry attempts - Access retry statistics via the function's retry.statistics attribute ## Key Features - Composable stop, wait, and retry predicates with operator overloading - Built-in support for asyncio, Tornado, and trio async frameworks - Reraise option to surface the original exception after all retries fail - Context manager form for retrying inline code blocks - No external dependencies beyond the Python standard library ## Comparison with Similar Tools - **urllib3 Retry** — HTTP-specific retry built into urllib3, not general-purpose - **backoff** — similar decorator approach but fewer composability options - **stamina** — newer retry library focused on production defaults and observability - **retrying** — the original library Tenacity forked from, now unmaintained - **Custom try/except loops** — manual retry code that Tenacity replaces with a one-liner ## FAQ **Q: Does Tenacity work with async functions?** A: Yes. Use the same @retry decorator on async def functions. Tenacity detects coroutines automatically and awaits them correctly. **Q: Can I retry on specific return values instead of exceptions?** A: Yes. Use retry_if_result with a predicate function to retry when the return value is unsatisfactory, such as an empty response. **Q: How do I log each retry attempt?** A: Pass a before_sleep callback like before_sleep_log(logger, logging.WARNING) to emit a log line before each retry wait. **Q: Is it thread-safe?** A: Yes. Each call gets its own RetryCallState, so concurrent threads retrying the same function do not interfere with each other. ## Sources - https://github.com/jd/tenacity - https://tenacity.readthedocs.io/ --- Source: https://tokrepo.com/en/workflows/asset-7f193a00 Author: AI Open Source