Retrying After Python Requests
If you are working with Python requests library to send HTTP requests, you might encounter situations where the request fails due to various reasons like network congestion, server-side issues, etc. In such cases, you might want to retry the request after a certain amount of time to avoid overloading the server with too many failed requests.
Fortunately, the requests library provides a simple way to implement retries using the Retry
object from the urllib3.util.retry
module.
Using Retry Object
To use the Retry
object, you need to create an instance of it and pass it as a parameter to the Session
object. The Retry
object takes several parameters like total
, backoff_factor
, etc. You can customize these parameters based on your requirements.
import requests
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
retry_strategy = Retry(
total=3, # Number of retries
backoff_factor=2 # Delay between retries in seconds (exponential backoff)
)
adapter = HTTPAdapter(max_retries=retry_strategy)
# Create a session and mount the adapter
session = requests.Session()
session.mount('http://', adapter)
session.mount('https://', adapter)
url = 'https://example.com'
response = session.get(url)
The above code creates a Retry
object with a maximum of 3 retries and a delay of 2 seconds between retries (exponential backoff). It then creates an HTTP adapter with this retry strategy and mounts it on a session object for all requests.
You can also customize the Retry
object further by adding specific status codes to retry for and excluding certain status codes from retries. For example, to retry only for 500 and 502 status codes, you can modify the Retry
object as follows:
retry_strategy = Retry(
total=3, # Number of retries
backoff_factor=2, # Delay between retries in seconds (exponential backoff)
status_forcelist=[500, 502] # Status codes to retry for
)
Alternatively, you can exclude certain status codes from retries by using the status_exclude
parameter:
retry_strategy = Retry(
total=3, # Number of retries
backoff_factor=2, # Delay between retries in seconds (exponential backoff)
status_exclude=[404] # Status codes to exclude from retries
)
Using Retry-After Header
Sometimes, the server might return a Retry-After
header in the response indicating how long you should wait before retrying the request. In such cases, you can extract the value of the header and use it to delay the next retry using Python's time.sleep()
function.
import requests
import time
url = 'https://example.com'
response = requests.get(url)
if response.status_code == 429:
# Too many requests, wait for Retry-After header value
retry_after = int(response.headers.get('Retry-After', '5'))
time.sleep(retry_after)
response = requests.get(url)
The above code checks if the response status code is 429 (Too Many Requests) and extracts the value of the Retry-After
header. It then waits for that many seconds before retrying the request.
Conclusion
Retrying failed requests is an important aspect of building robust HTTP clients. The requests
library provides a simple way to implement retries using the Retry
object and also allows you to handle Retry-After
headers from the server. With these techniques, you can build HTTP clients that gracefully handle temporary failures and avoid overloading the server with too many failed requests.