Skip to content

Instantly share code, notes, and snippets.

@inirudebwoy
Last active July 22, 2016 14:25
Show Gist options
  • Save inirudebwoy/2a33eb8a9cec464bff5b72540bc376db to your computer and use it in GitHub Desktop.
Save inirudebwoy/2a33eb8a9cec464bff5b72540bc376db to your computer and use it in GitHub Desktop.
Decorator retrying connection with the callback on failure
def retry(retries=3, callback_on_failure=None):
"""Retry requests method and run callback on failure
Decorator will retry the decorated function for specified number of times,
default is 3. If there is a callback passed, it will be called before
calling the decorated function again. Callback allows to perform cleanups,
clear the credentials, etc.
Decorator will only work with functions that return requests.Request
object, if decorated method returns other object result is returned with
out retrying.
Example:
def callback(result, exc):
if result.failed:
print('Cleaning up')
...
@retry(retries=2, callback_on_failure=callback)
def grab_data_from_external_source():
return requests.get('https://i.like.chorizo.es')
If decorated function fails callback will be called before retrying.
:param retries: number of retries of decorated function (Default value = 3)
:type retries: int
:param callback_on_failure: callback function to run on failure of
decorated function (Default value = None)
:type callback_on_failure: func
"""
def decorate(func):
@wraps(func)
def wrapper(*args, **kwargs):
mretries = retries
while mretries > 0:
result = func(*args, **kwargs)
try:
result.raise_for_status()
except requests.HTTPError as exc:
logger.info(
'Retrying function call "{0}"'.format(func.func_name))
logger.exception('HTTPError raised')
try:
logger.debug('Calling callback function.')
callback_on_failure(result, exc)
except TypeError:
# no callback, silence it
pass
except Exception as exc:
# catching every error raised by callback
logger.exception(
'Callback "{0}" raised an exception.'.format(
callback_on_failure.func_name))
mretries -= 1
except AttributeError:
logger.info('Result is not requests.Request type.')
return result
return result
return wrapper
return decorate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment