Skip to content

Requests - Handling Timeouts

When making network requests, especially to third-party services, it’s crucial to set timeouts. Without them, your application might hang indefinitely waiting for a response that never comes. This can deplete resources and degrade user experience. The requests library allows you to easily configure timeouts.

You can specify a timeout in seconds using the timeout parameter. This can be a single float value for the total timeout, or a tuple (connect_timeout, read_timeout).

  • Connect Timeout: The time (in seconds) to wait for the connection to the server to be established.
  • Read Timeout: The time (in seconds) to wait for the server to send a response after the connection has been established.

Let’s set an unrealistically short connect timeout to see how requests handles it.

import requests
try:
response = requests.get('https://jsonplaceholder.typicode.com/users', timeout=0.001)
print(response.text)
except requests.exceptions.ConnectTimeout as e:
print(f"Connection timed out: {e}")
except requests.exceptions.ReadTimeout as e:
print(f"Read timed out: {e}")
except requests.exceptions.Timeout as e:
print(f"A general timeout occurred: {e}")
Connection timed out: HTTPSConnectionPool(host='jsonplaceholder.typicode.com', port=443): Max retries exceeded with url: /users (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x...>, 'Connection to jsonplaceholder.typicode.com timed out. (connect timeout=0.001)'))

The code above demonstrates catching a ConnectTimeout exception. A timeout of 0.001 seconds is usually too short for any network request to complete, leading to this error.

Now, let’s use a more practical timeout value (e.g., 5 seconds for connect, 10 seconds for read).

import requests
try:
response = requests.get('https://jsonplaceholder.typicode.com/users', timeout=(5, 10))
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
print(response.json()[0]) # Print the first user object if successful
except requests.exceptions.Timeout as e:
print(f"Timeout occurred: {e}")
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
{
'id': 1,
'name': 'Leanne Graham',
'username': 'Bret',
'email': 'Sincere@april.biz',
'address': {
'street': 'Kulas Light',
'suite': 'Apt. 556',
'city': 'Gwenborough',
'zipcode': '92998-3874',
'geo': {
'lat': '-37.3159',
'lng': '81.1496'
}
},
'phone': '1-770-736-8031 x56442',
'website': 'hildegard.org',
'company': {
'name': 'Romaguera-Crona',
'catchPhrase': 'Multi-layered client-server neural-net',
'bs': 'harness real-time e-markets'
}
}

With a reasonable timeout, the request likely succeeds. We also added response.raise_for_status() for robust error handling of HTTP errors.

Best Practice: Always use timeouts for external requests. The specific values depend on the expected response time of the service you are calling. Not setting a timeout can cause your request to wait indefinitely.

For more details on timeout configurations, refer to the official Requests documentation on Timeouts.