💡 Python QuickBits — 🔄 Retry Logic Decorator
Posted On: October 8, 2025
Description:
Transient failures are common — API calls might timeout, or I/O operations may fail.
Instead of crashing, it’s better to retry automatically a few times before giving up.
With a simple decorator, you can add resilience to any function.
📝 The Retry Decorator
import functools
import time
def retry(max_attempts=3, delay=1):
"""
Decorator that retries a function if it raises an Exception.
Args:
max_attempts: number of total attempts (default 3)
delay: delay in seconds between retries
"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"[Attempt {attempt}] Failed with {e}")
if attempt < max_attempts:
time.sleep(delay) # wait before retrying
else:
raise # re-raise last error
return wrapper
return decorator
This decorator:
- Tries the function up to max_attempts.
- Waits delay seconds between attempts.
- Raises the last exception if all attempts fail.
🔄 Example: Flaky Task
Here’s a simulated function that randomly fails, wrapped with @retry:
import random
@retry(max_attempts=5, delay=0.5)
def flaky_task():
"""Simulate a flaky task that succeeds randomly."""
if random.random() < 0.7: # 70% chance of failure
raise ValueError("Random failure")
return "Success!"
print("Running flaky_task with retry logic...")
print("Result:", flaky_task())
Running this might show several failed attempts before success.
✅ Key Points
- ✅ Add resilience to unreliable operations.
- ✅ Pure standard library, no dependencies.
- ✅ Adjustable retries and delays.
- 🐍 Perfect for API calls, DB queries, file operations.
Code Snippet:
import functools # to preserve metadata when writing decorators
import time # to add delays between retries
import random # to simulate flaky behavior
def retry(max_attempts=3, delay=1):
"""
Decorator that retries a function if it raises an Exception.
Args:
max_attempts: number of total attempts (default 3)
delay: delay in seconds between retries
"""
def decorator(func):
@functools.wraps(func) # preserve function metadata
def wrapper(*args, **kwargs):
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs) # call the original function
except Exception as e:
print(f"[Attempt {attempt}] Failed with {e}")
if attempt < max_attempts: # if not last attempt
time.sleep(delay) # wait before retrying
else:
raise # re-raise last exception
return wrapper
return decorator
@retry(max_attempts=5, delay=0.5)
def flaky_task():
"""Simulate a flaky task that succeeds randomly."""
if random.random() < 0.7: # 70% chance to fail
raise ValueError("Random failure")
return "Success!"
print("Running flaky_task with retry logic...")
print("Result:", flaky_task())
Link copied!
Comments
Add Your Comment
Comment Added!
No comments yet. Be the first to comment!