State of client side HTTP in python
I'm developing a small package for writing typed Web API clients, similar to Uplink, only compatible with OpenAPI (lapidary). I use these clients mostly in Web servers, so I decided to make it async. So far I've settled on HTTPX, but I want to keep tabs on available python packages.
urllib.request
See also The Requests package is recommended for a higher-level HTTP client interface.
It accepts request headers only as a dict, and I've decided that it doesn't count as support for HTTP
❌ HTTP/1.1 ❌ HTTP/2 ❌ HTTP/3 ❌ asyncio
urllib3
Fast and robust, slowly acquiring HTTP/2 support, but only sync.
✅ HTTP/1.1 ❌ HTTP/2 ❌ HTTP/3 ❌ asyncio
requests
This the one every python example tells you to use. It's under a feature freeze since forever – HTTP moves on but requests is as perfect as possible. It also “broke the internet” when it moved to urllib3 2.0.0, which dropped support for older TLS algorithms, in a minor version release. As long as the API doesn't change in an incompatible way, right?
✅ HTTP/1.1 ❌ HTTP/2 ❌ HTTP/3 ❌ asyncio
pycURL
It's super fast, since it's super thin wrapper over libcURL.
Also a great showcase of how not to write python wrappers. Might as well use ctypes.
✅ HTTP/1.1 ✅ HTTP/2 ✅ HTTP/3 (I think it's supported, libcURL says it's experimental) ❌ asyncio but non-blocking, since it's a native code.
HTTPX
The most popular async HTTP client package for python. Supports HTTP/2 but claims it's “not as robust” as 1.1. Both sync and async.
API is mostly compatible with requests (it's not a feature). Depending on usage pattern, it's slightly slower or much slower than aiohttp.
✅ HTTP/1.1 ✅ HTTP/2 (discouraged, opt-in) ❌ HTTP/3 ✅ sync & async
aiohttp
API is close to the protocol, so a bit more complex than alternatives, but I like it. One of the fastest packages in python.
The community seems more focused on the server side (more features and plugins).
✅ HTTP/1.1 ❌ HTTP/2 ❌ HTTP/3 ✅ asyncio-only
Aiosonic
Looks and feels like HTTPX.
Depending on usage pattern, it's either a bit slower or a bit faster than aiohttp. Probably there's something wrong with it, because nobody seems to be using it. Definitely worth a closer look.
✅ HTTP/1.1 ✅ HTTP/2 – beta ❌ HTTP/3 ✅ sync & asyncio
Aioquic
Really low level HTTP/3 & QUIC package. Only for genuine H3 users. Could use better examples – example client has 600+ lines. Or maybe it's that hard to use...
❌ HTTP/1.1 ❌ HTTP/2 ✅ HTTP/3 ✅ asyncio-only
Niquests
Async fork of requests with HTTP/2 and 3. Fast, full featured but not user-friendly.
It uses a forked urllib3 (by the same author) that shadows it, so if you happen to have a transitive dependency on the original, it will mess up your environment. The author is fine with it. I recommend against using it.
✅ HTTP/1.1 ✅ HTTP/2 ✅ HTTP/3 ✅ sync & asyncio
Reqwest wrappers
This makes a lot of sense – Rust is a popular language, reqwest is a popular rust package, keep it DRY. None of the wrappers are widely popular, but some projects are live and definitely worth watching. – gufo-http – I think it's the oldest and still maintained – pyreqwest – httpr
Found a few more, just search reqwest in pypi.
✅ HTTP/1.1 ✅ HTTP/2 ❌ HTTP/3 – maybe, it's still experimental in reqwest ✅ sync and asyncio
Conclusion
Honestly, the clients for the protocol that makes the Web makes me wonder is Python still alive? There isn't a single popular and stable package with HTTP/2 (2015!) or HTTP/3 (2022) either sync or async. Is Python only for Django and LLM? Have everyone else switch to Rust and/or Deno?
