Resolving Timeout Exceptions in Python Requests Module

Updated: January 2, 2024 By: Guest Contributor Post a comment

Introduction

The Python requests module is commonly used for sending HTTP requests. However, developers may sometimes encounter a ‘Timeout exception’ error. This can be frustrating but can usually be resolved with a few troubleshooting steps.

Timeout exceptions occur when a request takes longer than the prescribed time to return a response. This can be due to network issues, server problems, or inefficient code. Below we’ll explore some solutions to fix this error, alongside their advantages and limitations.

Solution 1: Increase Timeout Duration

Solution description: Adjusting the timeout parameter in the request can provide the server with more time to respond, preventing the exception.

  • Step 1: Identify the request causing the timeout.
  • Step 2: Increase the timeout parameter value.

Example:

import requests

url = 'https://example.com'

try:
    response = requests.get(url, timeout=30) # Increase timeout as needed
    print(response.content)
except requests.exceptions.Timeout:
    print('The request timed out')
except requests.exceptions.RequestException as e:
    print(e)

Pros: Simple and effective; can be enough for slow networks or busy servers.

Cons: Not a solution if the server is unresponsive; can lead to delays in your program.

Solution 2: Retry Strategy

Solution description: Implement a retry mechanism that attempts the request multiple times before failing.

  • Step 1: Install the urllib3 library if not already available.
  • Step 2: Use a Session from the requests library.
  • Step 3: Mount a retry strategy using HTTPAdapter with appropriate configuration.
  • Step 4: Send a request using the session.

Example:

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

retry_strategy = Retry(
    total=3,
    status_forcelist=[429, 500, 502, 503, 504],
    method_whitelist=['HEAD', 'GET', 'OPTIONS'],
    backoff_factor=1
)
adaptor = HTTPAdapter(max_retries=retry_strategy)
session = requests.Session()
session.mount('http://', adaptor)
session.mount('https://', adaptor)

url = 'https://example.com'

try:
    response = session.get(url)
    print(response.content)
except requests.exceptions.RequestException as e:
    print(e)

Pros: Resilient against intermittent issues; customizable for different scenarios.

Cons: May increase the time taken to detect a real problem with the server.

Solution 3: Asynchronous Requests

Solution description: Use an asynchronous requests library, like aiohttp, to perform non-blocking requests, possibly improving speed and efficiency.

  • Step 1: Install the aiohttp library if not already available.
  • Step 2: Use the aiohttp session to send an asynchronous request.
  • Step 3: Add error handling for timeouts.

Example:

import aiohttp
import asyncio

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        try:
            async with session.get(url, timeout=30) as response:
                print(await response.text())
        except asyncio.TimeoutError:
            print('The request timed out')
        except Exception as e:
            print(e)

loop = asyncio.get_event_loop()
loop.run_until_complete(fetch('https://example.com'))

Pros: Non-blocking; can handle numerous requests efficiently.

Cons: Asynchronous programming is a paradigm shift; dealing with its complexity can be difficult for beginners.