Pythonic way of retry running a function

exception, python

Solution

Define retry utility:

# Retry utility   
# set logging for `retry` channel
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('retry')

# Define Exception class for retry
class RetryException(Exception):
    u_str = "Exception ({}) raised after {} tries."

    def __init__(self, exp, max_retry):
        self.exp = exp
        self.max_retry = max_retry    
    def __unicode__(self):
        return self.u_str.format(self.exp, self.max_retry)
    def __str__(self):
        return self.__unicode__()

# Define retry util function
def retry_func(func, max_retry=10):
    """
    @param func: The function that needs to be retry
    @param max_retry: Maximum retry of `func` function, default is `10`
    @return: func
    @raise: RetryException if retries exceeded than max_retry
    """
    for retry in range(1, max_retry + 1):
        try:
            return func()
        except Exception, e:
            logger.info('Failed to call {}, in retry({}/{})'.format(func.func,
                                                           retry, max_retry))
    else:
        raise RetryException(e, max_retry)

Use it:

from functools import partial
import requests

def some_request(uri, post):
    req = requests.post(uri, post)
    return req

uri = 'http://someuri.com'
post = {'test': 'yes'}

try:
    retry_func(partial(some_request, uri, post), max_retry=3)
except RetryException, e:
    print(e)

Output:

INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): someuri.com
INFO:retry:Failed to call <function some_request at 0x7faaba2318c0>, in retry(1/3)
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): someuri.com
INFO:retry:Failed to call <function some_request at 0x7faaba2318c0>, in retry(2/3)
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): someuri.com
INFO:retry:Failed to call <function some_request at 0x7faaba2318c0>, in retry(3/3)
Exception (HTTPConnectionPool(host='someuri.com', port=80): Max retries exceeded with url: / (Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)) raised after 3 tries.

Problem

How a Python Professinal would retry running a function that will request a web service(the webservice sometimes fails) The function: ``` def some_request(uri): try: req = requests.post('http://someuri.com', {'test': 'yes'}) except Exception as e: return False return {'id': req.json()['value'], 'other': req.json()['other']} ``` You handle the retry with a while or other python idiom? Give me a clue on how to do it the right way.

Original source

Related problems