Catching Failures via requests.exceptions.Timeout
๐ท๏ธ APIs and HTTP Requests / Timeouts and Error Handling
When your Python script makes HTTP requests to external services, sometimes those services take too long to respond. A timeout occurs when a request exceeds a specified waiting period. Without handling these timeouts properly, your script can hang indefinitely, causing delays or failures in your automation workflows.
โ๏ธ What Is a Timeout?
A timeout is a limit you set on how long your script will wait for a response from a server. If the server doesn't respond within that time, Python raises a requests.exceptions.Timeout exception.
- Connect timeout โ The time allowed for your script to establish a connection to the server.
- Read timeout โ The time allowed for your script to receive data from the server after the connection is made.
- Combined timeout โ A single value applied to both connect and read phases.
๐ ๏ธ How to Set Timeouts in requests
When making a request using the requests library, you pass a timeout parameter:
- timeout=5 โ Wait up to 5 seconds for both connect and read.
- timeout=(3, 10) โ Wait 3 seconds to connect, then 10 seconds to read.
- timeout=None โ No timeout (not recommended, as your script may hang forever).
Example of setting a timeout in a request:
- requests.get('https://example.com', timeout=5) โ This tells the script to wait a maximum of 5 seconds for a response.
๐ต๏ธ Catching Timeout Exceptions
When a timeout occurs, Python raises requests.exceptions.Timeout. You catch this exception using a try-except block to handle the failure gracefully.
Basic structure:
- Wrap your request in a try block.
- Catch requests.exceptions.Timeout in an except block.
- Inside the except block, log the error, retry, or take alternative action.
Example flow:
- try: โ Make the HTTP request with a timeout value.
- except requests.exceptions.Timeout: โ Print a message like "Request timed out" and continue with fallback logic.
๐ Comparison: With vs. Without Timeout Handling
| Scenario | Behavior | Impact |
|---|---|---|
| No timeout set | Script waits indefinitely | Script hangs, no error raised |
| Timeout set but not caught | Script raises an unhandled exception | Script crashes with a traceback |
| Timeout set and caught | Script handles the failure gracefully | Script logs the error and continues |
๐งช Practical Example Breakdown
Imagine you are polling a status endpoint every few seconds. If the endpoint becomes unresponsive, you want to detect that quickly and move on.
Steps in your logic:
- Set a timeout of 3 seconds on your request.
- Use a try-except block to catch requests.exceptions.Timeout.
- In the except block, print a warning message and continue the loop.
- Optionally, implement a retry mechanism with a delay.
This approach ensures your script does not get stuck waiting for a dead service.
๐ Retry Logic After Timeout
A common pattern is to retry the request a few times before giving up. You can combine timeout handling with a simple retry loop:
- Set a maximum number of retries (e.g., 3).
- Use a for loop to attempt the request multiple times.
- Catch the timeout exception inside the loop.
- If the request succeeds, break out of the loop.
- If all retries fail, log a final error and exit.
This pattern increases resilience against transient network issues.
โ ๏ธ Common Pitfalls to Avoid
- Forgetting to set a timeout โ Your script may hang forever if the server never responds.
- Catching the wrong exception โ Use requests.exceptions.Timeout, not a generic Exception.
- Not logging the failure โ Without logging, you won't know why your script behaved unexpectedly.
- Infinite retry loops โ Always limit retry attempts to avoid endless execution.
โ Best Practices Summary
- Always set a timeout on every HTTP request you make.
- Catch requests.exceptions.Timeout explicitly in your error handling.
- Log timeout events with details like the URL and elapsed time.
- Implement a retry mechanism with a maximum retry count and delay.
- Use separate connect and read timeouts for more granular control.
By handling timeouts properly, your scripts become more robust and reliable, especially when interacting with external APIs that may experience latency or downtime.
This exception is raised when a request takes longer than the allowed time limit, allowing engineers to handle slow or unresponsive servers gracefully.
โฑ๏ธ Example 1: Basic Timeout Exception
This example shows what happens when a request exceeds a very short timeout value.
import requests
try:
response = requests.get("https://httpbin.org/delay/5", timeout=1)
except requests.exceptions.Timeout:
print("The request timed out")
๐ค Output: The request timed out
โฑ๏ธ Example 2: Catching Timeout with a Specific Error Message
This example demonstrates how to catch the timeout and display a custom message.
import requests
url = "https://httpbin.org/delay/3"
try:
response = requests.get(url, timeout=2)
except requests.exceptions.Timeout:
print(f"Request to {url} failed due to timeout")
๐ค Output: Request to https://httpbin.org/delay/3 failed due to timeout
โฑ๏ธ Example 3: Using a Retry After Timeout
This example shows how to retry a request once after catching a timeout.
import requests
url = "https://httpbin.org/delay/4"
max_retries = 1
attempt = 0
while attempt <= max_retries:
try:
response = requests.get(url, timeout=2)
print("Request succeeded")
break
except requests.exceptions.Timeout:
attempt += 1
if attempt <= max_retries:
print(f"Timeout occurred, retrying (attempt {attempt})")
else:
print("Max retries reached, request failed")
๐ค Output: Timeout occurred, retrying (attempt 1)
Max retries reached, request failed
โฑ๏ธ Example 4: Different Timeout Values for Connect and Read
This example shows how to set separate timeouts for connecting and reading data.
import requests
url = "https://httpbin.org/delay/6"
try:
response = requests.get(url, timeout=(2, 3))
except requests.exceptions.Timeout:
print("Timeout occurred during connection or reading")
๐ค Output: Timeout occurred during connection or reading
โฑ๏ธ Example 5: Catching Timeout in a Function for Reuse
This example wraps timeout handling in a reusable function for multiple URLs.
import requests
def fetch_with_timeout(url, timeout=5):
try:
response = requests.get(url, timeout=timeout)
return response.text
except requests.exceptions.Timeout:
return "Request timed out"
result1 = fetch_with_timeout("https://httpbin.org/delay/1", timeout=2)
result2 = fetch_with_timeout("https://httpbin.org/delay/10", timeout=2)
print(result1[:50])
print(result2)
๐ค Output: {
Request timed out
๐ Comparison Table
| Scenario | Timeout Value | Behavior |
|---|---|---|
| Fast server response | 5 seconds | Request succeeds normally |
| Slow server response | 1 second | requests.exceptions.Timeout raised |
| Separate connect/read timeouts | (2, 3) | Connect timeout at 2s, read timeout at 3s |
| With retry logic | 2 seconds | Retries once before failing |
| Reusable function | 5 seconds | Returns data or timeout message |
When your Python script makes HTTP requests to external services, sometimes those services take too long to respond. A timeout occurs when a request exceeds a specified waiting period. Without handling these timeouts properly, your script can hang indefinitely, causing delays or failures in your automation workflows.
โ๏ธ What Is a Timeout?
A timeout is a limit you set on how long your script will wait for a response from a server. If the server doesn't respond within that time, Python raises a requests.exceptions.Timeout exception.
- Connect timeout โ The time allowed for your script to establish a connection to the server.
- Read timeout โ The time allowed for your script to receive data from the server after the connection is made.
- Combined timeout โ A single value applied to both connect and read phases.
๐ ๏ธ How to Set Timeouts in requests
When making a request using the requests library, you pass a timeout parameter:
- timeout=5 โ Wait up to 5 seconds for both connect and read.
- timeout=(3, 10) โ Wait 3 seconds to connect, then 10 seconds to read.
- timeout=None โ No timeout (not recommended, as your script may hang forever).
Example of setting a timeout in a request:
- requests.get('https://example.com', timeout=5) โ This tells the script to wait a maximum of 5 seconds for a response.
๐ต๏ธ Catching Timeout Exceptions
When a timeout occurs, Python raises requests.exceptions.Timeout. You catch this exception using a try-except block to handle the failure gracefully.
Basic structure:
- Wrap your request in a try block.
- Catch requests.exceptions.Timeout in an except block.
- Inside the except block, log the error, retry, or take alternative action.
Example flow:
- try: โ Make the HTTP request with a timeout value.
- except requests.exceptions.Timeout: โ Print a message like "Request timed out" and continue with fallback logic.
๐ Comparison: With vs. Without Timeout Handling
| Scenario | Behavior | Impact |
|---|---|---|
| No timeout set | Script waits indefinitely | Script hangs, no error raised |
| Timeout set but not caught | Script raises an unhandled exception | Script crashes with a traceback |
| Timeout set and caught | Script handles the failure gracefully | Script logs the error and continues |
๐งช Practical Example Breakdown
Imagine you are polling a status endpoint every few seconds. If the endpoint becomes unresponsive, you want to detect that quickly and move on.
Steps in your logic:
- Set a timeout of 3 seconds on your request.
- Use a try-except block to catch requests.exceptions.Timeout.
- In the except block, print a warning message and continue the loop.
- Optionally, implement a retry mechanism with a delay.
This approach ensures your script does not get stuck waiting for a dead service.
๐ Retry Logic After Timeout
A common pattern is to retry the request a few times before giving up. You can combine timeout handling with a simple retry loop:
- Set a maximum number of retries (e.g., 3).
- Use a for loop to attempt the request multiple times.
- Catch the timeout exception inside the loop.
- If the request succeeds, break out of the loop.
- If all retries fail, log a final error and exit.
This pattern increases resilience against transient network issues.
โ ๏ธ Common Pitfalls to Avoid
- Forgetting to set a timeout โ Your script may hang forever if the server never responds.
- Catching the wrong exception โ Use requests.exceptions.Timeout, not a generic Exception.
- Not logging the failure โ Without logging, you won't know why your script behaved unexpectedly.
- Infinite retry loops โ Always limit retry attempts to avoid endless execution.
โ Best Practices Summary
- Always set a timeout on every HTTP request you make.
- Catch requests.exceptions.Timeout explicitly in your error handling.
- Log timeout events with details like the URL and elapsed time.
- Implement a retry mechanism with a maximum retry count and delay.
- Use separate connect and read timeouts for more granular control.
By handling timeouts properly, your scripts become more robust and reliable, especially when interacting with external APIs that may experience latency or downtime.
Interactive Views
You are currently in ๐ All-in-One mode. Use the tabs at the top to switch to ๐ Theory Only or ๐ป Code Only views.
This exception is raised when a request takes longer than the allowed time limit, allowing engineers to handle slow or unresponsive servers gracefully.
โฑ๏ธ Example 1: Basic Timeout Exception
This example shows what happens when a request exceeds a very short timeout value.
import requests
try:
response = requests.get("https://httpbin.org/delay/5", timeout=1)
except requests.exceptions.Timeout:
print("The request timed out")
๐ค Output: The request timed out
โฑ๏ธ Example 2: Catching Timeout with a Specific Error Message
This example demonstrates how to catch the timeout and display a custom message.
import requests
url = "https://httpbin.org/delay/3"
try:
response = requests.get(url, timeout=2)
except requests.exceptions.Timeout:
print(f"Request to {url} failed due to timeout")
๐ค Output: Request to https://httpbin.org/delay/3 failed due to timeout
โฑ๏ธ Example 3: Using a Retry After Timeout
This example shows how to retry a request once after catching a timeout.
import requests
url = "https://httpbin.org/delay/4"
max_retries = 1
attempt = 0
while attempt <= max_retries:
try:
response = requests.get(url, timeout=2)
print("Request succeeded")
break
except requests.exceptions.Timeout:
attempt += 1
if attempt <= max_retries:
print(f"Timeout occurred, retrying (attempt {attempt})")
else:
print("Max retries reached, request failed")
๐ค Output: Timeout occurred, retrying (attempt 1)
Max retries reached, request failed
โฑ๏ธ Example 4: Different Timeout Values for Connect and Read
This example shows how to set separate timeouts for connecting and reading data.
import requests
url = "https://httpbin.org/delay/6"
try:
response = requests.get(url, timeout=(2, 3))
except requests.exceptions.Timeout:
print("Timeout occurred during connection or reading")
๐ค Output: Timeout occurred during connection or reading
โฑ๏ธ Example 5: Catching Timeout in a Function for Reuse
This example wraps timeout handling in a reusable function for multiple URLs.
import requests
def fetch_with_timeout(url, timeout=5):
try:
response = requests.get(url, timeout=timeout)
return response.text
except requests.exceptions.Timeout:
return "Request timed out"
result1 = fetch_with_timeout("https://httpbin.org/delay/1", timeout=2)
result2 = fetch_with_timeout("https://httpbin.org/delay/10", timeout=2)
print(result1[:50])
print(result2)
๐ค Output: {
Request timed out
๐ Comparison Table
| Scenario | Timeout Value | Behavior |
|---|---|---|
| Fast server response | 5 seconds | Request succeeds normally |
| Slow server response | 1 second | requests.exceptions.Timeout raised |
| Separate connect/read timeouts | (2, 3) | Connect timeout at 2s, read timeout at 3s |
| With retry logic | 2 seconds | Retries once before failing |
| Reusable function | 5 seconds | Returns data or timeout message |