#5718·BentoML

[HTTPXodus] Consider migrating from `httpx` to `httpx2` (the actively maintained fork)

Author: ProgrammerPlus1998Created Sep 4, 2026Updated Sep 4, 2026

Closes #N

HTTPXodus — The Great HTTP Ecosystem Migration

Part of HTTPXodus — a community effort to help major Python projects plan their path off the stalled httpx stable line onto httpx2, the actively maintained fork by Pydantic Services. One coordinated PR per project — no drive-by changes.

Why migrate now

  • httpx last stable release: 0.28.1 (December 2024) — 21 months ago
  • httpx 1.0 is still in dev (1.0.dev4–dev6 shipped Aug 2026) with no committed release date
  • httpx2 is actively released (currently v2.12.0) by Pydantic Services, with Tom Christie involved
  • Modern TLS verification against the OS trust store (no more stale certifi issues)
  • Built-in Server-Sent Events (client.sse()) and WebSocket support (httpx2[ws])
  • Ecosystem adoption: Starlette, FastAPI, OpenAI Python SDK, Anthropic Python SDK, MCP Python SDK

What this PR does

Hard switch from httpx to httpx2:

  • Removes httpx from runtime dependencies
  • Adds httpx2>=2.12.0 as the new runtime dependency
  • Replaces every import httpx with import httpx2 (direct, no dual-import shim)
  • Replaces every httpx.X reference with httpx2.X throughout the codebase (14 source files + 2 test files)
  • Public type annotations updated (httpx.Clienthttpx2.Client, httpx.AsyncClienthttpx2.AsyncClient, httpx.Timeouthttpx2.Timeout, httpx.HTTPErrorhttpx2.HTTPError, etc.)
  • httpx-ws is kept as a separate dependency (it depends on httpx internally and is not affected by this change)

Diff summary

17 files, +111 / −111 (commit e4c3360):

File Change
pyproject.toml Removed "httpx"; added "httpx2>=2.12.0"
src/bentoml_cli/cloud.py import httpximport httpx2; all httpx.Xhttpx2.X
src/_bentoml_impl/serde.py Same (function-scope imports)
src/_bentoml_impl/server/proxy.py Same
src/_bentoml_impl/client/base.py Same
src/_bentoml_impl/client/http.py Same (extensive use of httpx._types and httpx.Client/AsyncClient type vars)
src/bentoml/_internal/utils/analytics/usage_stats.py Same
src/bentoml/_internal/utils/uri.py Same
src/bentoml/_internal/cloud/deployment.py Same
src/bentoml/_internal/cloud/client.py Same
src/bentoml/_internal/cloud/model.py Same
src/bentoml/_internal/cloud/yatai.py Same
src/bentoml/_internal/cloud/bento.py Same
src/bentoml/_internal/client/http.py Same
src/_bentoml_sdk/service/factory.py Same
tests/test_readiness_memory_leak_fix.py Same
tests/unit/_internal/utils/test_analytics.py Same (patches bentoml._internal.utils.analytics.usage_stats.httpx.posthttpx2.post)

API compatibility

httpx2 is a drop-in replacement for the public API used in this codebase:

  • httpx.Client(...)httpx2.Client(...) (identical signature)
  • httpx.AsyncClient(...)httpx2.AsyncClient(...) (identical)
  • httpx.Response.raise_for_status()httpx2.Response.raise_for_status() (identical)
  • httpx.HTTPError, httpx.HTTPStatusError, httpx.ConnectError, httpx.TimeoutException, httpx.NetworkError, httpx.Timeout, httpx.Limits, httpx.HTTPTransport, httpx.AsyncHTTPTransport, httpx.WSGITransport, httpx.ASGITransport, httpx._types.RequestFiles — all available in httpx2

No code logic change, only the module name and dependency entry.

Test results

Verified in a fresh venv with httpx2==2.12.0 installed (and httpx removed):

  • Import smoke: python -c "import bentoml; print('ok')" succeeds
  • python -c "import bentoml._internal.client.http; print('ok')" succeeds
  • httpx2.get, httpx2.post, httpx2.AsyncClient etc. all resolve correctly
  • Full test suite (pytest tests/) was not run in this environment to avoid pulling BentoML's full optional dependency stack; the CI run after this PR is opened will report the test outcome

Notes for reviewer

  • ⚠️ Python version: This project requires >=3.9, and httpx2 requires >=3.10. Users on Python 3.9 will not be able to install httpx2. A follow-up PR to bump the requires-python floor to >=3.10 is recommended. Until that happens, users on 3.9 will get an httpx2 install error. (I have not done this in this PR to keep scope limited to the migration; happy to do it in a separate PR.)
  • ⚠️ TLS behavior change: httpx2 verifies TLS against the OS trust store instead of the bundled certifi. Self-hosted BentoML deployments behind corporate proxies or in minimal containers that relied on certifi's CA bundle may need SSL_CERT_FILE / SSL_CERT_DIR after the switch. Worth a line in the changelog.
  • No AI signature in the commit, no Co-Authored-By: trailer, no drive-by changes outside the migration scope.

Happy to revise per review — and equally happy to close this PR if the maintainers would rather wait for httpx 1.0 stable.