Skip to content

Releases: jawah/niquests

Version 3.2.2

08 Nov 08:49
d4a947a
Compare
Choose a tag to compare

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 our HTTPAdapter for advanced users.
    This limit was changed due to a constraint in qh3, 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

06 Nov 19:20
0e112b6
Compare
Choose a tag to compare

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 our HTTPAdapter for advanced users.

Version 3.2.0

05 Nov 18:46
17678b8
Compare
Choose a tag to compare

3.2.0 (2023-11-05)

Changed

  • Changed method raise_for_status in class Response 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 through Session(multiplexed=True), each Response object will
    be 'lazy' loaded. Accessing anything from the returned Response will block the code until the target response is retrieved.
    Use Session.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 within urllib3.future. Unfortunately, this feature may not be available depending on your platform.
    Passing cert=(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 to False, thus letting them be enabled.
    urllib3.future does not permit to disable HTTP/1.1 for now.

  • Support passing a single str to auth=... in addition to actually supported types. It will be treated as a
    Bearer token, by default to the Authorization 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

23 Oct 12:04
92c7548
Compare
Choose a tag to compare

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, and PreparedRequest in addition to Response.

Version 3.1.3

19 Oct 07:21
7de4041
Compare
Choose a tag to compare

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 of unspecified for the reason.

Changed

  • Allow setting None in max_size for SharableLimitedDict to remove limits.
  • Using RLock instead of Lock 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, and publish 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

16 Oct 11:49
5cb7c7b
Compare
Choose a tag to compare

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

11 Oct 18:39
d616667
Compare
Choose a tag to compare

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 of super_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

10 Oct 11:53
352d896
Compare
Choose a tag to compare

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 but 0. 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 plain http 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 running python -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 both PreparedRequest, and Response 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

01 Oct 08:07
43bfa77
Compare
Choose a tag to compare

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

26 Sep 12:10
Compare
Choose a tag to compare

3.0.1 (2023-09-26)

Fixed

  • Method head not accepting allow_redirect named argument.
  • PreparedRequest did not uppercase the HTTP verb when constructed manually.

Changed

  • Minor code refactor in the text, and json methods within the Response class to be more concise.