Package: auto-retry
auto-retryEasy to use retry decorator.FeaturesNo external dependency (stdlib only).(Optionally) Preserve function signatures (pip install decorator).Original traceback, easy to debug.Installationpipinstallauto-retryAPIretry decoratordefretry(exceptions=Exception,tries=-1,delay=0,max_delay=None,backoff=1,jitter=0,logger=logging_logger):"""Return a retry decorator.:param exceptions: an exception or a tuple of exceptions to catch. default: Exception.:param tries: the maximum number of attempts. default: -1 (infinite).:param delay: initial delay between attempts. default: 0.:param max_delay: the maximum value of delay. default: None (no limit).:param backoff: multiplier applied to delay between attempts. default: 1 (no backoff).:param jitter: extra seconds added to delay between attempts. default: 0.fixed if a number, random if a range tuple (min, max):param logger: logger.warning(fmt, error, delay) will be called on failed attempts.default: retry.logging_logger. if None, logging is disabled."""Various retrying logic can be achieved by combination of arguments.Examplesfromretryimportretry@retry()defmake_trouble():'''Retry until succeed'''@retry(ZeroDivisionError,tries=3,delay=2)defmake_trouble():'''Retry on ZeroDivisionError, raise error after 3 attempts, sleep 2 seconds between attempts.'''@retry((ValueError,TypeError),delay=1,backoff=2)defmake_trouble():'''Retry on ValueError or TypeError, sleep 1, 2, 4, 8, ... seconds between attempts.'''@retry((ValueError,TypeError),delay=1,backoff=2,max_delay=4)defmake_trouble():'''Retry on ValueError or TypeError, sleep 1, 2, 4, 4, ... seconds between attempts.'''@retry(ValueError,delay=1,jitter=1)defmake_trouble():'''Retry on ValueError, sleep 1, 2, 3, 4, ... seconds between attempts.'''# If you enable logging, you can get warnings like 'ValueError, retrying in# 1 seconds'if__name__=='__main__':importlogginglogging.basicConfig()make_trouble()retry_calldefretry_call(f,fargs=None,fkwargs=None,exceptions=Exception,tries=-1,delay=0,max_delay=None,backoff=1,jitter=0,logger=logging_logger):"""Calls a function and re-executes it if it failed.:param f: the function to execute.:param fargs: the positional arguments of the function to execute.:param fkwargs: the named arguments of the function to execute.:param exceptions: an exception or a tuple of exceptions to catch. default: Exception.:param tries: the maximum number of attempts. default: -1 (infinite).:param delay: initial delay between attempts. default: 0.:param max_delay: the maximum value of delay. default: None (no limit).:param backoff: multiplier applied to delay between attempts. default: 1 (no backoff).:param jitter: extra seconds added to delay between attempts. default: 0.fixed if a number, random if a range tuple (min, max):param logger: logger.warning(fmt, error, delay) will be called on failed attempts.default: retry.logging_logger. if None, logging is disabled.:returns: the result of the f function."""This is very similar to the decorator, except that it takes a function and its arguments as parameters. The use case behind it is to be able to dynamically adjust the retry arguments.importrequestsfromretry.apiimportretry_calldefmake_trouble(service,info=None):ifnotinfo:info=''r=requests.get(service+info)returnr.textdefwhat_is_my_ip(approach=None):ifapproach=="optimistic":tries=1elifapproach=="conservative":tries=3else:# skepticaltries=-1result=retry_call(make_trouble,fargs=["http://ipinfo.io/"],fkwargs={"info":"ip"},tries=tries)print(result)what_is_my_ip("conservative")