Asynchronous Python HTTP for Humans
Requests-futures is a small add-on for the popular 'requests' HTTP library, enabling asynchronous HTTP requests. It leverages Python's `concurrent.futures` module to perform requests concurrently using either `ThreadPoolExecutor` or `ProcessPoolExecutor`. It provides a `FuturesSession` class that mimics `requests.Session` but returns `Future` objects, allowing non-blocking operations and retrieval of responses later. The current version is 1.0.2, and its release cadence is infrequent but active.
Warnings
- gotcha Using `ProcessPoolExecutor` requires careful handling of pickling for the session and request objects. Python 2.x and < 3.4 are not supported for `ProcessPoolExecutor`. For Python 3.4+, an existing `requests.Session` instance *must* be passed when initializing `FuturesSession` with a `ProcessPoolExecutor`.
- breaking Exceptions are not raised immediately when a request is made. Instead, they are 'shifted' to when `future.result()` is called. This changes the expected location for `try/except` blocks.
- gotcha The default number of workers for the `ThreadPoolExecutor` has changed. Older versions might have defaulted to 2 workers, while recent versions (e.g., 1.0.2) default to 8 workers.
- gotcha As with standard `requests`, omitting `timeout` parameters can lead to requests hanging indefinitely, especially critical in concurrent applications where one stalled request can impact many others.
Install
-
pip install requests-futures
Imports
- FuturesSession
from requests_futures.sessions import FuturesSession
Quickstart
from requests_futures.sessions import FuturesSession
import os
session = FuturesSession()
# Example: Send multiple GET requests concurrently
urls = [
'http://httpbin.org/get?id=1',
'http://httpbin.org/get?id=2',
'http://httpbin.org/get?id=3',
]
futures = [session.get(url) for url in urls]
for i, future in enumerate(futures):
try:
response = future.result() # Blocks until the request completes
print(f"Request {i+1} Status: {response.status_code}")
print(f"Request {i+1} Content: {response.json()['args']}")
except Exception as e:
print(f"Request {i+1} failed: {e}")