The problem
You need to automatically retry operations that might fail temporarily (API calls, database connections).
The solution
import time
import functools
from typing import Tuple, Type
def retry(
max_attempts: int = 3,
delay: float = 1.0,
backoff: float = 2.0,
exceptions: Tuple[Type[Exception], ...] = (Exception,)
):
"""Retry decorator with exponential backoff."""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
current_delay = delay
last_exception = None
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except exceptions as e:
last_exception = e
if attempt < max_attempts - 1:
time.sleep(current_delay)
current_delay *= backoff
raise last_exception
return wrapper
return decoratorParameters
max_attemptsintMaximum number of retry attempts
delayfloatInitial delay between retries in seconds
backofffloatMultiplier for delay after each retry
exceptionstupleException types to catch and retry
Put it to work
import requests
@retry(max_attempts=3, delay=1, exceptions=(requests.RequestException,))
def fetch_data(url):
response = requests.get(url, timeout=5)
response.raise_for_status()
return response.json()
# Will retry up to 3 times on network errors
data = fetch_data('https://api.example.com/data')