Replace httpx and httpx-sse with httpx2

Merged
KL
4mo ago
+1029-948

Summary

Swaps the httpx + httpx-sse dependencies for httpx2 >=2.5.0. httpx2 is the next-generation httpx fork with server-sent events support built in, so the separate httpx-sse dependency is no longer needed.

Changes

  • Replace httpx>=0.27.1,<1.0.0 + httpx-sse>=0.4 with httpx2>=2.5.0 in the SDK and the example projects (lockfile regenerated).
  • Rewrite the SSE transports against httpx2's API: aconnect_sse(...) → client.stream(...) / client.sse(...) wrapped in EventSource, and iterate the EventSource directly instead of .aiter_sse().
  • Document the swap as a v2 breaking change in docs/migration.md and docs/whats-new.md; update the docs, README, and example sources.

Intentional behavior changes

  • SSE GET streams send Accept: application/json, text/event-stream (previously exactly text/event-stream): httpx2's client.sse() lets the transport's headers win where httpx_sse force-overwrote them. Cache-Control: no-store is unchanged.
  • TLS verification uses the operating system trust store via truststore instead of certifi's bundle; SSL_CERT_FILE/SSL_CERT_DIR are honored first. Documented in the migration guide.
  • Loggers rename: httpx → httpx2, httpcore.* → httpcore2.*; the default User-Agent becomes python-httpx2/<version>.
  • simple-chatbot example: except httpx.RequestError → except httpx2.HTTPError, so HTTP status errors are reported instead of propagating (the old handler's status-error branch was unreachable).

Notes

  • httpx2 is API-compatible with httpx, so most of the diff is the httpx → httpx2 import rename. Users passing their own http_client only need to change the import.
  • Tests use httpx2's AsyncClient.sse() convenience method for the raw-client SSE call sites.
  • The httpx2 requirement deliberately has no upper bound, unlike v1's httpx<1.0.0 cap (#2345): httpx2 is maintained in lockstep with this SDK, so a breaking httpx2 major would land alongside a coordinated SDK release rather than being fenced off ahead of time.

Verification

ruff, pyright, and the full test suite all pass at 100% coverage (strict-no-cover clean).

AI Disclaimer

This PR was developed with the assistance of either Claude or Codex. I've reviewed and verified the changes.