OAuth2 authentication for httpx. Handles OAuth flow with automatic client registration and token storage.
| 219 | |
| 220 | |
| 221 | class OAuthClientProvider(httpx.Auth): |
| 222 | """OAuth2 authentication for httpx. |
| 223 | |
| 224 | Handles OAuth flow with automatic client registration and token storage. |
| 225 | """ |
| 226 | |
| 227 | requires_response_body = True |
| 228 | |
| 229 | def __init__( |
| 230 | self, |
| 231 | server_url: str, |
| 232 | client_metadata: OAuthClientMetadata, |
| 233 | storage: TokenStorage, |
| 234 | redirect_handler: Callable[[str], Awaitable[None]] | None = None, |
| 235 | callback_handler: Callable[[], Awaitable[AuthorizationCodeResult]] | None = None, |
| 236 | timeout: float = 300.0, |
| 237 | client_metadata_url: str | None = None, |
| 238 | validate_resource_url: Callable[[str, str | None], Awaitable[None]] | None = None, |
| 239 | ): |
| 240 | """Initialize OAuth2 authentication. |
| 241 | |
| 242 | Args: |
| 243 | server_url: The MCP server URL. |
| 244 | client_metadata: OAuth client metadata for registration. |
| 245 | storage: Token storage implementation. |
| 246 | redirect_handler: Handler for authorization redirects. |
| 247 | callback_handler: Handler for authorization callbacks. |
| 248 | timeout: Timeout for the OAuth flow. |
| 249 | client_metadata_url: URL-based client ID. When provided and the server |
| 250 | advertises client_id_metadata_document_supported=True, this URL will be |
| 251 | used as the client_id instead of performing dynamic client registration. |
| 252 | Must be a valid HTTPS URL with a non-root pathname. |
| 253 | validate_resource_url: Optional callback to override resource URL validation. |
| 254 | Called with (server_url, prm_resource) where prm_resource is the resource |
| 255 | from Protected Resource Metadata (or None if not present). If not provided, |
| 256 | default validation rejects mismatched resources per RFC 8707. |
| 257 | |
| 258 | Raises: |
| 259 | ValueError: If client_metadata_url is provided but not a valid HTTPS URL |
| 260 | with a non-root pathname. |
| 261 | """ |
| 262 | # Validate client_metadata_url if provided |
| 263 | if client_metadata_url is not None and not is_valid_client_metadata_url(client_metadata_url): |
| 264 | raise ValueError( |
| 265 | f"client_metadata_url must be a valid HTTPS URL with a non-root pathname, got: {client_metadata_url}" |
| 266 | ) |
| 267 | |
| 268 | self.context = OAuthContext( |
| 269 | server_url=server_url, |
| 270 | client_metadata=client_metadata, |
| 271 | storage=storage, |
| 272 | redirect_handler=redirect_handler, |
| 273 | callback_handler=callback_handler, |
| 274 | timeout=timeout, |
| 275 | client_metadata_url=client_metadata_url, |
| 276 | ) |
| 277 | self._validate_resource_url_callback = validate_resource_url |
| 278 | self._initialized = False |
no outgoing calls