Package: aioretry
aioretryAsyncio retry utility for Python 3.7+Upgrade guideInstall$pipinstallaioretryUsageimportasynciofromtypingimport(Tuple)fromaioretryimport(retry,# Tuple[bool, Union[int, float]]RetryPolicyStrategy,RetryInfo)# This example shows the usage with python typingsdefretry_policy(info:RetryInfo)->RetryPolicyStrategy:"""- It will always retry until succeeded- If fails for the first time, it will retry immediately,- If it fails again,aioretry will perform a 100ms delay before the second retry,200ms delay before the 3rd retry,the 4th retry immediately,100ms delay before the 5th retry,etc..."""returnFalse,(info.fails-1)%3*0.1@retry(retry_policy)asyncdefconnect_to_server():# connec to server...asyncio.run(connect_to_server())Use as class instance method decoratorWe could also useretryas a decorator for instance methodclassClient:@retry(retry_policy)asyncdefconnect(self):awaitself._connect()asyncio.run(Client().connect())Use instance method as retry policyretry_policycould be the method name of the class ifretryis used as a decorator for instance method.classClientWithConfigurableRetryPolicy(Client):def__init__(self,max_retries:int=3):self._max_retries=max_retriesdef_retry_policy(self,info:RetryInfo)->RetryPolicyStrategy:returninfo.fails>self._max_retries,info.fails*0.1# Then aioretry will use `self._retry_policy` as the retry policy.# And by using a str as the parameter `retry_policy`,# the decorator must be used for instance methods@retry('_retry_policy')asyncdefconnect(self):awaitself._connect()asyncio.run(ClientWithConfigurableRetryPolicy(10).connect())Register anbefore_retrycallbackWe could also register anbefore_retrycallback which will be executed after every failure of the target function if the corresponding retry is not abandoned.classClientTrackableFailures(ClientWithConfigurableRetryPolicy):# `before_retry` could either be a sync function or an async functionasyncdef_before_retry(self,info:RetryInfo)->None:awaitself._send_failure_log(info.exception,info.fails)@retry(retry_policy='_retry_policy',# Similar to `retry_policy`,# `before_retry` could either be a Callable or a strbefore_retry='_before_retry')asyncdefconnect(self):awaitself._connect()Only retry for certain types of exceptionsdefretry_policy(info:RetryInfo)->RetryPolicyStrategy:ifisinstance(info.exception,(KeyError,ValueError)):# If it raises a KeyError or a ValueError, it will not retry.returnTrue,0# Otherwise, retry immediatelyreturnFalse,0@retry(retry_policy)asyncdeffoo():# do something that might raise KeyError, ValueError or RuntimeError...APIsretry(retry_policy, before_retry)(fn)fnCallable[[...], Awaitable]the function to be wrapped. The function should be an async function or normal function returns an awaitable.retry_policyUnion[str, RetryPolicy]before_retry?Optional[Union[str, Callable[[RetryInfo], Optional[Awaitable]]]]If specified,before_retryis called after each failure offnand before the corresponding retry. If the retry is abandoned,before_retrywill not be executed.Returns a wrapped function which accepts the same arguments asfnand returns anAwaitable.RetryPolicyRetryPolicy=Callable[[RetryInfo],Tuple[bool,Union[float,int]]]Retry policy is used to determine what to do next after thefnfails to do some certain thing.abandon,delay=retry_policy(info)infoRetryInfoinfo.failsintis the counter number of how many times functionfnperforms as a failure. Iffnfails for the first time, thenfailswill be1.info.exceptionExceptionis the exception thatfnraised.info.sincedatetimeis the datetime when the first failure happens.IfabandonisTrue, then aioretry will give up the retry and raise the exception directly, otherwise aioretry will sleepdelayseconds (asyncio.sleep(delay)) before the next retry.defretry_policy(info:RetryInfo):ifisinstance(info.exception,KeyError):# Just raise exceptions of type KeyErrorreturnTrue,0returnFalse,info.fails*0.1Python typingsfromaioretryimport(# The type of retry_policy functionRetryPolicy,# The type of the return value of retry_policy functionRetryPolicyStrategy,# The type of before_retry functionBeforeRetry,RetryInfo)Upgrade guideSince5.0.0, aioretry introducesRetryInfoas the only parameter ofretry_policyorbefore_retry2.x -> 5.x2.xdefretry_policy(fails:int):"""A policy that gives no chances to retry"""returnTrue,0.1*fails5.xdefretry_policy(info:RetryInfo):returnTrue,0.1*info.fails3.x -> 5.x3.xdefbefore_retry(e:Exception,fails:int):...5.x# Change the sequence of the parametersdefbefore_retry(info:RetryInfo):info.exceptioninfo.fails...4.x -> 5.xSince5.0.0, bothretry_policyandbefore_retryhave only one parameter of typeRetryInforespectively.LicenseMIT