You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
** Please make sure you read the contribution guide and file the issues in the right place. ** Contribution guide.
🔴 Required Information
Is your feature request related to a specific problem?
I need to control the httpx.AsyncClient used by RestApiTool (OpenAPI-generated tools) — for things like custom CA bundles for
mTLS, corporate proxies, request signing transports, HTTP/2, or observability instrumentation. Today RestApiTool exposes ssl_verify and a header_provider, but the underlying client is built inside the module-level helper _request(...) in src/google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py with only verify=... and timeout=None — none of the
other httpx.AsyncClient knobs are reachable.
The sibling primitive — MCPSessionManager — already solved this in PR #2997 (issue #3005) by accepting an httpx_client_factory
parameter. In the body of that PR the author explicitly wrote:
"exposing a httpx factory is a good pattern which could be followed for those issues too" — referring to similar requests on
other ADK surfaces.
This issue requests the same treatment for RestApiTool (and its toolset).
Describe the Solution You'd Like
Add an optional httpx_client_factory parameter to:
OpenAPIToolset.__init__ (src/google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py:65) — plumbed down to
every generated RestApiTool exactly the way ssl_verify and header_provider already are (see lines 238-239 of openapi_toolset.py).
The factory follows the same protocol used by MCPSessionManager — a zero-argument (or headers/timeout/auth-aware) callable
returning an httpx.AsyncClient. When set, the request path uses the user-supplied client instead of constructing a fresh one.
Defaults are unchanged: if httpx_client_factory is None, behaviour is exactly today's (an httpx.AsyncClient(verify=..., timeout=None)).
Impact on your work
Without this, the only escape hatches are:
ssl_verify=ssl.SSLContext(...) — works for one specific case (custom CAs) but doesn't help with proxies, HTTP/2, custom
transports, request signing, or shared connection pooling.
Sub-classing RestApiTool and overriding the call to the module-level _request(...) — but _request is a private function,
not a method, so the user has to monkeypatch or fork.
Both are brittle compared with the clean httpx_client_factory=... pattern already merged for MCP.
Willingness to contribute
Yes — I'd like to submit a PR for this. Planned scope:
Add httpx_client_factory: Optional[Callable[..., httpx.AsyncClient]] = None to RestApiTool.__init__, RestApiTool.from_parsed_operation, and OpenAPIToolset.__init__.
Plumb it through OpenAPIToolset._generate_tools_from_operations (where ssl_verify and header_provider are already
forwarded).
Modify _request(...) to use the factory when provided, falling back to today's httpx.AsyncClient(verify=..., timeout=None)
when not.
ssl_verify only — covers the custom-CA case but not proxies, HTTP/2, custom transports, request signing, or shared pools.
Sub-classing RestApiTool — _request is a private module function, not a method, so the only override path is
monkeypatching the module, which is brittle and breaks on every refactor.
Wrapping the OpenAPI spec in a proxy — moves the problem one layer up; doesn't help with credentials or per-request transport
policy.
Proposed API / Implementation
Following the MCP precedent (StreamableHTTPConnectionParams.httpx_client_factory):
** Please make sure you read the contribution guide and file the issues in the right place. **
Contribution guide.
🔴 Required Information
Is your feature request related to a specific problem?
I need to control the
httpx.AsyncClientused byRestApiTool(OpenAPI-generated tools) — for things like custom CA bundles formTLS, corporate proxies, request signing transports, HTTP/2, or observability instrumentation. Today
RestApiToolexposesssl_verifyand aheader_provider, but the underlying client is built inside the module-level helper_request(...)insrc/google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.pywith onlyverify=...andtimeout=None— none of theother
httpx.AsyncClientknobs are reachable.The sibling primitive —
MCPSessionManager— already solved this in PR #2997 (issue #3005) by accepting anhttpx_client_factoryparameter. In the body of that PR the author explicitly wrote:
This issue requests the same treatment for
RestApiTool(and its toolset).Describe the Solution You'd Like
Add an optional
httpx_client_factoryparameter to:RestApiTool.__init__(src/google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py:93-108)RestApiTool.from_parsed_operation(same file)OpenAPIToolset.__init__(src/google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py:65) — plumbed down toevery generated
RestApiToolexactly the wayssl_verifyandheader_provideralready are (see lines 238-239 ofopenapi_toolset.py).The factory follows the same protocol used by
MCPSessionManager— a zero-argument (orheaders/timeout/auth-aware) callablereturning an
httpx.AsyncClient. When set, the request path uses the user-supplied client instead of constructing a fresh one.Defaults are unchanged: if
httpx_client_factoryisNone, behaviour is exactly today's (anhttpx.AsyncClient(verify=..., timeout=None)).Impact on your work
Without this, the only escape hatches are:
ssl_verify=ssl.SSLContext(...)— works for one specific case (custom CAs) but doesn't help with proxies, HTTP/2, customtransports, request signing, or shared connection pooling.
RestApiTooland overriding the call to the module-level_request(...)— but_requestis a private function,not a method, so the user has to monkeypatch or fork.
Both are brittle compared with the clean
httpx_client_factory=...pattern already merged for MCP.Willingness to contribute
Yes — I'd like to submit a PR for this. Planned scope:
httpx_client_factory: Optional[Callable[..., httpx.AsyncClient]] = NonetoRestApiTool.__init__,RestApiTool.from_parsed_operation, andOpenAPIToolset.__init__.OpenAPIToolset._generate_tools_from_operations(wheressl_verifyandheader_providerare alreadyforwarded).
_request(...)to use the factory when provided, falling back to today'shttpx.AsyncClient(verify=..., timeout=None)when not.
tests/unittests/tools/openapi_tool/openapi_spec_parser/mirroring the test added in PR Feat/expose mcps streamable http custom httpx factory parameter #2997 — assert thecustom factory is invoked and that the default path remains unchanged.
🟡 Recommended Information
Describe Alternatives You've Considered
ssl_verifyonly — covers the custom-CA case but not proxies, HTTP/2, custom transports, request signing, or shared pools.RestApiTool—_requestis a private module function, not a method, so the only override path ismonkeypatching the module, which is brittle and breaks on every refactor.
policy.
Proposed API / Implementation
Following the MCP precedent (
StreamableHTTPConnectionParams.httpx_client_factory):Usage:
Internally,
_request(...)would become something like:Additional Context
Feat/expose mcps streamable http custom httpx factory parameter).streamablehttp_client'httpx_client_factoryonakd.tools.mcp_tools.StreamableHTTPConnectionParams#3005.httpx_client_factoryto be used when creating thestreamablehttp_client#2963.Versions checked:
google-adk1.33.0 /main. Files:src/google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.pysrc/google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py