Last modified: Nov 12, 2024 By Alexander Williams

Python Requests Timeout: Master Response Time Control

When making HTTP requests with Python's requests library, handling timeouts is crucial for building robust applications. Just like with GET requests, proper timeout management prevents your application from hanging.

Understanding Timeouts in Requests

A timeout occurs when a request takes too long to complete. The timeout parameter in requests helps control how long your application waits for a response before giving up.

There are two types of timeouts: connect timeout (time to establish connection) and read timeout (time to receive response).

Basic Timeout Implementation


import requests

try:
    # Single timeout value for both connect and read
    response = requests.get('https://api.example.com', timeout=5)
except requests.Timeout:
    print("The request timed out")

Using Tuple Timeout

For more precise control, you can specify connect and read timeouts separately using a tuple:


# (connect_timeout, read_timeout)
response = requests.get('https://api.example.com', timeout=(3, 5))

Implementing Retry Logic

Combining timeouts with retry logic creates more resilient applications. Here's how to implement basic retry functionality:


from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

session = requests.Session()
retry = Retry(total=3, backoff_factor=1)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)

try:
    response = session.get('https://api.example.com', timeout=5)
except requests.exceptions.RequestException as e:
    print(f"Request failed: {e}")

Handling Different Timeout Scenarios

Different requests might need different timeout values. Here's how to handle various scenarios:


import requests
from requests.exceptions import ConnectTimeout, ReadTimeout

def make_request(url, connect_timeout=3, read_timeout=6):
    try:
        response = requests.get(url, timeout=(connect_timeout, read_timeout))
        return response
    except ConnectTimeout:
        print("Failed to establish connection")
    except ReadTimeout:
        print("Server took too long to send data")
    except requests.RequestException as e:
        print(f"An error occurred: {e}")

Best Practices

When working with timeouts, consider these important practices:

  • Always set explicit timeouts rather than relying on defaults
  • Use shorter timeouts for HEAD requests and health checks
  • Implement longer timeouts for POST requests with large payloads

Error Handling Examples


def safe_request(url):
    try:
        response = requests.get(url, timeout=5)
        response.raise_for_status()
        return response.json()
    except requests.Timeout:
        return {"error": "Request timed out"}
    except requests.ConnectionError:
        return {"error": "Connection failed"}
    except requests.RequestException as e:
        return {"error": f"Request failed: {str(e)}"}

Conclusion

Proper timeout handling is essential for building reliable applications. By implementing appropriate timeout values and retry mechanisms, you can create more robust and responsive applications.

Remember to always test your timeout implementations with different network conditions and adjust values based on your specific use case requirements.