1.requests, httpx, and aiohttp
requests is the classic synchronous HTTP client — one blocking call at a time, the simplest API. httpx is a newer client with the same requests-like API but adds native async support (AsyncClient) and HTTP/2. aiohttp is async-only, built around its own event loop, and is also usable as a server framework.
Key features
- requests has no built-in async client — every call blocks until the response arrives
- httpx.Client is synchronous like requests; httpx.AsyncClient is its async twin, same method names
- aiohttp.ClientSession is async-only — there is no synchronous aiohttp client
- requests is the most widely installed of the three and has the largest plugin/adapter ecosystem
- httpx supports HTTP/2 (http2=True); requests and aiohttp are HTTP/1.1 only
Choosing a client
- requests
- Synchronous only — every call blocks
- requests.get(url), response.json()
- Largest ecosystem of adapters/plugins
- httpx / aiohttp
- httpx: one API, both httpx.Client (sync) and httpx.AsyncClient (async)
- aiohttp: async-only, built on asyncio, also usable as a server
- Both needed for concurrent HTTP calls without threads
Command
import requests
r = requests.get(url) # sync, blocks
import httpx
r = httpx.get(url) # sync, requests-like API
async with httpx.AsyncClient() as c:
r = await c.get(url) # async, same method names
import aiohttp
async with aiohttp.ClientSession() as s:
async with s.get(url) as r: # async, response is a context manager
data = await r.json()requests is sync-only with the biggest ecosystem; httpx gives one API for both sync and async plus HTTP/2; aiohttp is async-only and often doubles as a server.