Skip to content

Add optional httpx2 support to the ingress client - #248

Closed
maksimzayats wants to merge 4 commits into
restatedev:mainfrom
maksimzayats:client/httpx-optional
Closed

maksimzayats wants to merge 4 commits into
restatedev:mainfrom
maksimzayats:client/httpx-optional

Conversation

@maksimzayats

@maksimzayats maksimzayats commented Oct 28, 2026 •

Copy link
Copy Markdown

Summary

Fixes #247. Allow Client to use a compatible async HTTP client without requiring httpx at import time.

Client(supplied_client)                  -> HttpClient protocol
create_client(ingress)                   -> httpx, as before
create_client(ingress, backend="httpx2") -> httpx2

Add HttpClient and HttpResponse protocols. Export them from restate.client_types and restate. Import the selected HTTP package inside the factory. If it is missing, report the matching SDK install command. Reject invalid backend values. Pass through import failures inside an installed package.

Keep client = ["httpx[http2]"]. Add the separate client-httpx2 = ["httpx2[http2]>=2.12,<3"] extra. Add no base dependency.

This builds on Arthur Depasse's PR #231. The first commit retains his author identity and source commit reference. Later commits adapt his work to this scope. Please preserve his authored commit when merging.

Evidence

  • Before: importing Client from current upstream main fails when httpx is blocked.
    After: the import passes with both HTTP packages blocked. Clean wheels also import with neither package installed.
  • just sync, just build and just verify pass on Python 3.10 through 3.14. Each version passes Ruff, Mypy, Pyright and all 67 tests.
  • All 27 client tests pass with httpx2 2.12.0 on Python 3.10. Both real clients satisfy the protocols under Mypy and Pyright.
  • Clean wheels pass on Python 3.10 and 3.12 with neither HTTP package, only httpx, only httpx2 and both. Each client extra installs only its own HTTP stack.
  • Each client also passes against a real Restate server from an installed wheel with the other HTTP package absent. These checks cover factory and supplied clients, headers, codec use, decoded results and cleanup.
  • The rebuilt test-service image passes all 267 tests in eight conformance suites with runner v2.2 and Java 25.

Local Python checks use macOS arm64. Conformance uses Linux arm64 containers. GitHub Test and Integration workflows still need maintainer approval. The CLA check now passes.

Compatibility and scope

The three existing factory arguments keep their positional meaning. The default remains httpx. The new backend argument is keyword-only. There is no fallback. Both paths keep HTTP/2, headers, codec forwarding and async cleanup.

Client.client remains the supplied object. Requests and return values stay the same. HTTP status errors keep the same HttpError.status_code, .message and .body values from #152. Transport errors keep each client's own exception types.

The harness, its extra and downstream integrations are unchanged. Python 3.10 remains supported. The lock file records the new extra and its required dependencies.

Open question

Should httpx be deprecated in a future change? This PR supports both packages and adds no deprecation warning.

Merge Danger

Door: Two-way. Reverting this change needs no data migration.

Blast Radius: Ingress. Existing httpx calls and the existing client extra keep their behavior.

LeBoucEtMistere and others added 2 commits October 28, 2026 13:33
(cherry picked from commit fcb9991)
Accept structural HTTP clients without importing either HTTP package.
Keep httpx as the factory default and add explicit httpx2 selection
with a separate optional extra.

Restore the harness and existing extras to their upstream behavior.
Cover backend selection, request and error behavior, imports, and types.

Refs restatedev#247
@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@maksimzayats

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@maksimzayats

Copy link
Copy Markdown
Author

Hi @slinkydeveloper and @igalshilman. Could you please review this PR when you have time? It keeps httpx as the default and adds optional httpx2 support. Thank you.

@maksimzayats

Copy link
Copy Markdown
Author

Hi @slinkydeveloper and @igalshilman. Could you please review this PR when you have time? It keeps httpx as the default and adds optional httpx2 support. Thank you.

@maksimzayats

Copy link
Copy Markdown
Author

Hi @slinkydeveloper and @igalshilman. Could you please review this PR when you have time? It keeps httpx as the default and adds optional httpx2 support. Thank you.

@maksimzayats

Copy link
Copy Markdown
Author

Hi @slinkydeveloper and @igalshilman. Could you please review this PR when you have time? It keeps httpx as the default and adds optional httpx2 support. Thank you.

@igalshilman

Copy link
Copy Markdown
Contributor

fixed in main, thank you for reporting this!

@igalshilman igalshilman closed this Nov 5, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ingress client] Accept httpx-compatible clients without requiring httpx

3 participants