Skip to content

Commit 0cf0805

Browse files
committed
feat:Bigquery ADK support for search catalog tool
1 parent 330329a commit 0cf0805

File tree

2 files changed

+49
-9
lines changed

2 files changed

+49
-9
lines changed

src/google/adk/tools/bigquery/search_tool.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def search_catalog(
4545
project_id: str,
4646
credentials: Credentials,
4747
settings: BigQueryToolConfig,
48-
location: str,
48+
location: Optional[str] = None,
4949
page_size: int = 10,
5050
project_ids_filter: Optional[List[str]] = None,
5151
dataset_ids_filter: Optional[List[str]] = None,
@@ -113,7 +113,8 @@ def search_catalog(
113113

114114
full_query = " AND ".join(filter(None, query_parts))
115115

116-
search_scope = f"projects/{project_id}/locations/{location}"
116+
search_location = location or settings.location or "global"
117+
search_scope = f"projects/{project_id}/locations/{search_location}"
117118

118119
request = dataplex_v1.SearchEntriesRequest(
119120
name=search_scope,

tests/unittests/tools/bigquery/test_bigquery_search_tool.py

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def test_search_catalog_success(self):
6969
settings = _mock_settings()
7070
prompt = "customer data"
7171
project_id = "test-project"
72+
location = "us"
7273

7374
mock_api_results = [{
7475
"name": "entry1",
@@ -84,7 +85,9 @@ def test_search_catalog_success(self):
8485
_mock_search_entries_response(mock_api_results)
8586
)
8687

87-
result = search_tool.search_catalog(prompt, project_id, creds, settings)
88+
result = search_tool.search_catalog(
89+
prompt, project_id, creds, settings, location
90+
)
8891

8992
assert result["status"] == "SUCCESS"
9093
assert len(result["results"]) == 1
@@ -99,7 +102,7 @@ def test_search_catalog_success(self):
99102
'(customer data) AND projectid="test-project" AND system=BIGQUERY'
100103
)
101104
self.mock_search_request.assert_called_once_with(
102-
name=f"projects/{project_id}/locations/global",
105+
name=f"projects/{project_id}/locations/us",
103106
query=expected_query,
104107
page_size=10,
105108
semantic_search=True,
@@ -111,7 +114,7 @@ def test_search_catalog_success(self):
111114
def test_search_catalog_no_project_id(self):
112115
"""Test search_catalog with missing project_id."""
113116
result = search_tool.search_catalog(
114-
"test", "", _mock_creds(), _mock_settings()
117+
"test", "", _mock_creds(), _mock_settings(), "us"
115118
)
116119
assert result["status"] == "ERROR"
117120
assert "project_id must be provided" in result["error_details"]
@@ -124,10 +127,10 @@ def test_search_catalog_api_error(self):
124127
)
125128

126129
result = search_tool.search_catalog(
127-
"test", "test-project", _mock_creds(), _mock_settings()
130+
"test", "test-project", _mock_creds(), _mock_settings(), "us"
128131
)
129132
assert result["status"] == "ERROR"
130-
assert "Dataplex API Error: Invalid query" in result["error_details"]
133+
assert "Dataplex API Error: 400 Invalid query" in result["error_details"]
131134

132135
def test_search_catalog_other_exception(self):
133136
"""Test search_catalog handling unexpected exceptions."""
@@ -136,7 +139,7 @@ def test_search_catalog_other_exception(self):
136139
)
137140

138141
result = search_tool.search_catalog(
139-
"test", "test-project", _mock_creds(), _mock_settings()
142+
"test", "test-project", _mock_creds(), _mock_settings(), "us"
140143
)
141144
assert result["status"] == "ERROR"
142145
assert "Something went wrong" in result["error_details"]
@@ -166,6 +169,7 @@ def test_search_catalog_query_construction(
166169
"test-project",
167170
_mock_creds(),
168171
_mock_settings(),
172+
"us",
169173
project_ids_filter=project_ids,
170174
dataset_ids_filter=dataset_ids,
171175
types_filter=types,
@@ -184,7 +188,7 @@ def test_search_catalog_no_app_name(self):
184188
"""Test search_catalog when settings.application_name is None."""
185189
creds = _mock_creds()
186190
settings = _mock_settings(app_name=None)
187-
search_tool.search_catalog("test", "test-project", creds, settings)
191+
search_tool.search_catalog("test", "test-project", creds, settings, "us")
188192

189193
self.mock_get_dataplex_client.assert_called_once_with(
190194
credentials=creds, user_agent=[None, "search_catalog"]
@@ -330,3 +334,38 @@ def test_query_with_project_and_dataset_filters(self):
330334
self.mock_dataplex_client.search_entries.assert_called_once_with(
331335
request=self.mock_search_request.return_value
332336
)
337+
338+
def test_search_catalog_default_location(self):
339+
"""Test search_catalog fallback to global location when None is provided."""
340+
creds = _mock_creds()
341+
settings = _mock_settings()
342+
# settings.location is None by default
343+
344+
self.mock_dataplex_client.search_entries.return_value = (
345+
_mock_search_entries_response([])
346+
)
347+
348+
search_tool.search_catalog(
349+
"test", "test-project", creds, settings # location omitted
350+
)
351+
352+
self.mock_search_request.assert_called_once()
353+
name_arg = self.mock_search_request.call_args[1]["name"]
354+
assert "locations/global" in name_arg
355+
356+
def test_search_catalog_settings_location(self):
357+
"""Test search_catalog uses settings.location when provided."""
358+
creds = _mock_creds()
359+
settings = BigQueryToolConfig(location="eu")
360+
361+
self.mock_dataplex_client.search_entries.return_value = (
362+
_mock_search_entries_response([])
363+
)
364+
365+
search_tool.search_catalog(
366+
"test", "test-project", creds, settings # location omitted
367+
)
368+
369+
self.mock_search_request.assert_called_once()
370+
name_arg = self.mock_search_request.call_args[1]["name"]
371+
assert "locations/eu" in name_arg

0 commit comments

Comments
 (0)