Metadata-Version: 2.4 Name: urllib3-future Version: 2.17.902 Summary: urllib3.future is a powerful HTTP 1.1, 2, and 3 client with both sync and async interfaces Project-URL: Changelog, https://github.com/jawah/urllib3.future/blob/main/CHANGES.rst Project-URL: Documentation, https://urllib3future.readthedocs.io Project-URL: Code, https://github.com/jawah/urllib3.future Project-URL: Issue tracker, https://github.com/jawah/urllib3.future/issues Author-email: Andrey Petrov Maintainer-email: "Ahmed R. TAHRI" License-Expression: MIT License-File: LICENSE.txt Keywords: async,concurrent,dns,dns-over-https,dns-over-quic,dns-over-tls,doh,doq,dot,dou,filepost,http,httplib,https,multiplexed,pooling,ssl,tasksafe,threadsafe,urllib Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 Classifier: Programming Language :: Python :: 3.14 Classifier: Programming Language :: Python :: Free Threading :: 4 - Resilient Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Software Development :: Libraries Requires-Python: >=3.7 Requires-Dist: h11<1.0.0,>=0.11.0 Requires-Dist: jh2<6.0.0,>=5.0.3 Requires-Dist: qh3<2.0.0,>=1.5.4; (platform_python_implementation != 'CPython' or python_full_version > '3.7.10') and (platform_system == 'Darwin' or platform_system == 'Windows' or platform_system == 'Linux') and (platform_machine == 'x86_64' or platform_machine == 's390x' or platform_machine == 'armv7l' or platform_machine == 'ppc64le' or platform_machine == 'ppc64' or platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'arm64' or platform_machine == 'ARM64' or platform_machine == 'x86' or platform_machine == 'i686' or platform_machine == 'riscv64' or platform_machine == 'riscv64gc') and (platform_python_implementation == 'CPython' or (platform_python_implementation == 'PyPy' and python_version < '3.12')) Provides-Extra: brotli Requires-Dist: brotli>=1.0.9; (platform_python_implementation == 'CPython') and extra == 'brotli' Requires-Dist: brotlicffi>=0.8.0; (platform_python_implementation != 'CPython') and extra == 'brotli' Provides-Extra: qh3 Requires-Dist: qh3<2.0.0,>=1.5.4; extra == 'qh3' Provides-Extra: secure Provides-Extra: socks Requires-Dist: python-socks<=2.6.1,>=2.0; extra == 'socks' Provides-Extra: ws Requires-Dist: wsproto<2,>=1.2; extra == 'ws' Provides-Extra: zstd Requires-Dist: zstandard>=0.18.0; (python_version < '3.14') and extra == 'zstd' Description-Content-Type: text/markdown

urllib3.future logo

PyPI Version Python Versions
urllib3.future is as BoringSSL is to OpenSSL but to urllib3 (but with available support!)
✨🍰 Enjoy HTTP like its 2025 🍰✨
💰 Promotional offer, get everything and more for 40k 0$!
Wondering why and how this fork exist? Why urllib3 is stuck? Take a peek at this article!

