Retry mechanism¶
If your code depends on external factors (e.g. the availability of web services or the network connection) you may want to retry in case of failures.
Demo scenario
The code on this page uses the following demo scenario: A list of numbers is iterated and used as denominators. If the number is 0 (and a ZeroDivisionError is raised) the code retries up to three times (in reality you would try to fix the root cause).
For loop¶
import time
attempts_max = 3
wait_between = 2.0
denominator = [1, 2, 0, 3]
for d in denominator:
for _ in range(attempts_max):
try:
# Execute logic
print(f'1/{d} = {1 / d}')
except ZeroDivisionError:
# Logic failed (take neccesary steps before retry)
time.sleep(wait_between)
print('retry')
else:
# Logic successful
break
else:
# Max. number of attempts failed
raise RuntimeError('max number of attempts failed')
While loop¶
import time
attempts_max = 3
wait_between = 2.0
denominator = [1, 2, 0, 3]
def retry_while_loop():
i = 0
attempt_count = 0
while i < len(denominator):
d = denominator[i]
try:
# Execute logic
print(f'1/{d} = {1 / d}')
except ZeroDivisionError:
if attempt_count >= attempts_max:
# Max. number of attempts failed
raise RuntimeError('max number of attempts failed')
attempt_count += 1
# Logic failed (take neccesary steps before retry)
time.sleep(wait_between)
print('retry')
continue
i += 1
Function decorator¶
import functools
import time
def retry(num_tries: int, wait_between: float):
def decorator_retry(func):
@functools.wraps(func)
def wrapper_retry(*args, **kwargs):
for _ in range(num_tries-1):
try:
return func(*args, **kwargs, retry_error=RetryError)
except ZeroDivisionError:
# Logic failed (take neccesary steps before retry)
time.sleep(wait_between)
# Last try.
return func(*args, **kwargs)
return wrapper_retry
return decorator_retry
@retry(num_tries=3, wait_between=2.0)
def retry_decorated():
denominator = [1, 2, 0, 3]
for d in denominator:
print(f'1/{d} = {1 / d}')