Replace httpx and httpx-sse with httpx2 (#2972)
Some checks failed
CI / checks (push) Has been cancelled
CI / all-green (push) Has been cancelled

Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
This commit is contained in:
Marcelo Trylesinski 2026-07-14 18:05:08 +02:00 • committed by GitHub
commit 2713b53b12
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 1029 additions and 948 deletions

View file

@ -30,7 +30,7 @@ uv run python -m stories.identity_assertion.client --http http://127.0.0.1:8000/
`Client(url)` has no `auth=` passthrough, so both runners thread the module's
`build_auth` export (an `IdentityAssertionOAuthProvider`) onto the
`httpx.AsyncClient` underneath the transport and hand `main` a target that is
`httpx2.AsyncClient` underneath the transport and hand `main` a target that is
already routed through it.
## Try it without the SDK client
@ -57,7 +57,7 @@ kill "$SERVER_PID"
return a fresh ID-JAG. In production this is an RFC 8693 token exchange
against your IdP; here it calls the stand-in signer in `idp.py`.
- `client.py` `build_auth` — `IdentityAssertionOAuthProvider` is the same
`httpx.Auth` shape as every other provider. Note `issuer=ISSUER` with the
`httpx2.Auth` shape as every other provider. Note `issuer=ISSUER` with the
trailing slash: the provider compares it to the metadata document's `issuer`
by simple string comparison and refuses a mismatch before sending anything.
- `server.py` `exchange_identity_assertion` — the whole authorization-server

View file

@ -1,6 +1,6 @@
"""HTTP-only SEP-990: `build_auth` presents an IdP-issued ID-JAG (jwt-bearer grant); `whoami` proves the subject."""
import httpx
import httpx2
from mcp.client import Client
from mcp.client.auth.extensions.identity_assertion import IdentityAssertionOAuthProvider
@ -27,14 +27,14 @@ async def fetch_id_jag(audience: str, resource: str) -> str:
)
def build_auth(_http: httpx.AsyncClient) -> httpx.Auth:
def build_auth(_http: httpx2.AsyncClient) -> httpx2.Auth:
"""An `IdentityAssertionOAuthProvider` for the pre-registered confidential client.
`issuer` is configuration, not discovery: the provider fetches metadata from this issuer's
well-known and never asks the MCP server which authorization server to use. The string must
equal the `issuer` its metadata serves byte for byte (note the trailing slash).
`Client(url, auth=...)` doesn't exist yet, so the harness threads this onto the underlying
`httpx.AsyncClient` and hands `main` a target that is already routed through it.
`httpx2.AsyncClient` and hands `main` a target that is already routed through it.
"""
return IdentityAssertionOAuthProvider(
server_url=MCP_URL,