feat(tools): expose httpx_client_factory on RestApiTool and OpenAPITo…#5715
feat(tools): expose httpx_client_factory on RestApiTool and OpenAPITo…#5715darshil3011 wants to merge 6 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
Hi @darshil3011 , Thank you for your contribution! We appreciate you taking the time to submit this pull request. Your PR has been received by the team and is currently under review. We will provide feedback as soon as we have an update to share. |
|
Hi @xuanyang15 , can you please review this. |
|
Thanks, looking forward to feedbacks. |
|
@darshil3011 Thanks for creating this PR! ADK has upgraded to 2.0, could you please help rebase the PR? |
|
Sure, let me check and update you @xuanyang15 |
…olset Mirror the pattern merged for MCP in google#2997 (StreamableHTTPConnectionParams. httpx_client_factory) on the OpenAPI tool surface. Adds an optional httpx_client_factory parameter to: - RestApiTool.__init__ - RestApiTool.from_parsed_operation - OpenAPIToolset.__init__ OpenAPIToolset forwards the factory to every generated RestApiTool the same way ssl_verify and header_provider are already forwarded. When provided, the factory's client is used to issue each API call; when None (default), the existing httpx.AsyncClient(verify=..., timeout=None) construction is preserved exactly. This unlocks httpx.AsyncClient knobs that the narrower ssl_verify parameter can't reach: proxies, HTTP/2, custom transports (e.g. request signing), and shared connection pools. Closes google#5681
ba2c37e to
3074cd8
Compare
|
I rebased onto current main (ADK 2.0). The feature is purely additive and did not touch openapi_tool/openapi_spec_parser/*, so no API migration was needed |
|
@xuanyang15 did you get a chance to review this ? |
|
Thank you @darshil3011! I left some comments. Could you please also help fix the failed checks above? |
|
Hi @xuanyang15 I couldnt find your comments ? did you actually publish it or still drafting ? I am working on the failed checks though |
…px-client-factory
| an argument, allowing dynamic header generation based on the current | ||
| context. Useful for adding custom headers like correlation IDs, | ||
| authentication tokens, or other request metadata. | ||
| httpx_client_factory: Optional zero-argument callable returning an |
There was a problem hiding this comment.
This docstring says "zero-argument callable", but the HttpxClientFactory is defined as Callable[..., httpx.AsyncClient], which takes any arguments, is this inconsistency intended?
| ) -> httpx.Response: | ||
| verify = request_params.pop("verify", True) | ||
| if httpx_client_factory is not None: | ||
| async with httpx_client_factory() as client: |
There was a problem hiding this comment.
With async with, will the client being closed automatically after it is being used in line 615? Is this intended? Should we point this out clearly in the docstring?
There was a problem hiding this comment.
Yes, intentional — the client is used as an async context manager and closed after the request, mirroring the default branch. I've documented this in the docstrings (factory must return a fresh client per call) and dropped the inaccurate "shared connection pools" wording. Reusing a pooled client would require holding a persistent client on the tool, which I think is best as a separate change — happy to follow up if you'd prefer that.
|
@darshil3011 I forgot to submit the comments, could you please check again? |
|
Thanks @xuanyang15 ! I merged the latest main on top of your merge commit, the pre-commit check is green now. It had been failing on main-authored files that pre-commit run --all-files flags; that was fixed upstream in #af8bfe08, which is now in the branch. The remaining red check, check-file-contents → "Check for hardcoded googleapis.com endpoints", is flagging test_openapi_toolset.py and test_rest_api_tool.py — but only because of pre-existing fixtures, not anything this PR adds. That step scans all changed .py files, whereas its sibling steps in the same workflow already exclude tests/ . Could you either waive it here or add the same tests/ exclusion to that step? My added source and tests don't introduce any new endpoints. |
…lifecycle - Tighten HttpxClientFactory to Callable[[], httpx.AsyncClient] to match the zero-arg call site. - Document per-request client lifecycle (closed after each request); drop the inaccurate "shared connection pools" claim.
| request signing). The returned client is used as an async context | ||
| manager and closed after each request, so the factory must return a | ||
| fresh client on every call. Defaults to ``None``, which preserves | ||
| today's behaviour. Mirrors the pattern exposed for MCP by |
There was a problem hiding this comment.
nit: "today's behaviour" sounds unclear once the code is submitted. Can we remove this sentence or make it more clear, e.g. something like "which preserves the behavior when httpx_client_factory is not set".
- Replace vague "today's behaviour"/"unchanged" with a concrete description of what None does.
|
I think the only thing left is hardcoded googleapis.com endpoints which is beyond this PR's scope. Can you please waive this off ? |
|
Thanks you @darshil3011 for addressing the comments so quickly! This PR is now waiting for ADK team internal review. I will merge it as soon as it is approved by the team. |
…olset
Mirror the pattern merged for MCP in #2997 (StreamableHTTPConnectionParams. httpx_client_factory) on the OpenAPI tool surface.
Adds an optional httpx_client_factory parameter to:
OpenAPIToolset forwards the factory to every generated RestApiTool the same way ssl_verify and header_provider are already forwarded. When provided, the factory's client is used to issue each API call; when None (default), the existing httpx.AsyncClient(verify=..., timeout=None) construction is preserved exactly. This unlocks httpx.AsyncClient knobs that the narrower ssl_verify parameter can't reach: proxies, HTTP/2, custom transports (e.g. request signing), and shared connection pools.
Closes #5681
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
2. Or, if no issue exists, describe the change:
If applicable, please follow the issue templates to provide as much detail as
possible.
Problem:
A clear and concise description of what the problem is.
Solution:
A clear and concise description of what you want to happen and why you choose
this solution.
Testing Plan
Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes.
Unit Tests:
Please include a summary of passed
pytestresults.Manual End-to-End (E2E) Tests:
Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix.
Checklist
Additional context
Add any other context or screenshots about the feature request here.