Skip to content

Instantly share code, notes, and snippets.

@mlissner
Last active May 6, 2021 15:05
Show Gist options
  • Save mlissner/96d625acbb46d86408ff27eee665ccbf to your computer and use it in GitHub Desktop.
Save mlissner/96d625acbb46d86408ff27eee665ccbf to your computer and use it in GitHub Desktop.
A retry decorator to catch specific exceptions and retry the code, with exponential backoff
import time
from functools import wraps
from typing import Callable, Type
def retry(
ExceptionToCheck: Type[Exception],
tries: int = 4,
delay: float = 3,
backoff: float = 2,
) -> Callable:
"""Retry calling the decorated function using an exponential backoff.
http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
Use like:
@retry(SomeException, tries=10, delay=1, backoff=2)
def my_flakey_function():
if datetime.now().seconds % 10 == 0:
raise SomeException
:param ExceptionToCheck: the exception to check. may be a tuple of
exceptions to check
:type ExceptionToCheck: Exception or tuple
:param tries: number of times to try (not retry) before giving up
:type tries: int
:param delay: initial delay between retries in seconds
:type delay: int
:param backoff: backoff multiplier e.g. value of 2 will double the delay
each retry
:type backoff: int
"""
def deco_retry(f: Callable) -> Callable:
@wraps(f)
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay
while mtries > 1:
try:
return f(*args, **kwargs)
except ExceptionToCheck as e:
msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
print(msg)
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
return f(*args, **kwargs)
return f_retry # true decorator
return deco_retry
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment