Show HN: Niquests – A Requests fork, three years of catching Python's HTTP up

3 pointsposted 8 hours ago
by mesahm

5 Comments

mesahm

8 hours ago

Author here. I forked Requests in mid-2023 because it's effectively frozen, and Python's HTTP capabilities have fallen far behind what the protocols and the ecosystem allow today. The Requests API is great; I didn't want to replace it, I wanted to catch it up.

Three years later, here's where things stand:

HTTP/2 by default, HTTP/3 over QUIC when the server advertises it via Alt-Svc or via DNS HTTPS record. No configuration needed, the client negotiates automatically. This alone accounts for most of the performance difference in practice. A quick benchmark (1000 requests to httpbingo.org/get, reproduction steps in the README)

niquests 0.551s (HTTP/2) aiohttp 1.351s (HTTP/1.1) httpx 2.087s (HTTP/2)

Security defaults that should have been there years ago. OS trust store instead of bundled certifi. Certificate revocation checks via OCSP or CRL. Encrypted Client Hello. Post-quantum key exchange. None of this is exotic anymore - browsers have shipped most of it - but Python clients still don't do it.

DNS. DNS-over-HTTPS, DNS-over-TLS, DNS-over-QUIC, DNSSEC validation. Per-session resolver configuration.

Other things that accumulated over three years: Happy Eyeballs, WebSocket and SSE over all three HTTP versions, in-memory certificates for mTLS, connection-level telemetry (DNS/TCP/TLS timings via response.conn_info), native Unix socket support, and as of 3.18, experimental Pyodide/WASM support.

Migration is boring by design: import niquests as requests. Existing auth flows, cookie jars, .netrc, adapters - they all work. We also maintain compatibility shims for requests-mock, responses, and betamax.

Happy to discuss anything related to the project or HTTP in general.

thitami

7 hours ago

Three years is a serious commitment for a fork. The drop-in compatibility story is what makes this viable — the biggest adoption barrier for any requests replacement is the migration cost across existing codebases. Curious how you're handling the cases where people rely on requests internals directly — things like custom HTTPAdapter subclasses or session-level hooks. Those are usually where drop-in replacements start breaking in the real world.

mesahm

7 hours ago

We've extensively worked the compat layer. And every adapters out there should work as is. But most of time, we've exposed better way to achieve that (e.g. mTLS in memory, network fine tuning, peer cert retrieval, ...) can be done without extra customization.

regards,

emanuele-em

6 hours ago

That feature comparison table is brutal for httpx and aiohttp. HTTP/3 over QUIC, DNSSEC, post-quantum, and still 4x faster than httpx? How stable has QUIC negotiation been with the big CDNs in practice?

mesahm

4 hours ago

Very stable actually. We've enabled it by default as such.

regards,