⚡ urllib3.future is a powerful, *user-friendly* HTTP client for Python.
⚡ urllib3.future goes beyond supported features while remaining compatible.
⚡ urllib3.future brings many critical features that are missing from both the Python standard libraries **and urllib3**: - Async. - Task safety. - Thread safety. - Happy Eyeballs. - Connection pooling. - Unopinionated about OpenSSL. - Client-side SSL/TLS verification. - Highly customizable DNS resolution. - File uploads with multipart encoding. - DNS over UDP, TLS, QUIC, or HTTPS. DNSSEC protected. - Helpers for retrying requests and dealing with HTTP redirects. - Automatic Keep-Alive for HTTP/1.1, HTTP/2, and HTTP/3. - Support for gzip, deflate, brotli, and zstd encoding. - Support for Python/PyPy 3.7+, no compromise. - Automatic Connection Upgrade / Downgrade. - Early (Informational) Responses / Hints. - HTTP/1.1, HTTP/2 and HTTP/3 support. - WebSocket over HTTP/2+ (RFC8441). - Proxy support for HTTP and SOCKS. - Post-Quantum Security with QUIC. - Detailed connection inspection. - HTTP/2 with prior knowledge. - Support for free-threaded. - Server Side Event (SSE). - Multiplexed connection. - Mirrored Sync & Async. - Trailer Headers. - Amazingly Fast. - WebSocket. urllib3.future is powerful and easy to use: ```python >>> import urllib3 >>> pm = urllib3.PoolManager() >>> resp = pm.request("GET", "https://httpbin.org/robots.txt") >>> resp.status 200 >>> resp.data b"User-agent: *\nDisallow: /deny\n" >>> resp.version 20 ``` or using asyncio! ```python import asyncio import urllib3 async def main() -> None: async with urllib3.AsyncPoolManager() as pm: resp = await pm.request("GET", "https://httpbin.org/robots.txt") print(resp.status) # 200 body = await resp.data print(body) # # b"User-agent: *\nDisallow: /deny\n" print(resp.version) # 20 asyncio.run(main()) ``` ## Installing urllib3.future can be installed with [pip](https://pip.pypa.io): ```bash python -m pip install urllib3.future ``` You either do ```python import urllib3 ``` Or... ```bash URLLIB3_NO_OVERRIDE=1 python -m pip install urllib3.future --no-binary urllib3.future ``` ```python import urllib3_future ``` ## Notes / Frequently Asked Questions - **It's a fork** ⚠️ Installing urllib3.future shadows the actual urllib3 package. The semver will always be like _MAJOR.MINOR.9PP_ like 2.0.941, the patch node is always greater or equal to 900. Support for bugs or improvements is served in this repository. We regularly sync this fork with the main branch of urllib3/urllib3 against bugfixes and security patches if applicable. This package is a real drop-in replacement, 100% compatible with its predecessor. Found anything not compatible? We'll fix it. - **Why replacing urllib3 when it is maintained?** Progress does not necessarily mean to be a revisionist, first we need to embrace what was graciously made by our predecessors. So much knowledge has been poured into this that we must just extend it. We attempted to participate in urllib3 development only to find that we were in disagreement on how to proceed. It happens all the time, even on the biggest projects out there (e.g. OpenSSL vs BoringSSL or NSS or LibreSSL...) - **OK, but I got there because I saw that urllib3 was replaced in my environment!** Since Forks are allowed (fortunately for us); It how package manager do things. We know how sensible this matter is, this is why we are obligated to ensure the highest level of compatibility and a fast support in case anything happen. We are probably going to be less forgiven in case of bugs than the original urllib3. For understandable reasons, we know. The matter is taken with utmost seriousness and everyone can inspect this package at will. We regularly test this fork against the most used packages (that depend on urllib3, especially those who plunged deep into urllib3 internals). Finally, rare is someone "fully aware" of their transitive dependencies. And "urllib3" is forced into your environments regardless of your preferences. - **Wasn't there any other solution than having an in-place fork?** We assessed many solutions but none were completely satisfying. We agree that this solution isn't perfect and actually put a lot of pressure on us (urllib3-future). Here are some of the reasons (not exhaustive) we choose to work this way: > **A)** Some major companies may not be able to modify production code but can change/swap dependencies. > > **B)** urllib3-future's main purpose is to fuel Niquests, which is itself a drop-in replacement for Requests. > More than 100 commonly used packages plug into Requests, but their code invokes urllib3 directly. > We cannot fork those 100+ projects to patch urllib3 usage - it's impossible given our means. > Requests trapped us, and there should be a way to escape the "migrate to another HTTP client" cycle > that reinvents basic functionality. > > **C)** We don't have to reinvent the wheel. > > **D)** Some of our partners noticed that HTTP/1 is being disabled by some web services in favor of HTTP/2+. > This fork can unblock them at almost zero cost. - **OK... then what do I gain from this?** 1. It is faster than its counterpart, we measured gain up to 2X faster in a multithreaded environment using a http2 endpoint. 2. It works well with gevent / does not conflict. We do not use the standard queue class from stdlib as it does not fit http2+ constraints. 3. Leveraging recent protocols like http2 and http3 transparently. Code and behaviors does not change one bit. 4. You do not depend on the standard library to emit http/1 requests, and that is actually a good news. http.client has numerous known flaws but cannot be fixed as we speak. (e.g. urllib3 is based on http.client) 5. There a tons of other improvement you may leverage, but for that you will need to migrate to Niquests or update your code to enable specific capabilities, like but not limited to: "DNS over QUIC, HTTP" / "Happy Eyeballs" / "Native Asyncio" / "Advanced Multiplexing". 6. Non-blocking IO with concurrent streams/requests. And yes, transparently. 7. It relaxes some constraints established by upstream in their version 2, thus making it easier to upgrade from version 1. - **Is this funded?** Yes! We have some funds coming in regularly to ensure its sustainability. - **How can I restore urllib3 to the "legacy" version?** You still have a choice on your best discretion. Let's say you want to install Niquests and keep BOTH urllib3 and urllib3-future, do:
👆 pip ```shell URLLIB3_NO_OVERRIDE=1 pip install niquests --no-binary urllib3-future ```
👆 Poetry ```shell export URLLIB3_NO_OVERRIDE=1 poetry config --local installer.no-binary urllib3-future poetry add niquests ``` or in a one-liner shortcut: ```shell URLLIB3_NO_OVERRIDE=1 POETRY_INSTALLER_NO_BINARY=urllib3-future poetry add niquests ```
👆 PDM ```shell URLLIB3_NO_OVERRIDE=1 PDM_NO_BINARY=urllib3-future pdm add niquests ``` or with a persistent configuration (via pyproject.toml): ```toml [tool.pdm.resolution] no-binary = "urllib3-future" ``` then: ```shell export URLLIB3_NO_OVERRIDE=1 pdm add niquests ```
👆 UV Add to your pyproject.toml: ```toml [tool.uv] no-binary-package = ["urllib3-future"] ``` then: ```shell export URLLIB3_NO_OVERRIDE=1 uv add niquests # sync / pip / ... ```
This applies to every package you wish to install and brings indirectly urllib3-future. This enforces strict separation between urllib3 and urllib3-future. You will lose the perfect in-place backward compatibility without further deep compatibility hacks. - **Can you guarantee us that everything will go smooth?** Guarantee is a strong word with a lot of (legal) implication. We cannot offer a "guarantee". Yet, we answer and solve issues in a timely manner as you may have seen in our tracker. We take a lot of precaution with this fork, and we welcome any contribution at the sole condition that you don't break the compatibility between the projects. Namely, urllib3 and urllib3-future. Every software is subject to bugs no matter what we do. This being said, rest assured, we kept all the tests from urllib3 to ensure that what was guaranteed by upstream is also carefully watched down there. See the CI/pipeline for yourself. In addition to that, we enforced key integration tests to watch how urllib3-future acts with some critical projects. Top-priorities issues are those impacting users with the "shadowing" part. Meaning, if a user is suffering an error or something that ends up causing an undesirable outcome from a third-party library that leverage urllib3. - **Can I contribute to this?** Yes! But keep in mind that it is going to be hard to contribute as we have huge constraints. Some of them: Python 3.7+, OpenSSL <1.1.1,>1, LibreSSL, Downstream Perfect Compat, API Compatibility with urllib3, and so on. If you like a good challenge, then this project will definitely suit you. Make sure everything passes before submitting a PR, unless you need guidance on a specific topic. After applying your patch, run (Unix, Linux): ```shell ./ci/run_legacy_openssl.sh ./ci/run_legacy_libressl.sh ./ci/run_dockerized.sh nox -s test-3.11 ``` replace the `3.11` part in `test-3.11` by your interpreter version. If the tests all passes, then it is a firm good start. Complete them with: ```shell nox -s downstream_requests nox -s downstream_niquests nox -s downstream_boto3 nox -s downstream_sphinx ``` Finally make sure to fix any lint errors: ```shell nox -s lint ``` - **OS Package Managers, beware!** Fellow OS package maintainers: you cannot _simply_ build and ship this package to your package registry. As it override `urllib3` and due to its current criticality, you'll have to set: `URLLIB3_NO_OVERRIDE=1 python -m build`. Set `URLLIB3_NO_OVERRIDE` variable with any value. It will prevent the override. ## Compatibility with downstream Just adding `urllib3-future` in your dependency is enough. e.g. I want `requests` to be use this package. ```shell python -m pip install requests python -m pip install urllib3.future ``` or just in your dependencies ``` [project] name = "my-upgraded-project" version = "0.1.0" description = "Add your description here" requires-python = ">=3.13" dependencies = [ "requests", "urllib3-future", ] ``` Nowadays, we suggest using the package [**Niquests**](https://github.com/jawah/niquests) as a drop-in replacement for **Requests**. It leverages urllib3.future capabilities appropriately. ## Testing To ensure that we serve HTTP/1.1, HTTP/2 and HTTP/3 correctly we use containers that simulate a real-world server that is not made with Python. Although it is not made mandatory to run the test suite, it is strongly recommended. You should have docker installed and the compose plugin available. The rest will be handled automatically. ```shell python -m pip install nox nox -s test-3.11 ``` The nox script will attempt to start a Traefik server along with a httpbin instance. Both Traefik and httpbin are written in golang. You may prevent the containers from starting by passing the following environment variable: ```shell TRAEFIK_HTTPBIN_ENABLE=false nox -s test-3.11 ``` ## Documentation urllib3.future has usage and reference documentation at [urllib3future.readthedocs.io](https://urllib3future.readthedocs.io). ## Contributing urllib3.future happily accepts contributions. ## Security Disclosures To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure with maintainers. ## Sponsorship If your company benefits from this library, please consider sponsoring its development.