[HTTPXodus] Consider migrating from `httpx` to `httpx2` (the actively maintained fork)
️ This issue is part of HTTPXodus, a community effort to help major projects plan their path off the stalled
httpxstable line ontohttpx2, the actively maintained fork by Pydantic Services (with original httpx author Tom Christie involved). One coordinated issue per project — no spam, no drive-by PRs.
Background — what happened to httpx
httpx is one of the most important HTTP clients in the Python ecosystem (370k+ dependent repositories). However:
- The last stable release is 0.28.1 (December 2024) — over 20 months ago.
- For most of 2025 the repository was dormant; maintenance trackers (e.g. Snyk) now flag it as inactive.
- Encouragingly, the project has recently resumed activity:
1.0.dev4–dev6shipped between 2026-08-19 and 2026-08-31. A 1.0 is clearly in the works, but there is no committed date for a stable 1.0, and the dev line carries breaking changes.
Meanwhile, the ecosystem has already begun moving: Starlette, the Anthropic Python SDK (v1.0), and the MCP Python SDK (2.0) have migrated to httpx2; FastAPI supports it as a test dependency; the OpenAI Python SDK supports it as an optional extra.
What is httpx2
httpx2 is a fork of httpx 0.28.1 maintained by Pydantic Services Inc., with Tom Christie involved. It is actively released (v2.0.0 → v2.12.0 since May 2026) and keeps a compatible public API:
import httpx2
r = httpx2.get("https://example.org")
Why migrate — the benefits
- Active maintenance — regular releases, reviewed PRs, and a funded maintainer team, versus an uncertain stable-release timeline.
- Modern TLS by default — certificates are verified against the OS trust store instead of the bundled
certifi, removing a common source of stale-CA issues. - New capabilities — built-in Server-Sent Events (
client.sse()) and WebSocket support (httpx2[ws]), without extra dependencies. - Ecosystem alignment — as frameworks and SDKs migrate, staying on httpx increasingly means duplicate HTTP stacks in one dependency tree.
Risks of staying on httpx
- Security exposure: no stable-line releases means no stable-line security fixes. If a CVE lands in 0.28.x today, there is no maintained branch to patch it.
- Dependency conflicts: packages that pin
httpx<1.0already conflict with migrated peers; the longer the wait, the worse the resolver pain for downstream users. - Compounding migration cost: the gap between 0.28.x and whatever 1.0 becomes keeps growing; migrating to httpx2 now is a small, well-documented step (official migration guide: https://pydantic.dev/docs/httpx2/get-started/migration/).
What migration could look like here
FastChat's httpx usage is unusually narrow — this is a genuinely small migration:
- A single call site. Reviewing the serving stack,
httpxis imported in exactly one place:fastchat/serve/openai_api_server.py. Everywhere else the project makes HTTP calls (the controller, the non-streaming completion path, the Gradio servers,api_provider.py, the monitor/judge scripts) it usesaiohttporrequestsinstead. - It sits on the core streaming path. In
generate_completion_stream(payload, worker_addr)the OpenAI-compatible API server opens anhttpx.AsyncClient, thenclient.stream("POST", worker_addr + "/worker_generate_stream", ...)and iterates the body withasync for raw_chunk in response.aiter_raw():, splitting on ab"\0"delimiter. So this is the request path that streams completions from a model worker back to the API client — not an edge tool. - Async only, internal only. No
httpxtypes leak intofschat's public Python API; it's purely internal server→worker communication. (Note the non-streaming sibling path in the same file usesfetch_remote(...)overaiohttp, so the codebase already mixes the two clients.) - Unpinned dependency.
pyproject.tomldeclares plain"httpx"(no version bound) andrequires-python = ">=3.8". The lack of an<1.0pin means no resolver conflict today, but it also means FastChat will silently pick up httpx 1.0's breaking changes the day it ships — an argument for choosing the HTTP layer deliberately rather than by accident.
Because httpx is confined to one internal function, either option is cheap; the deciding factor is your Python floor:
Option A — dual support (recommended):
fschatis a published library and currently supports Python ≥3.8, while httpx2 requires ≥3.10. To avoid dropping 3.8/3.9 users, prefer httpx2 when present and fall back to httpx:try: import httpx2 as httpx except ModuleNotFoundError: import httpxwith
httpx2; python_version >= "3.10"added as an optional/extra dependency. The public API used here (AsyncClient,client.stream,aiter_raw,timeout) is unchanged in httpx2, so the streaming path works identically under either import.Option B — hard switch: if you're willing to bump
requires-pythonto>=3.10(reasonable in 2026 — 3.8 and 3.9 are both EOL), the switch is trivial: replace"httpx"with"httpx2"inpyproject.tomland change the single import inopenai_api_server.py. Given there's only one call site, this is close to a one-line change.
⚠️ One caveat worth calling out: httpx2 verifies TLS against the OS trust store instead of the bundled certifi. FastChat deployments that front worker endpoints with TLS behind corporate proxies, or run in minimal containers relying on certifi's CA bundle, may need SSL_CERT_FILE or system CA configuration. Worth a line in the deployment docs either way.
Notes
- No existing httpx2 issue/PR in this repo as of 2026-09-02 (checked via GitHub issue search — zero competition).
- Version constraint:
httpxis declared unpinned;requires-python = ">=3.8". Any migration must either keep 3.8/3.9 working (Option A) or explicitly drop them (Option B). - Project activity — honest assessment. FastChat's own development has slowed considerably: the latest release is v0.2.36 (2024-02-11), the most recent commit on
mainis a minorconstants.pyupdate dated 2025-06-02, and the repo was last pushed 2026-05-01 (a constants.py bump, #3733). The hosted Chatbot Arena also moved to a separate site (LMArena) in September 2024, leaving this repo as primarily the legacy open-source serving/eval stack. So while thehttpxchange itself is tiny and safe, the realistic value of migrating is modest and depends on whether the maintainers intend to keep the serving stack current. We're flagging it for completeness and because the unpinnedhttpxleaves the project exposed to httpx 1.0's breaking changes — but we fully understand if the answer is "we'll wait for httpx 1.0 stable."
Happy to open a PR for either option if the maintainers are interested — and equally happy to close this if you'd rather wait for httpx 1.0 stable. No pressure; the goal is just to make sure the decision is an informed one.
Source: lm-sys/FastChat