NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3379 most downloaded on PyPI
Niquests is a simple, yet elegant, HTTP library. It is a drop-in replacement for Requests, which is under feature freeze.
Last release 12 days ago
23 Sep 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
3 versions withdrawn
withdrawn after publishing
3 years old
89 releases · first in 2023
One column per quarter.
Minor performance improvement in CaseInsensitiveDict , with an expected gain of up to 1%.
Changed
CaseInsensitiveDict, with an expected gain of up to 1%.python -m niquests.help now reports the WebSocket backend and version through websocket.backendwebsocket.version, replacing websocket.wsproto.Fixed
iter_lines() when processing long lines.CaseInsensitiveDict to require str or bytes.Misc
websockets as a supported WebSocket backend alongside wsproto.pip install "niquests[ws-fast]". When both backends are installed, usewss+fast://example.org/ to explicitly select websockets. Run python -m niquests.helpurllib3-future, with no local build required.verify parameter not honored when targeting a wss or see endpoint (using the shortcut scheme).
Fixed
wss or see endpoint (using the shortcut scheme).First-class support for the WebAssembly System Interface (WASI) Component Model.
Added
First-class support for the WebAssembly System Interface (WASI) Component Model. (#364)
Niquests can now run inside sandboxed WebAssembly components using the same
Requests-compatible API available on native Python. This enables HTTP clients for
edge functions, plug-ins, agent runtimes, and other capability-constrained
applications without requiring application-specific adapters.
Niquests automatically discovers the interfaces imported by the component and
selects the most capable available transport. Synchronous applications can use
native WASI Preview 2 sockets, while asynchronous applications can use Preview 3
sockets. The socket transports retain urllib3.future's native behavior, including
connection pooling, HTTP/2 multiplexing, streaming, trailers, WebSocket, SSE,
redirects, retries, cookies, and timeout handling.
Components that intentionally omit raw socket authority can instead use the
host-managed wasi:http interfaces: HTTP 0.2 for synchronous applications and
HTTP 0.3 for asynchronous applications. This provides a narrower capability surface
in which the host controls DNS, TCP, TLS, certificate trust, protocol negotiation,
and connection reuse. Niquests also supports hybrid worlds, using sockets where
possible and WIT HTTP where host-managed TLS is required.
No network or filesystem authority is ambient under WASI. A component's WIT world
declares which interfaces it can access, while the runtime independently decides
which capabilities to grant. Native hostname resolution therefore requires an
explicit DNS grant, and host filesystem access remains unavailable unless a
directory is deliberately preopened.
HTTPS over native WASI sockets requires the rtls extra and urllib3.future
2.24.900 or newer. When using WIT HTTP, TLS is provided according to the host's
security policy instead.
With this release, Niquests supports native Python, browser-side WebAssembly through
Pyodide, and server-side WebAssembly through WASI while preserving the same familiar
request API. See the WASI quickstart and advanced capability guide for deployment
examples and transport-specific constraints.
Explicit support for Python 3.15
Custom json_encoder in Session and AsyncSession for request bodies. (#437)
Top-level request APIs accept custom JSON encoders and TLS configuration.
Fixed
A session initialized with multiplexed=True can starve the event loop when responses are pending read (i.e. no promise left, only stream data read).
Fixed
multiplexed=True can starve the event loop when responses are pending read (i.e. no promise left, only stream data read).Method/Verb QUERY as one of the promoted HTTP verb and available through top level function shortcuts and Session / AsyncSession methods. This is foll
Added
QUERY as one of the promoted HTTP verb and available through top level function shortcuts and Session/AsyncSession methods.request(...) calls.TLSConfiguration object to let you take a deeper control over the TLS configuration.Fixed
AsyncResponse iter_lines method. (#413)Relative Location redirects no longer raise MissingSchema when the request targets a synthetic scheme such as wsgi:// or asgi:// .
Fixed
Location redirects no longer raise MissingSchema when the request targets awsgi:// or asgi://. (#406)This is not a runtime breaking change: reading .cookies is unchanged, and a native CookieJar is still accepted everywhere it is passed as an argument…
Added
Session and AsyncSession constructors now accept params, cookies, proxies, verify and certheaders and auth. (#400)http.cookiejar.CookieJar (or a mapping) provided as cookies is now coerced into aRequestsCookieJar. The Session/AsyncSession constructor always coerces (so session.cookies.set(...)CookieJar subclass (e.g. MozillaCookieJar or anyutls extra.Session and AsyncSession constructors now accept allow_incoming_cookies (defaults to True).False to ignore every cookie sent by the remote peer (via Set-Cookie) so that nothingSession.request/AsyncSession.request (and the verb shortcuts) now accept an override_schemebase_url is set on the Session, it override the scheme of the finalsse,ws/wss, optionally with an implementation suffix like sse+unix) without retyping the full URL. (#325)Changed
The cookies attribute of Session, AsyncSession and Response is now always typed as
RequestsCookieJar instead of RequestsCookieJar | CookieJar. This restores the ergonomic mapping
interface (e.g. session.cookies.set(...)) when using static type checkers. (#401, #404)
This is not a runtime breaking change: reading .cookies is unchanged, and a native CookieJar
is still accepted everywhere it is passed as an argument (it is coerced when relevant). We do,
however, acknowledge a static-typing trade-off: assigning a custom/non-RequestsCookieJar jar
directly to the attribute (e.g. session.cookies = MozillaCookieJar(...)) now makes type checkers
such as mypy complain, since the attribute is annotated as RequestsCookieJar. The assignment keeps
working at runtime; if you rely on it, add a # type: ignore. We chose narrowing on
purpose the predominant path is that RequestsCookieJar is expected while subclasses (custom implementation)
are a niche usage.
CaseInsensitiveDict is now generic over its key and value types (CaseInsensitiveDict[_KT, _VT],
mirroring dict/Mapping), and Response.headers/Response.trailers are typed as
CaseInsensitiveDict[str, str]. Reading a response header (e.g. response.headers["Content-Type"])
now yields str instead of str | bytes, removing the need for a cast/assert to use the headers
as a plain string mapping with static type checkers. (#401)
This is purely a typing improvement with no runtime change: the class still subclasses
collections.abc.MutableMapping (it merely also gains typing.Generic), so the Python 3.7 floor and
the existing behavior are preserved, and no new dependency is introduced. Unsubscripted
CaseInsensitiveDict keeps its historical str | bytes key/value types, so existing annotations are
unaffected.
Avoid starting the background idle watcher/task in session-less requests.
Fixed
Session/AsyncSession with multiplexed=True (i.e. lazy response resolution) performance improvement. Up to 20% gain.
Fixed
multiplexed=True (i.e. lazy response resolution) performance improvement. Up to 20% gain.AsyncResponse aenter is not awaitable.
sse scheme (web extension) urls preparation are skipped.
Failing basic isinstance check due to unintended modules duplicate via niquests.packages compat module.
Fixed
niquests.packages compat module. (#361)Lowered default keepalive_delay from 1h to 10min.
Fixed
Misc
rtls alternative TLS backend.Unprepared URLs when scheme don't contain http.
Fixed
http.Module 'importlib' has no attribute 'util'.
Fixed
Experimental support for WASM through Pyodide. (#219) Niquests should be able to automatically operate in the browser or a Node interpreter. We tested
Added
auth parameter through Session or AsyncSession constructor. (#337)psse+unix:// and ws+unix:// schemes. (#325)Fixed
tell never awaited when using aiofiles file wrapper or alike in async. (#334)AsyncSession.send method. (#335)Misc
niquests.typing.TLSVerifyType without a lazy PathLike reference for Python 3.9+ (#324)Native support for http+unix connections without 3rd party support in both sync and async context.
Added
http+unix connections without 3rd party support in both sync and async context. (#315)AsyncSession and WSGI (e.g. Flask) app direct usage within Session. (#316)hooks directly in the Session or AsyncSession constructor. (#321)LeakyBucketLimiter and TokenBucketLimiter that can be passed directly to the hooks parameter
of Session or AsyncSession for automatic request throttling. (#321)Fixed
get of CaseInsensitiveDict ambiguous return type. (#288)Changed
niquests.typing. This aims to considerably ease extending Niquests.Misc
utils.guess_json_utf from Requests era. (#313)Accidental deadlock on a specific case within the revocation checks in sync mode (threads).
Fixed
Custom strategies for TLS revocation check per Session or AsyncSession via the new revocation_configuration parameter that takes a RevocationConfigura
Added
Session or AsyncSession via the new revocation_configuration parameter
that takes a RevocationConfiguration object.niquests.LifecycleHook or niquests.AsyncLifecycleHook depending on your use case.
This should considerably ease the scenario where you need to create complex hooks.repr(my_session) for debugging purposes.ServerSentEvent in top level package imports to ease SSE related developments.AsyncHTTPDigestAuth counterpart of HTTPDigestAuth for async usage.Session or AsyncSession construction.Fixed
The return type of CaseInsensitiveDict.items() could be a list instead of an expected tuple.
Fixed
CaseInsensitiveDict.items() could be a list instead of an expected tuple. (#276)Session.hooks dict causing an error at merge with request specific hooks.Session.Disabled OCSP and CRL signature check when either the target site is located in a private network OR at least one proxy is used. See #274 for the rati
Changed
Fixed
Prevent MITM attack with OCSP. Previous to that version we did not check the signature against the issuer public key. While this sort of attack are in
Security
Added
Changed
wassima upperbound to version 2 that includes various QoL improvements and stopped relying on Rust.
The package is now pure Python and ships with the CCADB store as a fallback.urllib3-future lower bound version is raised to 2.13.903 for newest requirements.Fixed
Removed
Prevent accessing lazy attr if it does not exist (e.g. requests_cache mixin)
Fixed
"Repr" for our HTTPAdapter and AsyncHTTPAdapter for debugging purposes.
Added
aget, apost, aput, ..., as the asynchronous counterpart of niquests.get, niquests.post, ...Session or AsyncSession. Like Session(timeout=10). (#232)iter_raw method in Response and AsyncResponse in order to retrieve content from remote without decompression. (#233)Fixed
AsyncResponse.close(...). (#231)close coroutine (urllib3 raw Response) in async mode when the response is not awaitable.Internal shortcut to urllib3-future as niquests.packages.urllib3. This immediately helps end-user migrating from Requests to Niquests and avoid the co
Added
niquests.packages.urllib3. This immediately helps end-user migrating
from Requests to Niquests and avoid the confusion around urllib3 and urllib3-future.
The package own code benefit from it. idna, charset_normalizer (+ aliased as chardet) can be used also.Misc
Dependency on idna. Since qh3 version 1.4, we can rely on their internal idna encoder that does not require any external dependencies. This change doe
Removed
idna. Since qh3 version 1.4, we can rely on their internal idna encoder that does not require any external dependencies.
This change does not affect the feature on international domain names. If idna is installed, it will be used instead.kiss-headers. We decided to vendor kiss-headers into Niquests for several reasons. The principal one
is that the project is stable and require next to no maintenance. And pulling extra dependencies affect some end-users.
We are in the process of measuring potential interest for kiss-headers models. We may decide to remove its support completely
in a next major version.Relaxed strict compliance on JSON parsing. We brought strict compliance into Niquests, a response must explicitly set Content-Type: application/json o
Changed
Content-Type: application/json or alike prior to attempt parsing the JSON string.
We decided to relax that constraint as old and bad-behaving server may send JSON with missing or broken Content-Type.Parsing of special scheme that exceed 9 characters on rare custom adapters.
Fixed
Changed
Content-Type for json payloads changed from application/json; charset="utf-8" to application/json;charset=utf-8.
While the previous default was valid, this is the preferred value according to RFC9110. (#204)Misc
Certificate validation may end up in error in highly concurrent environment using the experimental freethreaded build. This was due to a racing condit
Fixed
Restoring the state of AsyncSession through pickle.
Fixed
AsyncSession through pickle.None as values. (#193)AsyncSession::get. (#192)Added
PathLike objects for verify parameter when passing a ca bundle path. (#194)Session or AsyncSession.Session or AsyncSession.Retry and Timeout configuration objects in top-level import.Invoking niquests in more than one event loop, even if no loop concurrence occurs. (#190) The faulty part was the shared OCSP cache that was automatic
Fixed
niquests in more than one event loop, even if no loop concurrence occurs. (#190)
The faulty part was the shared OCSP cache that was automatically bound the first event loop and
could not be shared across more than one loop. Keep in mind that Niquests async is task safe within
a single event loop. Sharing a single AsyncSession across more than one event loop is unpredictable.
We've waived that limitation by binding the ocsp cache to a single Session. (both sync & async)socket.timeout error coming from the ocsp checker when running Python < 3.9.Static type checker getting confused around AsyncSession and attached overloads (AsyncResponse or Response).
Fixed
AsyncSession and attached overloads (AsyncResponse or Response). (#185)Changed
Removed
max_in_flight_multiplexed in your HTTPAdapter to
restore this broken behavior.SSE request block IO by default. Integrate better with urllib3-future new SSE web extension.
Fixed
Changed
Fixed - async version of iter_line.
Fixed
iter_line. (#182)base_url parameter to niquests.Session or niquests.AsyncSession. automatically prefix every request emitted with it.
Added
niquests.Session or niquests.AsyncSession. automatically prefix every request emitted with it. (#179)Fixed
Resolving lazy responses when emitted through a SOCKS, HTTP or HTTPS proxy.
Fixed
Ensure stream, and verify both defaults to your Session parameters.
Fixed
stream, and verify both defaults to your Session parameters.Exception leak from urllib3-future when gathering / resolving lazy responses.
Fixed
Automatic Advanced Keep-Alive for HTTP/2 and HTTP/3 over QUIC by sending PING frames. New Session, and Adapter parameters are now available: keepalive
Added
keepalive_delay, and keepalive_idle_window.
This greatly improves your daily experience working with HTTP/2+ remote peers.Fixed
Exception leak from urllib3-future when using WebSocket.
Fixed
Response.extension linked to the generic interface instead of the inherited ones.Misc
Changed
Support for WebSocket over HTTP/1, HTTP/2 and HTTP/3. It brings a unified API that makes you leverage our powerful features like Happy Eyeballs, SOCKS
Added
Fixed
Changed
Help script now yield warnings if update are available for each sub dependencies.
Added
Fixed
Changed
DummyLock injected into RequestsCookieJar is not fully compatible, thus breaking AsyncSession on certain scenario.
Fixed
Official support for Python 3.13 This has been tested outside GitHub CI due to httpbin unready state for 3.13[...]
Added
AsyncIterable that yield either bytes or str.quic_cache_layer property of Session.
In order to exclude cloudflare.com from HTTP3 auto-upgrade:from niquests import Session
s = Session()
s.quic_cache_layer.exclude_domain("cloudflare.com")
Fixed
AsyncSession. Its effect has been nullified to improve performances.Changed
TransferProgress tracking in Response when downloading using stream=True based on the Content-Length. (#127) There's no easy way to track the "real" a
Added
stream=True based on the Content-Length. (#127)
There's no easy way to track the "real" amount of bytes consumed using "iter_content" when the remote is
sending a compressed body. This change makes it possible to track the amount of bytes consumed.
The Response object now contain a property named download_progress that is either None or a TransferProgress object.disable_http1 toggle is now available through your Session constructor.
In consequence, you may leverage all HTTP/2 capabilities like multiplexing using a plain (e.g. non-TLS) socket.
You may enable/disable any protocols per Session object (but not all of them at once!).
In non-TLS connections, you have to keep one of HTTP/1.1 or HTTP/2 enabled.
Otherwise, one of HTTP/1.1, HTTP/2 or HTTP/3. A RuntimeError may be thrown if no protocol can be used in a
given context.Changed
CaseInsensitiveDict repr (to string) causing an unexpected error when upstream have multiple values for a single header.
Fixed
Misc
ReasonFlag not properly translated to readable text when peer or intermediate certificate is revoked.
Fixed
Support localhost as a valid domain for cookies. The standard library does not allow this special domain. Researches showed that a valid domain should
Fixed
localhost as a valid domain for cookies. The standard library does not allow this special
domain. Researches showed that a valid domain should have at least two dots (e.g. abc.com. and xyz.tld. but not com.).
Public suffixes cannot be used as a cookie domain for security reasons, but as localhost isn't one we are explicitly
allowing it. Reported in https://github.com/httpie/cli/issues/602
RequestsCookieJar set a default policy that circumvent that limitation, if you specified a custom cookie policy then this
fix won't be applied.Changed
Removed
disable_thread in AsyncSession that is no longer relevant since the native asyncio implementation. (PR #122)Avoid parsing X509 peer certificate in the certificate revocation check process over and over again.
Changed
Fixed encoding data with None values and other objects. This was a regression introduced in our v3. #119
Fixed
Changed
"Help" program python -m niquests.help that depended on h2 while not required anymore.
Fixed
python -m niquests.help that depended on h2 while not required anymore.Changed
Handling broken environments with a graceful exception with a detailed error message.
Fixed
Support for qh3 version 1.0.0 This qh3 release enable a greater flexibility by dropping cryptography. We had to adapt the OCSP code as we relied on cr
Added
Changed
Fixed
Support for Happy Eyeballs. This feature is disabled by default, you must pass happy_eyeballs=True within your session constructor or http adapter in
Added
happy_eyeballs=True within your session
constructor or http adapter in order to leverage this.Fixed
Changed
Support to verify the peer certificate fingerprint using verify=... by passing a string using the following format: verify="sha256_748c76348778cb4a536
Added
verify=... by passing a string using the following format:
verify="sha256_748c76348778cb4a536e7ec12bc9aa559c12770bd1419c7ffe516006e1dea0ec". Doing so disable the certificate
usual verification and only checks for its fingerprint match.Fixed
verify=... and cert=... then change it for the same host did not apply to the underlying (existing) connection pool.Misc
A rare error that occurs on PyPy, especially on Windows, complaining about a missing release call.
Fixed
Misc
ImportError in an attempt to retrieve ConnectionInfo.
Fixed
ConnectionInfo.Changed
General performance improvements.
Changed
Replaced the thread pool executor for the true asyncio implementation. The asynchronous part is rewritten.
Changed
Added
speedups to increase overall performances by including optional dependencies such as zstandard, brotli and orjson.Fixed
Unintentional performance regression with multiple concurrent multiplexed connection within a single Session.
Fixed
Your coding agent can read these notes before it upgrades. Set up the MCP server →