Skip to content

Commit 8383bec

Browse files
committed
feat(gooddata-sdk): [AUTO] Add AI catalog generateDescription, generateTitle, trendingObjects endpoints
1 parent 4cb8139 commit 8383bec

2 files changed

Lines changed: 142 additions & 0 deletions

File tree

packages/gooddata-sdk/src/gooddata_sdk/compute/service.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@
1212
from gooddata_api_client.model.chat_history_result import ChatHistoryResult
1313
from gooddata_api_client.model.chat_request import ChatRequest
1414
from gooddata_api_client.model.chat_result import ChatResult
15+
from gooddata_api_client.model.generate_description_request import GenerateDescriptionRequest
16+
from gooddata_api_client.model.generate_description_response import GenerateDescriptionResponse
17+
from gooddata_api_client.model.generate_title_request import GenerateTitleRequest
18+
from gooddata_api_client.model.generate_title_response import GenerateTitleResponse
1519
from gooddata_api_client.model.saved_visualization import SavedVisualization
1620
from gooddata_api_client.model.search_request import SearchRequest
1721
from gooddata_api_client.model.search_result import SearchResult
22+
from gooddata_api_client.model.trending_objects_result import TrendingObjectsResult
1823

1924
from gooddata_sdk.client import GoodDataApiClient
2025
from gooddata_sdk.compute.model.execution import (
@@ -276,6 +281,7 @@ def search_ai(
276281
workspace_id: str,
277282
question: str,
278283
deep_search: bool | None = None,
284+
enable_hybrid_search: bool | None = None,
279285
limit: int | None = None,
280286
object_types: list[str] | None = None,
281287
relevant_score_threshold: float | None = None,
@@ -288,6 +294,8 @@ def search_ai(
288294
workspace_id (str): workspace identifier
289295
question (str): keyword/sentence input for search
290296
deep_search (bool): turn on deep search - if true, content of complex objects will be searched as well
297+
enable_hybrid_search (Optional[bool]): if true, enables hybrid search combining vector similarity and
298+
keyword matching. Defaults to None.
291299
limit (Optional[int]): maximum number of results to return. Defaults to None.
292300
object_types (Optional[list[str]]): list of object types to search for. Enum items: "attribute", "metric", "fact",
293301
"label", "date", "dataset", "visualization" and "dashboard". Defaults to None.
@@ -303,6 +311,8 @@ def search_ai(
303311
search_params: dict[str, Any] = {}
304312
if deep_search is not None:
305313
search_params["deep_search"] = deep_search
314+
if enable_hybrid_search is not None:
315+
search_params["enable_hybrid_search"] = enable_hybrid_search
306316
if limit is not None:
307317
search_params["limit"] = limit
308318
if object_types is not None:
@@ -315,6 +325,63 @@ def search_ai(
315325
response = self._actions_api.ai_search(workspace_id, search_request, _check_return_type=False)
316326
return response
317327

328+
def generate_description(
329+
self,
330+
workspace_id: str,
331+
object_id: str,
332+
object_type: str,
333+
) -> GenerateDescriptionResponse:
334+
"""
335+
Generate a description for an analytics catalog object.
336+
337+
Args:
338+
workspace_id (str): workspace identifier
339+
object_id (str): identifier of the object to describe
340+
object_type (str): type of the object to describe.
341+
One of: "Visualization", "Dashboard", "Metric", "Fact", "Attribute"
342+
343+
Returns:
344+
GenerateDescriptionResponse: Generated description and optional note
345+
"""
346+
request = GenerateDescriptionRequest(object_id=object_id, object_type=object_type, _check_type=False)
347+
response = self._actions_api.generate_description(workspace_id, request, _check_return_type=False)
348+
return response
349+
350+
def generate_title(
351+
self,
352+
workspace_id: str,
353+
object_id: str,
354+
object_type: str,
355+
) -> GenerateTitleResponse:
356+
"""
357+
Generate a title for an analytics catalog object.
358+
359+
Args:
360+
workspace_id (str): workspace identifier
361+
object_id (str): identifier of the object to generate a title for
362+
object_type (str): type of the object to generate a title for.
363+
One of: "Visualization", "Dashboard", "Metric", "Fact", "Attribute"
364+
365+
Returns:
366+
GenerateTitleResponse: Generated title and optional note
367+
"""
368+
request = GenerateTitleRequest(object_id=object_id, object_type=object_type, _check_type=False)
369+
response = self._actions_api.generate_title(workspace_id, request, _check_return_type=False)
370+
return response
371+
372+
def get_trending_objects(self, workspace_id: str) -> TrendingObjectsResult:
373+
"""
374+
Get trending analytics catalog objects for a workspace.
375+
376+
Args:
377+
workspace_id (str): workspace identifier
378+
379+
Returns:
380+
TrendingObjectsResult: List of trending analytics catalog objects
381+
"""
382+
response = self._actions_api.trending_objects(workspace_id, _check_return_type=False)
383+
return response
384+
318385
def cancel_executions(self, executions: dict[str, dict[str, str]]) -> None:
319386
"""
320387
Try to cancel given executions using the cancel api endpoint.

packages/gooddata-sdk/tests/compute/test_compute_service.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,81 @@ def test_ai_chat_stream(test_config):
219219
sdk.compute.reset_ai_chat_history(test_workspace_id)
220220

221221

222+
@gd_vcr.use_cassette(str(_fixtures_dir / "ai_search_hybrid.yaml"))
223+
def test_search_ai_with_hybrid_search(test_config):
224+
"""Test AI search with enable_hybrid_search parameter."""
225+
sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"])
226+
path = _current_dir / "load" / "ai"
227+
test_workspace_id = test_config["workspace_test"]
228+
229+
try:
230+
_setup_test_workspace(sdk, test_workspace_id, path)
231+
result = sdk.compute.search_ai(
232+
workspace_id=test_workspace_id,
233+
question="What is the total revenue?",
234+
enable_hybrid_search=True,
235+
)
236+
assert result is not None
237+
assert hasattr(result, "results")
238+
finally:
239+
sdk.catalog_workspace.delete_workspace(test_workspace_id)
240+
241+
242+
@gd_vcr.use_cassette(str(_fixtures_dir / "generate_description.yaml"))
243+
def test_generate_description(test_config):
244+
"""Test generate description for an analytics catalog object."""
245+
sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"])
246+
path = _current_dir / "load" / "ai"
247+
test_workspace_id = test_config["workspace_test"]
248+
249+
try:
250+
_setup_test_workspace(sdk, test_workspace_id, path)
251+
# Use a metric object type for description generation
252+
result = sdk.compute.generate_description(
253+
workspace_id=test_workspace_id,
254+
object_id="revenue",
255+
object_type="Metric",
256+
)
257+
assert result is not None
258+
finally:
259+
sdk.catalog_workspace.delete_workspace(test_workspace_id)
260+
261+
262+
@gd_vcr.use_cassette(str(_fixtures_dir / "generate_title.yaml"))
263+
def test_generate_title(test_config):
264+
"""Test generate title for an analytics catalog object."""
265+
sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"])
266+
path = _current_dir / "load" / "ai"
267+
test_workspace_id = test_config["workspace_test"]
268+
269+
try:
270+
_setup_test_workspace(sdk, test_workspace_id, path)
271+
result = sdk.compute.generate_title(
272+
workspace_id=test_workspace_id,
273+
object_id="revenue",
274+
object_type="Metric",
275+
)
276+
assert result is not None
277+
finally:
278+
sdk.catalog_workspace.delete_workspace(test_workspace_id)
279+
280+
281+
@gd_vcr.use_cassette(str(_fixtures_dir / "trending_objects.yaml"))
282+
def test_get_trending_objects(test_config):
283+
"""Test get trending analytics catalog objects."""
284+
sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"])
285+
path = _current_dir / "load" / "ai"
286+
test_workspace_id = test_config["workspace_test"]
287+
288+
try:
289+
_setup_test_workspace(sdk, test_workspace_id, path)
290+
result = sdk.compute.get_trending_objects(test_workspace_id)
291+
assert result is not None
292+
assert hasattr(result, "objects")
293+
finally:
294+
sdk.catalog_workspace.delete_workspace(test_workspace_id)
295+
296+
222297
@gd_vcr.use_cassette(str(_fixtures_dir / "build_exec_def_from_chat_result.yaml"))
223298
def test_build_exec_def_from_chat_result(test_config):
224299
"""Test build execution definition from chat result."""

0 commit comments

Comments
 (0)