In this post , we will be discussing about Retry decorator and how to use it in python.
Generally , we might have encountered many scenarios where we want to execute a piece of code until we get expected result or we may need to wait for the some operation should complete before proceeding further.
Before directly going to the implementation , I will explain a simple use case where I had to use retry decorator.
The use case is , there is an API with following endpoints:-
1.api/getData
2.api/status
3.api/data
api/getData , returns “id” instead of directly returning data for every request made(has some input parameters).
api/status , takes the parameter “id” returned from api/getData , and checks if the status of that “id” is success or not (returns true/false).
Until api/status returns true we cannot make a request api/data because data is not yet parsed. So, api/status indicates if we can make a request to api/data to get the data which accepts “id” as parameter.
So , in this case we have make continuous requests to api/status endpoint to check the status.
Lets see how we can achieve this , with and without using retry decorator.
Without Retry decorator
def check_status(id):
status = requests.get(status_url)
if status == True:
return True
else:
return Falsedef get_data(id):
status = None
while status is None or status == False:
time.sleep(5)
status = check_status(id) response = requests.get(url)
return response;
In above pseudo code , I am making a call to “check_status” method in while loop and for every request I am delaying it for 5 seconds and it has to wait until status is “True” , only then we can fetch the data using “api/data”
endpoint.
So , its a kind of retry pattern where we are repeatedly checking the status of id by delaying it by 5 seconds.
The same can be implemented using “Retry decorator”.
With Retry decorator
To install retry decorator , use below command.
pip install retry
To use it in your code , include below statement in your code.
from retry import retry
To make any function as a retry logic , just add @retry() statement above your function definition as below.
@retry()
def check_status:
Retry decorator accepts some parameters ,
exceptions - you can specify your custom exception class , which indicates that you are expecting the function to retry when specified exception occurs.tries - specifies the maximum number of times function can be retried. Default value is "-1".delay - specifies the amount of time the function waits before next retry , similar to time.sleep() we have used above. Default value is "0".
Above are some of the parameters that retry decorator accepts , for more information refer documentation.
Implementation:
@retry(InvalidStatus, delay=5, tries=6)
def wait_for_success_status(url):
status = None
try:
result = requests.get(url)
response = result.json()
status = response["data"]
if status != "SUCCESS":
raise InvalidStatus(ErrorMessages.STATUS_TIMEOUT_MESSAGE)
except Exception as error:
print(error)
raise
Instead of using time.sleep(5) , I have used retry decorator declared above “waitforsuccess_status” function with 3 parameters Exception type which indicates that on that specific type of exception function has to retry , delay with 5 seconds which delays the function execution by 5 seconds , tries with value 6 which indicates that function can be retried maximum of 6 times.
We can add multiple exception types as well.
@retry((ValueError,TypeError,InvalidStatus), delay=5, tries=6)
In this case function will be re-tried if any one of exception occurs.