Snippets

Python Snippet: Retry Decorator with Exponential Backoff

By Mohd Baquir Qureshi
Python code on screen

When working with unreliable third-party APIs or unstable network connections, adding retry logic is essential to prevent your application from failing. Instead of writing try-except blocks in every function, you can use this clean, reusable decorator.

The Snippet


import time
import logging
from functools import wraps

def retry_with_backoff(retries=3, backoff_in_seconds=1, exceptions=(Exception,)):
    """
    Retry a function with exponential backoff.
    
    Args:
        retries (int): Maximum number of retry attempts
        backoff_in_seconds (int): Initial backoff duration in seconds
        exceptions (tuple): Exceptions to catch and retry upon
    """
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            attempt = 0
            while attempt <= retries:
                try:
                    return func(*args, **kwargs)
                except exceptions as e:
                    if attempt == retries:
                        logging.error(f"Function {func.__name__} failed after {retries} retries.")
                        raise e
                    
                    sleep_time = (backoff_in_seconds * 2 ** attempt)
                    logging.warning(f"Attempt {attempt+1} failed. Retrying in {sleep_time} seconds...")
                    time.sleep(sleep_time)
                    attempt += 1
        return wrapper
    return decorator

How to Use It

You can apply this decorator to any function that might fail due to a transient error, such as a database query or an HTTP request.


import requests

# Retries 5 times, starts with a 2-second delay (2s, 4s, 8s, 16s, 32s)
@retry_with_backoff(retries=5, backoff_in_seconds=2, exceptions=(requests.exceptions.RequestException,))
def fetch_external_data(url):
    response = requests.get(url, timeout=5)
    response.raise_for_status()
    return response.json()

# Usage
data = fetch_external_data("https://api.unstable-service.com/data")