Retry decorator with backoff

Python
import functools
import random
import time


def retry(times=3, base_delay=0.5, exceptions=(Exception,)):
    """Retry a function with exponential backoff and jitter."""
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(1, times + 1):
                try:
                    return func(*args, **kwargs)
                except exceptions:
                    if attempt == times:
                        raise
                    delay = base_delay * 2 ** (attempt - 1)
                    time.sleep(delay + random.uniform(0, delay / 2))
        return wrapper
    return decorator


@retry(times=4)
def fetch_price(symbol: str) -> float:
    ...