mirror of
https://github.com/EvolutionAPI/adk-python.git
synced 2026-02-05 06:16:24 -06:00
191 lines
6.8 KiB
Python
191 lines
6.8 KiB
Python
# Copyright 2025 Google LLC
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
|
|
from typing import List
|
|
from typing import Optional
|
|
from typing import Union
|
|
|
|
from typing_extensions import override
|
|
import yaml
|
|
|
|
from ...agents.readonly_context import ReadonlyContext
|
|
from ...auth.auth_credential import AuthCredential
|
|
from ...auth.auth_schemes import AuthScheme
|
|
from ..base_toolset import BaseToolset
|
|
from ..base_toolset import ToolPredicate
|
|
from ..openapi_tool.common.common import to_snake_case
|
|
from ..openapi_tool.openapi_spec_parser.openapi_toolset import OpenAPIToolset
|
|
from ..openapi_tool.openapi_spec_parser.rest_api_tool import RestApiTool
|
|
from .clients.apihub_client import APIHubClient
|
|
|
|
|
|
class APIHubToolset(BaseToolset):
|
|
"""APIHubTool generates tools from a given API Hub resource.
|
|
|
|
Examples:
|
|
|
|
```
|
|
apihub_toolset = APIHubToolset(
|
|
apihub_resource_name="projects/test-project/locations/us-central1/apis/test-api",
|
|
service_account_json="...",
|
|
tool_filter=lambda tool, ctx=None: tool.name in ('my_tool',
|
|
'my_other_tool')
|
|
)
|
|
|
|
# Get all available tools
|
|
agent = LlmAgent(tools=apihub_toolset)
|
|
|
|
```
|
|
|
|
**apihub_resource_name** is the resource name from API Hub. It must include
|
|
API name, and can optionally include API version and spec name.
|
|
- If apihub_resource_name includes a spec resource name, the content of that
|
|
spec will be used for generating the tools.
|
|
- If apihub_resource_name includes only an api or a version name, the
|
|
first spec of the first version of that API will be used.
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
*,
|
|
# Parameters for fetching API Hub resource
|
|
apihub_resource_name: str,
|
|
access_token: Optional[str] = None,
|
|
service_account_json: Optional[str] = None,
|
|
# Parameters for the toolset itself
|
|
name: str = '',
|
|
description: str = '',
|
|
# Parameters for generating tools
|
|
lazy_load_spec=False,
|
|
auth_scheme: Optional[AuthScheme] = None,
|
|
auth_credential: Optional[AuthCredential] = None,
|
|
# Optionally, you can provide a custom API Hub client
|
|
apihub_client: Optional[APIHubClient] = None,
|
|
tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
|
|
):
|
|
"""Initializes the APIHubTool with the given parameters.
|
|
|
|
Examples:
|
|
```
|
|
apihub_toolset = APIHubToolset(
|
|
apihub_resource_name="projects/test-project/locations/us-central1/apis/test-api",
|
|
service_account_json="...",
|
|
)
|
|
|
|
# Get all available tools
|
|
agent = LlmAgent(tools=[apihub_toolset])
|
|
|
|
apihub_toolset = APIHubToolset(
|
|
apihub_resource_name="projects/test-project/locations/us-central1/apis/test-api",
|
|
service_account_json="...",
|
|
tool_filter = ['my_tool']
|
|
)
|
|
# Get a specific tool
|
|
agent = LlmAgent(tools=[
|
|
...,
|
|
apihub_toolset,
|
|
])
|
|
```
|
|
|
|
**apihub_resource_name** is the resource name from API Hub. It must include
|
|
API name, and can optionally include API version and spec name.
|
|
- If apihub_resource_name includes a spec resource name, the content of that
|
|
spec will be used for generating the tools.
|
|
- If apihub_resource_name includes only an api or a version name, the
|
|
first spec of the first version of that API will be used.
|
|
|
|
Example:
|
|
* projects/xxx/locations/us-central1/apis/apiname/...
|
|
* https://console.cloud.google.com/apigee/api-hub/apis/apiname?project=xxx
|
|
|
|
Args:
|
|
apihub_resource_name: The resource name of the API in API Hub.
|
|
Example: `projects/test-project/locations/us-central1/apis/test-api`.
|
|
access_token: Google Access token. Generate with gcloud cli `gcloud auth
|
|
auth print-access-token`. Used for fetching API Specs from API Hub.
|
|
service_account_json: The service account config as a json string.
|
|
Required if not using default service credential. It is used for
|
|
creating the API Hub client and fetching the API Specs from API Hub.
|
|
apihub_client: Optional custom API Hub client.
|
|
name: Name of the toolset. Optional.
|
|
description: Description of the toolset. Optional.
|
|
auth_scheme: Auth scheme that applies to all the tool in the toolset.
|
|
auth_credential: Auth credential that applies to all the tool in the
|
|
toolset.
|
|
lazy_load_spec: If True, the spec will be loaded lazily when needed.
|
|
Otherwise, the spec will be loaded immediately and the tools will be
|
|
generated during initialization.
|
|
tool_filter: The filter used to filter the tools in the toolset. It can
|
|
be either a tool predicate or a list of tool names of the tools to
|
|
expose.
|
|
"""
|
|
self.name = name
|
|
self.description = description
|
|
self._apihub_resource_name = apihub_resource_name
|
|
self._lazy_load_spec = lazy_load_spec
|
|
self._apihub_client = apihub_client or APIHubClient(
|
|
access_token=access_token,
|
|
service_account_json=service_account_json,
|
|
)
|
|
|
|
self._openapi_toolset = None
|
|
self._auth_scheme = auth_scheme
|
|
self._auth_credential = auth_credential
|
|
self.tool_filter = tool_filter
|
|
|
|
if not self._lazy_load_spec:
|
|
self._prepare_toolset()
|
|
|
|
@override
|
|
async def get_tools(
|
|
self, readonly_context: Optional[ReadonlyContext] = None
|
|
) -> List[RestApiTool]:
|
|
"""Retrieves all available tools.
|
|
|
|
Returns:
|
|
A list of all available RestApiTool objects.
|
|
"""
|
|
if not self._openapi_toolset:
|
|
self._prepare_toolset()
|
|
if not self._openapi_toolset:
|
|
return []
|
|
return await self._openapi_toolset.get_tools(readonly_context)
|
|
|
|
def _prepare_toolset(self) -> None:
|
|
"""Fetches the spec from API Hub and generates the toolset."""
|
|
# For each API, get the first version and the first spec of that version.
|
|
spec_str = self._apihub_client.get_spec_content(self._apihub_resource_name)
|
|
spec_dict = yaml.safe_load(spec_str)
|
|
if not spec_dict:
|
|
return
|
|
|
|
self.name = self.name or to_snake_case(
|
|
spec_dict.get('info', {}).get('title', 'unnamed')
|
|
)
|
|
self.description = self.description or spec_dict.get('info', {}).get(
|
|
'description', ''
|
|
)
|
|
self._openapi_toolset = OpenAPIToolset(
|
|
spec_dict=spec_dict,
|
|
auth_credential=self._auth_credential,
|
|
auth_scheme=self._auth_scheme,
|
|
tool_filter=self.tool_filter,
|
|
)
|
|
|
|
@override
|
|
async def close(self):
|
|
if self._openapi_toolset:
|
|
await self._openapi_toolset.close()
|