google-adk 1.0.0__py3-none-any.whl → 1.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. google/adk/agents/callback_context.py +2 -1
  2. google/adk/agents/readonly_context.py +3 -1
  3. google/adk/auth/auth_credential.py +4 -1
  4. google/adk/cli/browser/index.html +4 -4
  5. google/adk/cli/browser/{main-QOEMUXM4.js → main-PKDNKWJE.js} +59 -59
  6. google/adk/cli/browser/polyfills-B6TNHZQ6.js +17 -0
  7. google/adk/cli/cli.py +3 -2
  8. google/adk/cli/cli_eval.py +6 -85
  9. google/adk/cli/cli_tools_click.py +39 -10
  10. google/adk/cli/fast_api.py +53 -184
  11. google/adk/cli/utils/agent_loader.py +137 -0
  12. google/adk/cli/utils/cleanup.py +40 -0
  13. google/adk/cli/utils/evals.py +2 -1
  14. google/adk/cli/utils/logs.py +2 -7
  15. google/adk/code_executors/code_execution_utils.py +2 -1
  16. google/adk/code_executors/container_code_executor.py +0 -1
  17. google/adk/code_executors/vertex_ai_code_executor.py +6 -8
  18. google/adk/evaluation/eval_case.py +3 -1
  19. google/adk/evaluation/eval_metrics.py +74 -0
  20. google/adk/evaluation/eval_result.py +86 -0
  21. google/adk/evaluation/eval_set.py +2 -0
  22. google/adk/evaluation/eval_set_results_manager.py +47 -0
  23. google/adk/evaluation/eval_sets_manager.py +2 -1
  24. google/adk/evaluation/evaluator.py +2 -0
  25. google/adk/evaluation/local_eval_set_results_manager.py +113 -0
  26. google/adk/evaluation/local_eval_sets_manager.py +4 -4
  27. google/adk/evaluation/response_evaluator.py +2 -1
  28. google/adk/evaluation/trajectory_evaluator.py +3 -2
  29. google/adk/examples/base_example_provider.py +1 -0
  30. google/adk/flows/llm_flows/base_llm_flow.py +4 -6
  31. google/adk/flows/llm_flows/contents.py +3 -1
  32. google/adk/flows/llm_flows/instructions.py +7 -77
  33. google/adk/flows/llm_flows/single_flow.py +1 -1
  34. google/adk/models/base_llm.py +2 -1
  35. google/adk/models/base_llm_connection.py +2 -0
  36. google/adk/models/google_llm.py +4 -1
  37. google/adk/models/lite_llm.py +3 -2
  38. google/adk/models/llm_response.py +2 -1
  39. google/adk/runners.py +36 -4
  40. google/adk/sessions/_session_util.py +2 -1
  41. google/adk/sessions/database_session_service.py +5 -8
  42. google/adk/sessions/vertex_ai_session_service.py +28 -13
  43. google/adk/telemetry.py +4 -2
  44. google/adk/tools/agent_tool.py +1 -1
  45. google/adk/tools/apihub_tool/apihub_toolset.py +1 -1
  46. google/adk/tools/apihub_tool/clients/apihub_client.py +10 -3
  47. google/adk/tools/apihub_tool/clients/secret_client.py +1 -0
  48. google/adk/tools/application_integration_tool/application_integration_toolset.py +6 -2
  49. google/adk/tools/application_integration_tool/clients/connections_client.py +8 -1
  50. google/adk/tools/application_integration_tool/clients/integration_client.py +3 -1
  51. google/adk/tools/application_integration_tool/integration_connector_tool.py +1 -1
  52. google/adk/tools/base_toolset.py +40 -2
  53. google/adk/tools/bigquery/__init__.py +38 -0
  54. google/adk/tools/bigquery/bigquery_credentials.py +217 -0
  55. google/adk/tools/bigquery/bigquery_tool.py +116 -0
  56. google/adk/tools/bigquery/bigquery_toolset.py +86 -0
  57. google/adk/tools/bigquery/client.py +33 -0
  58. google/adk/tools/bigquery/metadata_tool.py +249 -0
  59. google/adk/tools/bigquery/query_tool.py +76 -0
  60. google/adk/tools/function_parameter_parse_util.py +7 -0
  61. google/adk/tools/function_tool.py +33 -3
  62. google/adk/tools/get_user_choice_tool.py +1 -0
  63. google/adk/tools/google_api_tool/__init__.py +17 -11
  64. google/adk/tools/google_api_tool/google_api_tool.py +1 -1
  65. google/adk/tools/google_api_tool/google_api_toolset.py +0 -14
  66. google/adk/tools/google_api_tool/google_api_toolsets.py +8 -2
  67. google/adk/tools/google_search_tool.py +2 -2
  68. google/adk/tools/mcp_tool/conversion_utils.py +6 -2
  69. google/adk/tools/mcp_tool/mcp_session_manager.py +62 -188
  70. google/adk/tools/mcp_tool/mcp_tool.py +27 -24
  71. google/adk/tools/mcp_tool/mcp_toolset.py +76 -131
  72. google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +1 -3
  73. google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +6 -7
  74. google/adk/tools/openapi_tool/common/common.py +5 -1
  75. google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +7 -2
  76. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +2 -7
  77. google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +5 -1
  78. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +11 -1
  79. google/adk/tools/toolbox_toolset.py +31 -3
  80. google/adk/utils/__init__.py +13 -0
  81. google/adk/utils/instructions_utils.py +131 -0
  82. google/adk/version.py +1 -1
  83. {google_adk-1.0.0.dist-info → google_adk-1.1.1.dist-info}/METADATA +12 -15
  84. {google_adk-1.0.0.dist-info → google_adk-1.1.1.dist-info}/RECORD +87 -78
  85. google/adk/agents/base_agent.py.orig +0 -330
  86. google/adk/cli/browser/polyfills-FFHMD2TL.js +0 -18
  87. google/adk/cli/fast_api.py.orig +0 -822
  88. google/adk/memory/base_memory_service.py.orig +0 -76
  89. google/adk/models/google_llm.py.orig +0 -305
  90. google/adk/tools/_built_in_code_execution_tool.py +0 -70
  91. google/adk/tools/mcp_tool/mcp_session_manager.py.orig +0 -322
  92. {google_adk-1.0.0.dist-info → google_adk-1.1.1.dist-info}/WHEEL +0 -0
  93. {google_adk-1.0.0.dist-info → google_adk-1.1.1.dist-info}/entry_points.txt +0 -0
  94. {google_adk-1.0.0.dist-info → google_adk-1.1.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,217 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ import json
18
+ from typing import List
19
+ from typing import Optional
20
+
21
+ from fastapi.openapi.models import OAuth2
22
+ from fastapi.openapi.models import OAuthFlowAuthorizationCode
23
+ from fastapi.openapi.models import OAuthFlows
24
+ from google.auth.exceptions import RefreshError
25
+ from google.auth.transport.requests import Request
26
+ from google.oauth2.credentials import Credentials
27
+ from pydantic import BaseModel
28
+ from pydantic import model_validator
29
+
30
+ from ...auth import AuthConfig
31
+ from ...auth import AuthCredential
32
+ from ...auth import AuthCredentialTypes
33
+ from ...auth import OAuth2Auth
34
+ from ..tool_context import ToolContext
35
+
36
+ BIGQUERY_TOKEN_CACHE_KEY = "bigquery_token_cache"
37
+
38
+
39
+ class BigQueryCredentialsConfig(BaseModel):
40
+ """Configuration for Google API tools. (Experimental)"""
41
+
42
+ # Configure the model to allow arbitrary types like Credentials
43
+ model_config = {"arbitrary_types_allowed": True}
44
+
45
+ credentials: Optional[Credentials] = None
46
+ """the existing oauth credentials to use. If set,this credential will be used
47
+ for every end user, end users don't need to be involved in the oauthflow. This
48
+ field is mutually exclusive with client_id, client_secret and scopes.
49
+ Don't set this field unless you are sure this credential has the permission to
50
+ access every end user's data.
51
+
52
+ Example usage: when the agent is deployed in Google Cloud environment and
53
+ the service account (used as application default credentials) has access to
54
+ all the required BigQuery resource. Setting this credential to allow user to
55
+ access the BigQuery resource without end users going through oauth flow.
56
+
57
+ To get application default credential: `google.auth.default(...)`. See more
58
+ details in https://cloud.google.com/docs/authentication/application-default-credentials.
59
+
60
+ When the deployed environment cannot provide a pre-existing credential,
61
+ consider setting below client_id, client_secret and scope for end users to go
62
+ through oauth flow, so that agent can access the user data.
63
+ """
64
+ client_id: Optional[str] = None
65
+ """the oauth client ID to use."""
66
+ client_secret: Optional[str] = None
67
+ """the oauth client secret to use."""
68
+ scopes: Optional[List[str]] = None
69
+ """the scopes to use.
70
+ """
71
+
72
+ @model_validator(mode="after")
73
+ def __post_init__(self) -> BigQueryCredentialsConfig:
74
+ """Validate that either credentials or client ID/secret are provided."""
75
+ if not self.credentials and (not self.client_id or not self.client_secret):
76
+ raise ValueError(
77
+ "Must provide either credentials or client_id abd client_secret pair."
78
+ )
79
+ if self.credentials and (
80
+ self.client_id or self.client_secret or self.scopes
81
+ ):
82
+ raise ValueError(
83
+ "Cannot provide both existing credentials and"
84
+ " client_id/client_secret/scopes."
85
+ )
86
+
87
+ if self.credentials:
88
+ self.client_id = self.credentials.client_id
89
+ self.client_secret = self.credentials.client_secret
90
+ self.scopes = self.credentials.scopes
91
+ return self
92
+
93
+
94
+ class BigQueryCredentialsManager:
95
+ """Manages Google API credentials with automatic refresh and OAuth flow handling.
96
+
97
+ This class centralizes credential management so multiple tools can share
98
+ the same authenticated session without duplicating OAuth logic.
99
+ """
100
+
101
+ def __init__(self, credentials_config: BigQueryCredentialsConfig):
102
+ """Initialize the credential manager.
103
+
104
+ Args:
105
+ credentials_config: Credentials containing client id and client secrete
106
+ or default credentials
107
+ """
108
+ self.credentials_config = credentials_config
109
+
110
+ async def get_valid_credentials(
111
+ self, tool_context: ToolContext
112
+ ) -> Optional[Credentials]:
113
+ """Get valid credentials, handling refresh and OAuth flow as needed.
114
+
115
+ Args:
116
+ tool_context: The tool context for OAuth flow and state management
117
+
118
+ Returns:
119
+ Valid Credentials object, or None if OAuth flow is needed
120
+ """
121
+ # First, try to get credentials from the tool context
122
+ creds_json = tool_context.state.get(BIGQUERY_TOKEN_CACHE_KEY, None)
123
+ creds = (
124
+ Credentials.from_authorized_user_info(
125
+ json.loads(creds_json), self.credentials_config.scopes
126
+ )
127
+ if creds_json
128
+ else None
129
+ )
130
+
131
+ # If credentails are empty use the default credential
132
+ if not creds:
133
+ creds = self.credentials_config.credentials
134
+
135
+ # Check if we have valid credentials
136
+ if creds and creds.valid:
137
+ return creds
138
+
139
+ # Try to refresh expired credentials
140
+ if creds and creds.expired and creds.refresh_token:
141
+ try:
142
+ creds.refresh(Request())
143
+ if creds.valid:
144
+ # Cache the refreshed credentials
145
+ tool_context.state[BIGQUERY_TOKEN_CACHE_KEY] = creds.to_json()
146
+ return creds
147
+ except RefreshError:
148
+ # Refresh failed, need to re-authenticate
149
+ pass
150
+
151
+ # Need to perform OAuth flow
152
+ return await self._perform_oauth_flow(tool_context)
153
+
154
+ async def _perform_oauth_flow(
155
+ self, tool_context: ToolContext
156
+ ) -> Optional[Credentials]:
157
+ """Perform OAuth flow to get new credentials.
158
+
159
+ Args:
160
+ tool_context: The tool context for OAuth flow
161
+ required_scopes: Set of required OAuth scopes
162
+
163
+ Returns:
164
+ New Credentials object, or None if flow is in progress
165
+ """
166
+
167
+ # Create OAuth configuration
168
+ auth_scheme = OAuth2(
169
+ flows=OAuthFlows(
170
+ authorizationCode=OAuthFlowAuthorizationCode(
171
+ authorizationUrl="https://accounts.google.com/o/oauth2/auth",
172
+ tokenUrl="https://oauth2.googleapis.com/token",
173
+ scopes={
174
+ scope: f"Access to {scope}"
175
+ for scope in self.credentials_config.scopes
176
+ },
177
+ )
178
+ )
179
+ )
180
+
181
+ auth_credential = AuthCredential(
182
+ auth_type=AuthCredentialTypes.OAUTH2,
183
+ oauth2=OAuth2Auth(
184
+ client_id=self.credentials_config.client_id,
185
+ client_secret=self.credentials_config.client_secret,
186
+ ),
187
+ )
188
+
189
+ # Check if OAuth response is available
190
+ auth_response = tool_context.get_auth_response(
191
+ AuthConfig(auth_scheme=auth_scheme, raw_auth_credential=auth_credential)
192
+ )
193
+
194
+ if auth_response:
195
+ # OAuth flow completed, create credentials
196
+ creds = Credentials(
197
+ token=auth_response.oauth2.access_token,
198
+ refresh_token=auth_response.oauth2.refresh_token,
199
+ token_uri=auth_scheme.flows.authorizationCode.tokenUrl,
200
+ client_id=self.credentials_config.client_id,
201
+ client_secret=self.credentials_config.client_secret,
202
+ scopes=list(self.credentials_config.scopes),
203
+ )
204
+
205
+ # Cache the new credentials
206
+ tool_context.state[BIGQUERY_TOKEN_CACHE_KEY] = creds.to_json()
207
+
208
+ return creds
209
+ else:
210
+ # Request OAuth flow
211
+ tool_context.request_credential(
212
+ AuthConfig(
213
+ auth_scheme=auth_scheme,
214
+ raw_auth_credential=auth_credential,
215
+ )
216
+ )
217
+ return None
@@ -0,0 +1,116 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ import inspect
17
+ from typing import Any
18
+ from typing import Callable
19
+ from typing import Optional
20
+
21
+ from google.oauth2.credentials import Credentials
22
+ from typing_extensions import override
23
+
24
+ from ..function_tool import FunctionTool
25
+ from ..tool_context import ToolContext
26
+ from .bigquery_credentials import BigQueryCredentialsConfig
27
+ from .bigquery_credentials import BigQueryCredentialsManager
28
+
29
+
30
+ class BigQueryTool(FunctionTool):
31
+ """GoogleApiTool class for tools that call Google APIs.
32
+
33
+ This class is for developers to handcraft customized Google API tools rather
34
+ than auto generate Google API tools based on API specs.
35
+
36
+ This class handles all the OAuth complexity, credential management,
37
+ and common Google API patterns so subclasses can focus on their
38
+ specific functionality.
39
+ """
40
+
41
+ def __init__(
42
+ self,
43
+ func: Callable[..., Any],
44
+ credentials: Optional[BigQueryCredentialsConfig] = None,
45
+ ):
46
+ """Initialize the Google API tool.
47
+
48
+ Args:
49
+ func: callable that impelments the tool's logic, can accept one
50
+ 'credential" parameter
51
+ credentials: credentials used to call Google API. If None, then we don't
52
+ hanlde the auth logic
53
+ """
54
+ super().__init__(func=func)
55
+ self._ignore_params.append("credentials")
56
+ self.credentials_manager = (
57
+ BigQueryCredentialsManager(credentials) if credentials else None
58
+ )
59
+
60
+ @override
61
+ async def run_async(
62
+ self, *, args: dict[str, Any], tool_context: ToolContext
63
+ ) -> Any:
64
+ """Main entry point for tool execution with credential handling.
65
+
66
+ This method handles all the OAuth complexity and then delegates
67
+ to the subclass's run_async_with_credential method.
68
+ """
69
+ try:
70
+ # Get valid credentials
71
+ credentials = (
72
+ await self.credentials_manager.get_valid_credentials(tool_context)
73
+ if self.credentials_manager
74
+ else None
75
+ )
76
+
77
+ if credentials is None and self.credentials_manager:
78
+ # OAuth flow in progress
79
+ return (
80
+ "User authorization is required to access Google services for"
81
+ f" {self.name}. Please complete the authorization flow."
82
+ )
83
+
84
+ # Execute the tool's specific logic with valid credentials
85
+
86
+ return await self._run_async_with_credential(
87
+ credentials, args, tool_context
88
+ )
89
+
90
+ except Exception as ex:
91
+ return {
92
+ "status": "ERROR",
93
+ "error_details": str(ex),
94
+ }
95
+
96
+ async def _run_async_with_credential(
97
+ self,
98
+ credentials: Credentials,
99
+ args: dict[str, Any],
100
+ tool_context: ToolContext,
101
+ ) -> Any:
102
+ """Execute the tool's specific logic with valid credentials.
103
+
104
+ Args:
105
+ credentials: Valid Google OAuth credentials
106
+ args: Arguments passed to the tool
107
+ tool_context: Tool execution context
108
+
109
+ Returns:
110
+ The result of the tool execution
111
+ """
112
+ args_to_call = args.copy()
113
+ signature = inspect.signature(self.func)
114
+ if "credentials" in signature.parameters:
115
+ args_to_call["credentials"] = credentials
116
+ return await super().run_async(args=args_to_call, tool_context=tool_context)
@@ -0,0 +1,86 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import List
18
+ from typing import Optional
19
+ from typing import Union
20
+
21
+ from google.adk.agents.readonly_context import ReadonlyContext
22
+ from typing_extensions import override
23
+
24
+ from . import metadata_tool
25
+ from . import query_tool
26
+ from ...tools.base_tool import BaseTool
27
+ from ...tools.base_toolset import BaseToolset
28
+ from ...tools.base_toolset import ToolPredicate
29
+ from .bigquery_credentials import BigQueryCredentialsConfig
30
+ from .bigquery_tool import BigQueryTool
31
+
32
+
33
+ class BigQueryToolset(BaseToolset):
34
+ """BigQuery Toolset contains tools for interacting with BigQuery data and metadata."""
35
+
36
+ def __init__(
37
+ self,
38
+ *,
39
+ tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
40
+ credentials_config: Optional[BigQueryCredentialsConfig] = None,
41
+ ):
42
+ self._credentials_config = credentials_config
43
+ self.tool_filter = tool_filter
44
+
45
+ def _is_tool_selected(
46
+ self, tool: BaseTool, readonly_context: ReadonlyContext
47
+ ) -> bool:
48
+ if self.tool_filter is None:
49
+ return True
50
+
51
+ if isinstance(self.tool_filter, ToolPredicate):
52
+ return self.tool_filter(tool, readonly_context)
53
+
54
+ if isinstance(self.tool_filter, list):
55
+ return tool.name in self.tool_filter
56
+
57
+ return False
58
+
59
+ @override
60
+ async def get_tools(
61
+ self, readonly_context: Optional[ReadonlyContext] = None
62
+ ) -> List[BaseTool]:
63
+ """Get tools from the toolset."""
64
+ all_tools = [
65
+ BigQueryTool(
66
+ func=func,
67
+ credentials=self._credentials_config,
68
+ )
69
+ for func in [
70
+ metadata_tool.get_dataset_info,
71
+ metadata_tool.get_table_info,
72
+ metadata_tool.list_dataset_ids,
73
+ metadata_tool.list_table_ids,
74
+ query_tool.execute_sql,
75
+ ]
76
+ ]
77
+
78
+ return [
79
+ tool
80
+ for tool in all_tools
81
+ if self._is_tool_selected(tool, readonly_context)
82
+ ]
83
+
84
+ @override
85
+ async def close(self):
86
+ pass
@@ -0,0 +1,33 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ import google.api_core.client_info
18
+ from google.cloud import bigquery
19
+ from google.oauth2.credentials import Credentials
20
+
21
+ USER_AGENT = "adk-bigquery-tool"
22
+
23
+
24
+ def get_bigquery_client(*, credentials: Credentials) -> bigquery.Client:
25
+ """Get a BigQuery client."""
26
+
27
+ client_info = google.api_core.client_info.ClientInfo(user_agent=USER_AGENT)
28
+
29
+ bigquery_client = bigquery.Client(
30
+ credentials=credentials, client_info=client_info
31
+ )
32
+
33
+ return bigquery_client
@@ -0,0 +1,249 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from google.cloud import bigquery
16
+ from google.oauth2.credentials import Credentials
17
+
18
+ from ...tools.bigquery import client
19
+
20
+
21
+ def list_dataset_ids(project_id: str, credentials: Credentials) -> list[str]:
22
+ """List BigQuery dataset ids in a Google Cloud project.
23
+
24
+ Args:
25
+ project_id (str): The Google Cloud project id.
26
+ credentials (Credentials): The credentials to use for the request.
27
+
28
+ Returns:
29
+ list[str]: List of the BigQuery dataset ids present in the project.
30
+
31
+ Examples:
32
+ >>> list_dataset_ids("bigquery-public-data")
33
+ ['america_health_rankings',
34
+ 'american_community_survey',
35
+ 'aml_ai_input_dataset',
36
+ 'austin_311',
37
+ 'austin_bikeshare',
38
+ 'austin_crime',
39
+ 'austin_incidents',
40
+ 'austin_waste',
41
+ 'baseball',
42
+ 'bbc_news']
43
+ """
44
+ try:
45
+ bq_client = client.get_bigquery_client(credentials=credentials)
46
+
47
+ datasets = []
48
+ for dataset in bq_client.list_datasets(project_id):
49
+ datasets.append(dataset.dataset_id)
50
+ return datasets
51
+ except Exception as ex:
52
+ return {
53
+ "status": "ERROR",
54
+ "error_details": str(ex),
55
+ }
56
+
57
+
58
+ def get_dataset_info(
59
+ project_id: str, dataset_id: str, credentials: Credentials
60
+ ) -> dict:
61
+ """Get metadata information about a BigQuery dataset.
62
+
63
+ Args:
64
+ project_id (str): The Google Cloud project id containing the dataset.
65
+ dataset_id (str): The BigQuery dataset id.
66
+ credentials (Credentials): The credentials to use for the request.
67
+
68
+ Returns:
69
+ dict: Dictionary representing the properties of the dataset.
70
+
71
+ Examples:
72
+ >>> get_dataset_info("bigquery-public-data", "penguins")
73
+ {
74
+ "kind": "bigquery#dataset",
75
+ "etag": "PNC5907iQbzeVcAru/2L3A==",
76
+ "id": "bigquery-public-data:ml_datasets",
77
+ "selfLink":
78
+ "https://bigquery.googleapis.com/bigquery/v2/projects/bigquery-public-data/datasets/ml_datasets",
79
+ "datasetReference": {
80
+ "datasetId": "ml_datasets",
81
+ "projectId": "bigquery-public-data"
82
+ },
83
+ "access": [
84
+ {
85
+ "role": "OWNER",
86
+ "groupByEmail": "cloud-datasets-eng@google.com"
87
+ },
88
+ {
89
+ "role": "READER",
90
+ "iamMember": "allUsers"
91
+ },
92
+ {
93
+ "role": "READER",
94
+ "groupByEmail": "bqml-eng@google.com"
95
+ }
96
+ ],
97
+ "creationTime": "1553208775542",
98
+ "lastModifiedTime": "1686338918114",
99
+ "location": "US",
100
+ "type": "DEFAULT",
101
+ "maxTimeTravelHours": "168"
102
+ }
103
+ """
104
+ try:
105
+ bq_client = client.get_bigquery_client(credentials=credentials)
106
+ dataset = bq_client.get_dataset(
107
+ bigquery.DatasetReference(project_id, dataset_id)
108
+ )
109
+ return dataset.to_api_repr()
110
+ except Exception as ex:
111
+ return {
112
+ "status": "ERROR",
113
+ "error_details": str(ex),
114
+ }
115
+
116
+
117
+ def list_table_ids(
118
+ project_id: str, dataset_id: str, credentials: Credentials
119
+ ) -> list[str]:
120
+ """List table ids in a BigQuery dataset.
121
+
122
+ Args:
123
+ project_id (str): The Google Cloud project id containing the dataset.
124
+ dataset_id (str): The BigQuery dataset id.
125
+ credentials (Credentials): The credentials to use for the request.
126
+
127
+ Returns:
128
+ list[str]: List of the tables ids present in the dataset.
129
+
130
+ Examples:
131
+ >>> list_table_ids("bigquery-public-data", "ml_datasets")
132
+ ['census_adult_income',
133
+ 'credit_card_default',
134
+ 'holidays_and_events_for_forecasting',
135
+ 'iris',
136
+ 'penguins',
137
+ 'ulb_fraud_detection']
138
+ """
139
+ try:
140
+ bq_client = client.get_bigquery_client(credentials=credentials)
141
+
142
+ tables = []
143
+ for table in bq_client.list_tables(
144
+ bigquery.DatasetReference(project_id, dataset_id)
145
+ ):
146
+ tables.append(table.table_id)
147
+ return tables
148
+ except Exception as ex:
149
+ return {
150
+ "status": "ERROR",
151
+ "error_details": str(ex),
152
+ }
153
+
154
+
155
+ def get_table_info(
156
+ project_id: str, dataset_id: str, table_id: str, credentials: Credentials
157
+ ) -> dict:
158
+ """Get metadata information about a BigQuery table.
159
+
160
+ Args:
161
+ project_id (str): The Google Cloud project id containing the dataset.
162
+ dataset_id (str): The BigQuery dataset id containing the table.
163
+ table_id (str): The BigQuery table id.
164
+ credentials (Credentials): The credentials to use for the request.
165
+
166
+ Returns:
167
+ dict: Dictionary representing the properties of the table.
168
+
169
+ Examples:
170
+ >>> get_table_info("bigquery-public-data", "ml_datasets", "penguins")
171
+ {
172
+ "kind": "bigquery#table",
173
+ "etag": "X0ZkRohSGoYvWemRYEgOHA==",
174
+ "id": "bigquery-public-data:ml_datasets.penguins",
175
+ "selfLink":
176
+ "https://bigquery.googleapis.com/bigquery/v2/projects/bigquery-public-data/datasets/ml_datasets/tables/penguins",
177
+ "tableReference": {
178
+ "projectId": "bigquery-public-data",
179
+ "datasetId": "ml_datasets",
180
+ "tableId": "penguins"
181
+ },
182
+ "schema": {
183
+ "fields": [
184
+ {
185
+ "name": "species",
186
+ "type": "STRING",
187
+ "mode": "REQUIRED"
188
+ },
189
+ {
190
+ "name": "island",
191
+ "type": "STRING",
192
+ "mode": "NULLABLE"
193
+ },
194
+ {
195
+ "name": "culmen_length_mm",
196
+ "type": "FLOAT",
197
+ "mode": "NULLABLE"
198
+ },
199
+ {
200
+ "name": "culmen_depth_mm",
201
+ "type": "FLOAT",
202
+ "mode": "NULLABLE"
203
+ },
204
+ {
205
+ "name": "flipper_length_mm",
206
+ "type": "FLOAT",
207
+ "mode": "NULLABLE"
208
+ },
209
+ {
210
+ "name": "body_mass_g",
211
+ "type": "FLOAT",
212
+ "mode": "NULLABLE"
213
+ },
214
+ {
215
+ "name": "sex",
216
+ "type": "STRING",
217
+ "mode": "NULLABLE"
218
+ }
219
+ ]
220
+ },
221
+ "numBytes": "28947",
222
+ "numLongTermBytes": "28947",
223
+ "numRows": "344",
224
+ "creationTime": "1619804743188",
225
+ "lastModifiedTime": "1634584675234",
226
+ "type": "TABLE",
227
+ "location": "US",
228
+ "numTimeTravelPhysicalBytes": "0",
229
+ "numTotalLogicalBytes": "28947",
230
+ "numActiveLogicalBytes": "0",
231
+ "numLongTermLogicalBytes": "28947",
232
+ "numTotalPhysicalBytes": "5350",
233
+ "numActivePhysicalBytes": "0",
234
+ "numLongTermPhysicalBytes": "5350",
235
+ "numCurrentPhysicalBytes": "5350"
236
+ }
237
+ """
238
+ try:
239
+ bq_client = client.get_bigquery_client(credentials=credentials)
240
+ return bq_client.get_table(
241
+ bigquery.TableReference(
242
+ bigquery.DatasetReference(project_id, dataset_id), table_id
243
+ )
244
+ ).to_api_repr()
245
+ except Exception as ex:
246
+ return {
247
+ "status": "ERROR",
248
+ "error_details": str(ex),
249
+ }