Dowemo
0 0 0 0

Python simple retry module

Background

我们经常遇到一个场景,就是如果操作失败则需要多次重试某些操作,这种情况下,如果想优雅的实现功能,又不关心重试逻辑,则可以学习该模块

Install

  • pip install retry

Introduction to the api

retry decorator

defretry(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.
"""

The retry parameter introduction

  • No arguments
from retry import retry@retry()defmake_trouble():'''Retry until succeed'''print ('retrying...')
 raiseif __name__ == '__main__':
 make_trouble()# 输出: 一直重试,直到运行成功retrying...
retrying...
retrying...
retrying...
retrying...
retrying...
  • Exception parameter, default exception, captures only the exceptions that are retry and can be tuples
@retry(ZeroDivisionError, tries=3, delay=2)defmake_trouble():'''Retry on ZeroDivisionError, raise error after 3 attempts, sleep 2 seconds between attempts.'''print'aaa' a = 1/0if __name__ == '__main__':
 make_trouble()
输出:
aaa
aaa
Traceback (most recent call last):
 File "E:/WORKSPACE/document/document/test/1.py", line 20, in <module>
 make_trouble()
 File "<decorator-gen-2>", line 2, in make_trouble
 File "D:python27WinPython-64bit-2.7.10.3python-2.7.10.amd64libsite-packagesretryapi.py", line 74, in retry_decorator
 logger)
 File "D:python27WinPython-64bit-2.7.10.3python-2.7.10.amd64libsite-packagesretryapi.py", line 33, in __retry_internal
 return f()
 File "E:/WORKSPACE/document/document/test/1.py", line 16, in make_trouble
 a = 1/0ZeroDivisionError: integer division or modulo by zero
aaa
  • A backoff parameter, an attempt interval, and a multiple increase
import time@retry((ValueError, TypeError), delay=1, backoff=2)defmake_trouble():'''Retry on ValueError or TypeError, sleep 1, 2, 4, 8,.. . seconds between attempts.'''print (1, int(time.time()))
 raise ValueError('a')if __name__ == '__main__':
 make_trouble()
输出:
(1, 1504107288)
(1, 1504107289)
(1, 1504107291)
(1, 1504107295)
(1, 1504107303)
(1, 1504107319)
(1, 1504107351)
  • When max_delay specifies the maximum interval, the sleep time takes the max delay as the rule when the sleep time triggered by the backoff parameter is greater than max delay
import time@retry((ValueError, TypeError), delay=1, backoff=2, max_delay=8)defmake_trouble():'''Retry on ValueError or TypeError, sleep 1, 2, 4, 4,.. . seconds between attempts.'''print (1, int(time.time()))
 raise ValueError('aa')if __name__ == '__main__':
 make_trouble()
输出:
(1, 1504107496)
(1, 1504107497)
(1, 1504107499)
(1, 1504107503)
(1, 1504107511)
(1, 1504107519)
(1, 1504107527)
(1, 1504107535)
  • Jitter,, and logs
import time@retry(ValueError, delay=1, jitter=1)defmake_trouble():'''Retry on ValueError, sleep 1, 2, 3, 4,.. . seconds between attempts.'''print (1, int(time.time()))
 raise ValueError('e')if __name__ == '__main__':
 import logging
 logging.basicConfig()
 make_trouble()
输出:
WARNING:retry.api:e, retrying in1 seconds...
(1, 1504107644)
WARNING:retry.api:e, retrying in2 seconds...
(1, 1504107645)
WARNING:retry.api:e, retrying in3 seconds...
(1, 1504107647)
WARNING:retry.api:e, retrying in4 seconds...
(1, 1504107650)
WARNING:retry.api:e, retrying in5 seconds...
(1, 1504107654)
WARNING:retry.api:e, retrying in6 seconds...
(1, 1504107659)
(1, 1504107665)
WARNING:retry.api:e, retrying in7 seconds...
(1, 1504107672)
WARNING:retry.api:e, retrying in8 seconds...

Retry_call

Def retry_call ( f, fargs = none, fkwargs = none, exception = exception, tries = -1, delay = 0, max_delay = none, backoff = 1
Jitter = 0,
Logger = logging_logger:
""""""
Call 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.
"""

Examples

import requestsfrom retry.api import retry_calldefmake_trouble(service, info=None):ifnot info:
 info = ''print ('retry..., service: {}, info: {}'.format(service, info))
 r = requests.get(service + info)
 print r.text
 raise Exception('info')defwhat_is_my_ip(approach=None):if approach == "optimistic":
 tries = 1elif approach == "conservative":
 tries = 3else:
 # skeptical tries = -1 result = retry_call(make_trouble, fargs=["http://ipinfo.io/"], fkwargs={"info": "ip"}, tries=tries)
 print(result)if __name__ == '__main__':
 import logging
 logging.basicConfig()
 what_is_my_ip("conservative")
输出:
retry..., service: http://ipinfo.io/, info: ip118.113.1.255retry..., service: http://ipinfo.io/, info: ip
WARNING:retry.api:info, retrying in0 seconds...
WARNING:retry.api:info, retrying in0 seconds...118.113.1.255retry..., service: http://ipinfo.io/, info: ip
Traceback (most recent call last):
 File "E:/WORKSPACE/document/document/test/1.py", line 74, in <module>
 what_is_my_ip("conservative")
 File "E:/WORKSPACE/document/document/test/1.py", line 66, in what_is_my_ip
 result = retry_call(make_trouble, fargs=["http://ipinfo.io/"], fkwargs={"info": "ip"}, tries=tries)
 File "D:python27WinPython-64bit-2.7.10.3python-2.7.10.amd64libsite-packagesretryapi.py", line 101, in retry_call
 return __retry_internal(partial(f, *args, **kwargs), exceptions, tries, delay, max_delay, backoff, jitter, logger)
 File "D:python27WinPython-64bit-2.7.10.3python-2.7.10.amd64libsite-packagesretryapi.py", line 33, in __retry_internal
 return f()
 File "E:/WORKSPACE/document/document/test/1.py", line 54, in make_trouble
 raise Exception('info')
Exception: info118.113.1.255

Other paramete & with retry decorator
Official https://pypi. Python. org/pypi/retry.




Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs