Niquests is a simple, yet elegant, HTTP library. It is a drop-in replacement for Requests, which is under feature freeze.
Niquests, is the “Safest, Fastest1, Easiest, and Most advanced” Python HTTP Client. Production Ready!
✔️ Try before you switch: See Multiplexed in Action
📖 See why you should switch: Read about 10 reasons why, and "Revived the promise made six years ago for Requests 3"
✨ You were used to betamax, requests-mock, responses, ...? See how they still work! We got you covered.
👆 Look at the feature table comparison against requests, httpx and aiohttp!
Feature | niquests | requests | httpx | aiohttp |
---|---|---|---|---|
HTTP/1.1 |
✅ | ✅ | ✅ | ✅ |
HTTP/2 |
✅ | ❌ | ✅2 | ❌ |
HTTP/3 over QUIC |
✅ | ❌ | ❌ | ❌ |
Synchronous |
✅ | ✅ | ✅ | N/A3 |
Asynchronous |
✅ | ❌ | ✅ | ✅ |
Thread Safe |
✅ | ✅ | ❌4 | N/A3 |
Task Safe |
✅ | N/A5 | ✅ | ✅ |
OS Trust Store |
✅ | ❌ | ❌ | ❌ |
Multiplexing |
✅ | ❌ | Limited6 | ❌ |
DNSSEC |
✅7 | ❌ | ❌ | ❌ |
Customizable DNS Resolution |
✅ | ❌ | ❌ | ✅ |
DNS over HTTPS |
✅ | ❌ | ❌ | ❌ |
DNS over QUIC |
✅ | ❌ | ❌ | ❌ |
DNS over TLS |
✅ | ❌ | ❌ | ❌ |
Multiple DNS Resolver |
✅ | ❌ | ❌ | ❌ |
Network Fine Tuning & Inspect |
✅ | ❌ | Limited8 | Limited8 |
Certificate Revocation Protection |
✅ | ❌ | ❌ | ❌ |
Session Persistence |
✅ | ✅ | ✅ | ✅ |
In-memory Certificate CA & mTLS |
✅ | ❌ | Limited9 | Limited9 |
SOCKS 4/5 Proxies |
✅ | ✅ | ✅ | ❌ |
HTTP/HTTPS Proxies |
✅ | ✅ | ✅ | ✅ |
TLS-in-TLS Support |
✅ | ✅ | ✅ | ✅ |
Direct HTTP/3 Negotiation |
✅10 | N/A11 | N/A11 | N/A11 |
Happy Eyeballs |
✅ | ❌ | ❌ | ✅ |
Package / SLSA Signed |
✅ | ❌ | ❌ | ✅ |
HTTP/2 with prior knowledge (h2c) |
✅ | ❌ | ✅ | ❌ |
Post-Quantum Security |
Limited12 | ❌ | ❌ | ❌ |
HTTP Trailers |
✅ | ❌ | ❌ | ❌ |
Early Responses |
✅ | ❌ | ❌ | ❌ |
WebSocket over HTTP/1 |
✅ | ❌13 | ❌13 | ✅ |
WebSocket over HTTP/2 and HTTP/3 |
✅14 | ❌ | ❌ | ❌ |
Automatic Ping for HTTP/2+ |
✅ | N/A | ❌ | N/A |
Automatic Connection Upgrade / Downgrade |
✅ | N/A | ❌ | N/A |
Server Side Event (SSE) |
✅ | ❌ | ❌ | ❌ |
📈 Look at the performance comparison against them!
Scenario: Fetch a thousand requests using 10 tasks or threads, each with a hundred requests using a single pool of connection.
High-Level APIs
Client | Average Delay to Complete | Notes |
---|---|---|
requests | 987 ms or ~1013 req/s | ThreadPoolExecutor. HTTP/1.1 |
httpx | 720 ms or ~1389 req/s | Asyncio. HTTP/2 |
niquests | 340 ms or ~2941 req/s | Asyncio. HTTP/2 |
Simplified APIs
Client | Average Delay to Complete | Notes |
---|---|---|
requests core | 643 ms or ~1555 req/s | ThreadPoolExecutor. HTTP/1.1 |
httpx core | 490 ms or ~2000 req/s | Asyncio. HTTP/2 |
aiohttp | 210 ms or ~4762 req/s | Asyncio. HTTP/1.1 |
niquests core | 160 ms or ~6200 req/s | Asyncio. HTTP/2 |
Did you give up on HTTP/2 due to performance concerns? Think again! Do you realize that you can get 3 times faster with the same CPU if you ever switched to Niquests from Requests? Multiplexing and response lazyness open up a wide range of possibilities! Want to learn more about the tests? scripts? reasoning?
Take a deeper look at https://github.com/Ousret/niquests-stats
>>> import niquests
>>> s = niquests.Session(resolver="doh+google://", multiplexed=True)
>>> r = s.get('https://one.one.one.one')
>>> r
<ResponsePromise HTTP/3>
>>> r.status_code
200
>>> r.headers['content-type']
'application/json; charset=utf8'
>>> r.oheaders.content_type.charset
'utf8'
>>> r.encoding
'utf-8'
>>> r.text
'{"authenticated": true, ...'
>>> r.json()
{'authenticated': True, ...}
>>> r
<Response HTTP/3 [200]>
>>> r.ocsp_verified
True
>>> r.conn_info.established_latency
datetime.timedelta(microseconds=38)
or using async/await!
import niquests
import asyncio
async def main() -> None:
async with niquests.AsyncSession(resolver="doh+google://") as s:
r = await s.get('https://one.one.one.one', stream=True)
print(r) # Output: <Response HTTP/3 [200]>
payload = await r.json()
print(payload) # Output: {'authenticated': True, ...}
asyncio.run(main())
Niquests allows you to send HTTP requests extremely easily. There’s no need to manually add query strings to your URLs, or to form-encode your PUT
& POST
data — just use the json
method!
This project does not require any compilation toolchain. The HTTP/3 support is not enforced and installed if your platform can support it natively (e.g. pre-built wheel available).
Niquests is available on PyPI:
$ python -m pip install niquests
Niquests officially supports Python or PyPy 3.7+.
Niquests is ready for the demands of building scalable, robust and reliable HTTP–speaking applications.
- DNS over HTTPS, DNS over QUIC, DNS over TLS, and DNS over UDP
- Automatic Content Decompression and Decoding
- OS truststore by default, no more certifi!
- OCSP Certificate Revocation Verification
- Advanced connection timings inspection
- In-memory certificates (CAs, and mTLS)
- Browser-style TLS/SSL Verification
- Sessions with Cookie Persistence
- Keep-Alive & Connection Pooling
- International Domains and URLs
- Automatic honoring of
.netrc
- Basic & Digest Authentication
- Familiar
dict
–like Cookies - Network settings fine-tuning
- HTTP/2 with prior knowledge
- Object-oriented headers
- Multi-part File Uploads
- Post-Quantum Security
- Chunked HTTP Requests
- Fully type-annotated!
- SOCKS Proxy Support
- Connection Timeouts
- Streaming Downloads
- HTTP/2 by default
- HTTP/3 over QUIC
- Early Responses
- Happy Eyeballs
- Multiplexed!
- Thread-safe!
- WebSocket!
- Trailers!
- DNSSEC!
- Async!
- SSE!
Need something more? Create an issue, we listen.
For many years now, Requests has been frozen. Being left in a vegetative state and not evolving, this blocked millions of developers from using more advanced features.
We don't have to reinvent the wheel all over again, HTTP client Requests is well established and really pleasant in its usage. We believe that Requests has the most inclusive and developer friendly interfaces. We intend to keep it that way. As long as we can, long live Niquests!
How about a nice refresher with a mere CTRL+H
import requests to import niquests as requests ?
Professional support for Niquests is available as part of the Tidelift Subscription. Tidelift gives software development teams a single source for purchasing and maintaining their software, with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools.
You may also be interested in unlocking specific advantages (like access to a private issue tracker) by looking at our GitHub sponsor tiers.
Niquests is a highly improved HTTP client that is based (forked) on Requests. The previous project original author is Kenneth Reitz and actually left the maintenance of Requests years ago.
Footnotes
-
performance measured when leveraging a multiplexed connection with or without uses of any form of concurrency as of October 2024. The research compared
httpx
,requests
,aiohttp
againstniquests
. See https://github.com/Ousret/niquests-stats ↩ -
while advertised as possible, they refuse to make it the default due to performance issues. as of October 2024 an extra is required to enable it manually. ↩
-
aiohttp was conceived solely for an asynchronous context. ↩ ↩2
-
httpx officially claim to be thread safe but recent tests demonstrate otherwise as of february 2024. https://github.com/jawah/niquests/issues/83#issuecomment-1956065258 https://github.com/encode/httpx/issues/3072 https://github.com/encode/httpx/issues/3002 and only recently acknowledged the issue in https://github.com/encode/httpx/issues/3324 (one year after getting valid reports). ↩
-
requests has no support for asynchronous request. ↩
-
while the HTTP/2 connection object can handle concurrent requests, you cannot leverage its true potential. ↩
-
enabled when using a custom DNS resolver. ↩
-
they do not expose anything to control network aspects such as IPv4/IPv6 toggles, and timings (e.g. DNS response time, established delay, TLS handshake delay, etc...) and such. ↩ ↩2
-
you must use a custom DNS resolver so that it can preemptively connect using HTTP/3 over QUIC when remote is compatible. ↩
-
available only when using HTTP/3 over QUIC and that the remote server support also the same post-quantum key-exchange algorithm. Also, the
qh3
installed version must be >= 1.1. ↩ -
they don't offer any built-in to speak with a WebSocket server. ↩ ↩2
-
most servers out there are not ready for this feature, but Niquests is already compliant and future-proof! Modern server like Caddy are still working on it, see https://github.com/caddyserver/caddy/pull/6567 for more. ↩