Releases: jawah/niquests
Version 3.2.2
3.2.2 (2023-11-08)
Changed
- Enforced a maximum in-flight request when using multiplexed connections. Default to 124 per connection
so, actually 1240 per Session (default is 10 connections). This can be overridden in ourHTTPAdapter
for advanced users.
This limit was changed due to a constraint inqh3
, for now, we have no way to set this dynamically. We choose the safest
lowest value in h2, and qh3. This will be improved later.
Fixed
- Performance issue in
get_environ_proxies()
.
Version 3.2.1
3.2.1 (2023-11-06)
Fixed
- Performance issues in HTTP/2, and HTTP/3, with or without multiplexed connections.
Changed
- Enforced a maximum in-flight request when using multiplexed connections. Default to 200 per connection
so, actually 2000 per Session (default is 10 connections). This can be overridden in ourHTTPAdapter
for advanced users.
Version 3.2.0
3.2.0 (2023-11-05)
Changed
- Changed method
raise_for_status
in classResponse
to return self in order to make the call chainable.
Idea taken from upstream psf#6215 - Bump minimal version supported for
urllib3.future
to 2.2.901 for recently introduced added features (bellow).
Added
-
Support for multiplexed connection in HTTP/2 and HTTP/3. Concurrent requests per connection are now a thing, in synchronous code.
This feature is the real advantage of using binaries HTTP protocols.
It is disabled by default and can be enabled throughSession(multiplexed=True)
, eachResponse
object will
be 'lazy' loaded. Accessing anything from the returnedResponse
will block the code until the target response is retrieved.
UseSession.gather()
to efficiently receive responses. You may also give a list of responses that you want to load.Example A) Emitting concurrent requests and loading them via
Session.gather()
from niquests import Session from time import time s = Session(multiplexed=True) before = time() responses = [] responses.append( s.get("https://pie.dev/delay/3") ) responses.append( s.get("https://pie.dev/delay/1") ) s.gather() print(f"waited {time() - before} second(s)") # will print 3s
Example B) Emitting concurrent requests and loading them via direct access
from niquests import Session from time import time s = Session(multiplexed=True) before = time() responses = [] responses.append( s.get("https://pie.dev/delay/3") ) responses.append( s.get("https://pie.dev/delay/1") ) # internally call gather with self (Response) print(responses[0].status_code) # 200! :! Hidden call to s.gather(responses[0]) print(responses[1].status_code) # 200! print(f"waited {time() - before} second(s)") # will print 3s
You have nothing to do, everything from streams to connection pooling are handled automagically!
-
Support for in-memory intermediary/client certificate (mTLS).
Thanks for support withinurllib3.future
. Unfortunately, this feature may not be available depending on your platform.
Passingcert=(a, b, c)
where a or/and b contains directly the certificate is supported.
See https://urllib3future.readthedocs.io/en/latest/advanced-usage.html#in-memory-client-mtls-certificate for more information.
It is proposed to circumvent the recent pyOpenSSL complete removal. -
Detect if a new (stable) version is available when invoking
python -m niquests.help
and propose it for installation. -
Add the possibility to disable a specific protocol (e.g. HTTP/2, and/or HTTP/3) when constructing
Session
.
Like so:s = Session(disable_http2=..., disable_http3=...)
both options are set toFalse
, thus letting them be enabled.
urllib3.future does not permit to disable HTTP/1.1 for now. -
Support passing a single
str
toauth=...
in addition to actually supported types. It will be treated as a
Bearer token, by default to theAuthorization
header. It's a shortcut. You may keep your own token prefix in a given
string (e.g. if not Bearer). -
Added
MultiplexingError
exception for anything related to failure with a multiplexed connection. -
Added async support through
AsyncSession
that utilizes an underlying thread pool.from niquests import AsyncSession import asyncio from time import time async def emit() -> None: responses = [] async with AsyncSession(multiplexed=True) as s: responses.append(await s.get("https://pie.dev/get")) responses.append(await s.get("https://pie.dev/head")) await s.gather() print(responses) async def main() -> None: foo = asyncio.create_task(emit()) bar = asyncio.create_task(emit()) await foo await bar if __name__ == "__main__": before = time() asyncio.run(main()) print(time() - before)
Or without
multiplexing
if you want to keep multiple connections open per host per request.from niquests import AsyncSession import asyncio from time import time async def emit() -> None: responses = [] async with AsyncSession() as s: responses.append(await s.get("https://pie.dev/get")) responses.append(await s.get("https://pie.dev/head")) print(responses) async def main() -> None: foo = asyncio.create_task(emit()) bar = asyncio.create_task(emit()) await foo await bar if __name__ == "__main__": before = time() asyncio.run(main()) print(time() - before)
You may disable concurrent threads by setting
AsyncSession.no_thread = True
.
Security
- Certificate revocation verification may not be fired for subsequent requests in a specific condition (redirection).
Version 3.1.4
3.1.4 (2023-10-23)
Fixed
- Static type checker not accepting iterable[str] for data. A fix in urllib3.future allows it since v2.1.902.
- Unattended override of manually provided Authorization if
.netrc
existed with an eligible entry.
Taken from closed PR psf#6555 and initially raised in psf#3929
Added
- oheaders property in
Request
, andPreparedRequest
in addition toResponse
.
Version 3.1.3
3.1.3 (2023-10-19)
Fixed
- oheaders from a Response contains
Set-Cookie
entries when it should not. - Static type checker not accepting list[str] in values for argument param.
- Static type checker not accepting Iterable[bytes] for data.
- Function proxy_bypass_registry for Windows may be fooled by insufficient control on our end.
Patch taken from idle upstream PR psf#6302 - SSLError message related to the certificate revocation could print
None
instead ofunspecified
for the reason.
Changed
- Allow setting
None
in max_size for SharableLimitedDict to remove limits. - Using
RLock
instead ofLock
in SharableLimitedDict, and InMemoryRevocationStatus classes.
Misc
- Missing assert statements for test test_header_validation.
- Unrelated warnings are now silent in our test suite.
- Unexpected warning now trigger an error in our test suite.
- Removed
tests.compat
. - Removed
test-readme
,flake8
, andpublish
from Makefile.
Added
- Extra-dist install
http3
to force install HTTP/3 support in your environment if not present. - Extra-dist install
ocsp
to force install certificate revocation support in your environment if not present.
Version 3.1.2
3.1.2 (2023-10-16)
Fixed
- Static type checker not accepting list[str] in values for argument data.
Misc
- Changed the documentation theme by furo.
Added
-
IPv6 support in the
NO_PROXY
environment variable or in the proxies (key no_proxy) argument.
Patch taken from idle upstream PR psf#5953 -
Preemptively register a website to be HTTP/3 capable prior to the first TLS over TCP handshake.
You can do so by doing like:from niquests import Session s = Session() s.quic_cache_layer.add_domain("cloudflare.com")
-
Passed data will be converted to form-data if headers have a Content-Type header and is set to
multipart/form-data
.
Otherwise, by default, it is still urlencoded. If you specified a boundary, it will be used, otherwise, a random one will
be generated.
Version 3.1.1
3.1.1 (2023-10-11)
Fixed
- Fixed
Transfer-Encoding
wrongfully added to headers when body is actually of length 0. Due to the ambiguous return ofsuper_len
in niquests internals. - Fixed accepting three-valued tuple for Timeout (connect, read, total) in addition to known (connect, read) tuple.
Version 3.1.0
Release History
3.1.0 (2023-10-10)
Misc
- Static typing has been improved to provide a better development experience.
Added
-
Certificate revocation verification via the OCSP protocol.
This feature is broadly available and is enabled by default when
verify=True
.
We decided to follow what browsers do by default, so Niquests follows by being non-strict.
OCSP responses are expected to arrive in less than 200ms, otherwise ignored (e.g. OCSP is dropped).
Niquests keep in-memory the results until the size exceeds 2,048 entries, then an algorithm chooses an entry
to be deleted (oldest request or the first one that ended in error).You can at your own discretion enable strict OCSP checks by passing the environment variable
NIQUESTS_STRICT_OCSP
with anything inside but0
. In strict mode, the maximum delay for response passes from 200ms to 1,000ms and
raises an error or explicit warning.In non-strict mode, this security measure will be deactivated automatically if your usage is unreasonable.
e.g. Making a hundred of requests to a hundred of domains, thus consuming resources that should have been
allocated to browser users. This was made available for users with a limited target of domains to get
a complementary security measure.Unless in strict mode, the proxy configuration will be respected when given, as long as it specifies
a plainhttp
proxy. This is meant for people who want privacy.This feature may not be available if the
cryptography
package is missing from your environment.
Verify the availability after Niquests upgrade by runningpython -m niquests.help
.There is several downside to using OCSP, Niquests knows it. It is not a silver bullet solution. But better than nothing.
It does not apply to HTTPS proxies themselves. For now. -
Add property
ocsp_verified
in bothPreparedRequest
, andResponse
to have a clue on the post handshake verification.Will be
None
if no verification took place,True
if the verification leads to confirmation from the OCSP server
that the certificate is valid,False
otherwise.
Changed
- Bump lower version requirement for
urllib3.future
to 2.1.900 to ensure compatibility with newer features. - Internal in-memory QUIC capabilities is now thread-safe and limited to 12,288 entries.
- Pickling a
Session
object no longer dumps adapters or the QUIC in-memory capabilities, they are reset on setstate.
Fixed
conn_info
was unset if the response came after a redirect.
Release 3.0.2
3.0.2 (2023-10-01)
Changed
- niquests.help show more information about direct dependencies.
- urllib3.future minimal version was raised to 2.0.936 due to an important fix on the QUIC layer.
- wassima minimal version was raised to 1.0.1 in order to support certifi as a fallback in rare cases.
Version 3.0.1
3.0.1 (2023-09-26)
Fixed
- Method
head
not acceptingallow_redirect
named argument. PreparedRequest
did not uppercase the HTTP verb when constructed manually.
Changed
- Minor code refactor in the
text
, andjson
methods within theResponse
class to be more concise.