Skip to content

Migrate from httpx to httpxyz #6024

@falkoschindler

Description

@falkoschindler

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:

  1. 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.
  2. One-shot httpx.get() / httpx.Client() in tests and examples – negligible.
  3. 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

  1. Native import: switch to import httpxyz everywhere (not import httpxyz as httpx). Cleaner long-term and avoids future readers wondering why we shadow.
  2. Swap public API types: re-type nicegui.testing signatures to httpxyz.AsyncClient / httpxyz.Response. Users follow the same one-line swap.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedStatus: Blocked by another issue or dependencydependenciesType/scope: Third party libraries

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions