Motivation
Raised by @cervelas in discussion #5876: httpx has been effectively unmaintained since November 2024 and the maintainer has disabled new GitHub issues. The community fork httpxyz (blog post, one month in) is an active drop-in replacement with identical APIs and exceptions, plus accumulated bug fixes and performance improvements in httpcorexyz.
The primary driver is maintenance posture, not bugs. NiceGUI's actual httpx usage barely exercises the areas httpxyz has improved (see impact analysis below), so this is not urgent — but it is the right direction once we accept a public-API break.
Impact analysis
NiceGUI uses httpx in three patterns:
ASGITransport for nicegui.testing (user_plugin.py, user_simulation.py) – short-circuits the transport layer. None of httpxyz's pool/HTTP/2/SOCKS5/proxy fixes apply.
- One-shot
httpx.get() / httpx.Client() in tests and examples – negligible.
AsyncClient in air.py (On Air relay) – the only place pooling and concurrency matter. We don't use HTTP/2, SOCKS5, or proxies, so most fixes are moot. The 3.3× lock-acquire improvement is real but the relay's bottleneck is the WebSocket hop, not local httpx overhead.
Net: switching is low-risk and low-reward for users today. Justified by long-term maintainability, not performance or correctness.
Why this is breaking
- Public API surface:
nicegui.testing.User and UserDownload expose httpx.AsyncClient and httpx.Response in their type signatures. Users writing tests against the User fixture import httpx directly and rely on these types.
- Transitive install: some users list
nicegui in requirements.txt and rely on it pulling in httpx for their own code (acknowledged in discussion Making HTTPX an optional dependency #5876). Dropping httpx from our deps will break those installs without warning.
Both reasons argue for landing this in 4.0, not in a minor release.
Proposed strategy
- Native import: switch to
import httpxyz everywhere (not import httpxyz as httpx). Cleaner long-term and avoids future readers wondering why we shadow.
- Swap public API types: re-type
nicegui.testing signatures to httpxyz.AsyncClient / httpxyz.Response. Users follow the same one-line swap.
- Drop
httpx from pyproject.toml and add httpxyz. Call out the transitive-install break in the 4.0 changelog and migration guide.
Re-evaluate before committing
Since 4.0 is still a few months out, revisit closer to the cut: is httpxyz still active, has the original httpx resumed maintenance, or has another fork emerged as the de-facto successor? We only want to take the public-API break once — migrating again in 5.0 would be embarrassing.
Motivation
Raised by @cervelas in discussion #5876:
httpxhas been effectively unmaintained since November 2024 and the maintainer has disabled new GitHub issues. The community forkhttpxyz(blog post, one month in) is an active drop-in replacement with identical APIs and exceptions, plus accumulated bug fixes and performance improvements inhttpcorexyz.The primary driver is maintenance posture, not bugs. NiceGUI's actual httpx usage barely exercises the areas httpxyz has improved (see impact analysis below), so this is not urgent — but it is the right direction once we accept a public-API break.
Impact analysis
NiceGUI uses httpx in three patterns:
ASGITransportfornicegui.testing(user_plugin.py,user_simulation.py) – short-circuits the transport layer. None of httpxyz's pool/HTTP/2/SOCKS5/proxy fixes apply.httpx.get()/httpx.Client()in tests and examples – negligible.AsyncClientinair.py(On Air relay) – the only place pooling and concurrency matter. We don't use HTTP/2, SOCKS5, or proxies, so most fixes are moot. The 3.3× lock-acquire improvement is real but the relay's bottleneck is the WebSocket hop, not local httpx overhead.Net: switching is low-risk and low-reward for users today. Justified by long-term maintainability, not performance or correctness.
Why this is breaking
nicegui.testing.UserandUserDownloadexposehttpx.AsyncClientandhttpx.Responsein their type signatures. Users writing tests against theUserfixture importhttpxdirectly and rely on these types.niceguiinrequirements.txtand rely on it pulling inhttpxfor their own code (acknowledged in discussion Making HTTPX an optional dependency #5876). Droppinghttpxfrom our deps will break those installs without warning.Both reasons argue for landing this in 4.0, not in a minor release.
Proposed strategy
import httpxyzeverywhere (notimport httpxyz as httpx). Cleaner long-term and avoids future readers wondering why we shadow.nicegui.testingsignatures tohttpxyz.AsyncClient/httpxyz.Response. Users follow the same one-line swap.httpxfrompyproject.tomland addhttpxyz. Call out the transitive-install break in the 4.0 changelog and migration guide.Re-evaluate before committing
Since 4.0 is still a few months out, revisit closer to the cut: is
httpxyzstill active, has the originalhttpxresumed maintenance, or has another fork emerged as the de-facto successor? We only want to take the public-API break once — migrating again in 5.0 would be embarrassing.