Skip to content

Commit 08ebaed

Browse files
committed
feat(gooddata-sdk): [AUTO] Add AI Lake database instances, pipe tables, and StarRocks service management
1 parent 4cb8139 commit 08ebaed

11 files changed

Lines changed: 513 additions & 0 deletions

File tree

packages/gooddata-sdk/src/gooddata_sdk/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@
77
import logging
88

99
from gooddata_sdk._version import __version__
10+
from gooddata_sdk.catalog.ai_lake.entity_model.database_instance import (
11+
CatalogDatabaseInstance,
12+
CatalogProvisionDatabaseInstanceRequest,
13+
)
14+
from gooddata_sdk.catalog.ai_lake.entity_model.pipe_table import (
15+
CatalogCreatePipeTableRequest,
16+
CatalogPipeTable,
17+
CatalogPipeTableSummary,
18+
)
19+
from gooddata_sdk.catalog.ai_lake.entity_model.service_info import CatalogServiceInfo
20+
from gooddata_sdk.catalog.ai_lake.service import CatalogAiLakeService
1021
from gooddata_sdk.catalog.appearance.entity_model.color_palette import (
1122
CatalogColorPalette,
1223
CatalogColorPaletteAttributes,
@@ -36,6 +47,7 @@
3647
)
3748
from gooddata_sdk.catalog.data_source.entity_model.data_source import (
3849
CatalogDataSource,
50+
CatalogDataSourceAiLakehouse,
3951
CatalogDataSourceBigQuery,
4052
CatalogDataSourceDatabricks,
4153
CatalogDataSourceGdStorage,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# (C) 2026 GoodData Corporation
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# (C) 2026 GoodData Corporation
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# (C) 2026 GoodData Corporation
2+
from __future__ import annotations
3+
4+
from typing import Any
5+
6+
import attrs
7+
from gooddata_api_client.model.provision_database_instance_request import ProvisionDatabaseInstanceRequest
8+
9+
10+
@attrs.define(kw_only=True)
11+
class CatalogDatabaseInstance:
12+
"""Represents an AI Lake database instance."""
13+
14+
id: str
15+
name: str
16+
storage_ids: list[str] = attrs.field(factory=list)
17+
18+
@classmethod
19+
def from_api(cls, entity: dict[str, Any]) -> CatalogDatabaseInstance:
20+
return cls(
21+
id=entity["id"],
22+
name=entity["name"],
23+
storage_ids=entity.get("storage_ids") or [],
24+
)
25+
26+
27+
@attrs.define(kw_only=True)
28+
class CatalogProvisionDatabaseInstanceRequest:
29+
"""Request to provision a new AI Lake database instance."""
30+
31+
name: str
32+
storage_ids: list[str] = attrs.field(factory=list)
33+
34+
def as_api_model(self) -> ProvisionDatabaseInstanceRequest:
35+
return ProvisionDatabaseInstanceRequest(
36+
name=self.name,
37+
storage_ids=self.storage_ids,
38+
_check_type=False,
39+
)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# (C) 2026 GoodData Corporation
2+
from __future__ import annotations
3+
4+
from typing import Any
5+
6+
import attrs
7+
from gooddata_api_client.model.create_pipe_table_request import CreatePipeTableRequest
8+
9+
10+
@attrs.define(kw_only=True)
11+
class CatalogPipeTableSummary:
12+
"""Summary of an AI Lake pipe table as returned by the list endpoint."""
13+
14+
pipe_table_id: str
15+
table_name: str
16+
path_prefix: str
17+
columns: list[dict[str, Any]] = attrs.field(factory=list)
18+
19+
@classmethod
20+
def from_api(cls, entity: dict[str, Any]) -> CatalogPipeTableSummary:
21+
return cls(
22+
pipe_table_id=entity["pipe_table_id"],
23+
table_name=entity["table_name"],
24+
path_prefix=entity["path_prefix"],
25+
columns=entity.get("columns") or [],
26+
)
27+
28+
29+
@attrs.define(kw_only=True)
30+
class CatalogPipeTable:
31+
"""Full representation of an AI Lake pipe table."""
32+
33+
pipe_table_id: str
34+
table_name: str
35+
source_storage_name: str
36+
path_prefix: str
37+
database_name: str
38+
polling_interval_seconds: int
39+
partition_columns: list[str] = attrs.field(factory=list)
40+
table_properties: dict[str, str] = attrs.field(factory=dict)
41+
columns: list[dict[str, Any]] = attrs.field(factory=list)
42+
43+
@classmethod
44+
def from_api(cls, entity: dict[str, Any]) -> CatalogPipeTable:
45+
return cls(
46+
pipe_table_id=entity["pipe_table_id"],
47+
table_name=entity["table_name"],
48+
source_storage_name=entity["source_storage_name"],
49+
path_prefix=entity["path_prefix"],
50+
database_name=entity["database_name"],
51+
polling_interval_seconds=entity["polling_interval_seconds"],
52+
partition_columns=entity.get("partition_columns") or [],
53+
table_properties=entity.get("table_properties") or {},
54+
columns=entity.get("columns") or [],
55+
)
56+
57+
58+
@attrs.define(kw_only=True)
59+
class CatalogCreatePipeTableRequest:
60+
"""Request to create a new AI Lake pipe table."""
61+
62+
path_prefix: str
63+
source_storage_name: str
64+
table_name: str
65+
column_overrides: dict[str, str] | None = None
66+
max_varchar_length: int | None = None
67+
polling_interval_seconds: int | None = None
68+
table_properties: dict[str, str] | None = None
69+
70+
def as_api_model(self) -> CreatePipeTableRequest:
71+
kwargs: dict[str, Any] = {}
72+
if self.column_overrides is not None:
73+
kwargs["column_overrides"] = self.column_overrides
74+
if self.max_varchar_length is not None:
75+
kwargs["max_varchar_length"] = self.max_varchar_length
76+
if self.polling_interval_seconds is not None:
77+
kwargs["polling_interval_seconds"] = self.polling_interval_seconds
78+
if self.table_properties is not None:
79+
kwargs["table_properties"] = self.table_properties
80+
return CreatePipeTableRequest(
81+
path_prefix=self.path_prefix,
82+
source_storage_name=self.source_storage_name,
83+
table_name=self.table_name,
84+
_check_type=False,
85+
**kwargs,
86+
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# (C) 2026 GoodData Corporation
2+
from __future__ import annotations
3+
4+
from typing import Any
5+
6+
import attrs
7+
8+
9+
@attrs.define(kw_only=True)
10+
class CatalogServiceInfo:
11+
"""Information about an AI Lake service."""
12+
13+
name: str
14+
service_id: str
15+
16+
@classmethod
17+
def from_api(cls, entity: dict[str, Any]) -> CatalogServiceInfo:
18+
return cls(
19+
name=entity["name"],
20+
service_id=entity["service_id"],
21+
)
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# (C) 2026 GoodData Corporation
2+
from __future__ import annotations
3+
4+
from gooddata_sdk.catalog.ai_lake.entity_model.database_instance import (
5+
CatalogDatabaseInstance,
6+
CatalogProvisionDatabaseInstanceRequest,
7+
)
8+
from gooddata_sdk.catalog.ai_lake.entity_model.pipe_table import (
9+
CatalogCreatePipeTableRequest,
10+
CatalogPipeTable,
11+
CatalogPipeTableSummary,
12+
)
13+
from gooddata_sdk.catalog.ai_lake.entity_model.service_info import CatalogServiceInfo
14+
from gooddata_sdk.client import GoodDataApiClient
15+
16+
17+
class CatalogAiLakeService:
18+
"""Service for managing AI Lake database instances, pipe tables, and StarRocks services."""
19+
20+
def __init__(self, api_client: GoodDataApiClient) -> None:
21+
self._client = api_client
22+
self._ai_lake_api = api_client.ai_lake_api
23+
self._ai_lake_pipe_tables_api = api_client.ai_lake_pipe_tables_api
24+
25+
# Database instance methods
26+
27+
def provision_database_instance(
28+
self,
29+
request: CatalogProvisionDatabaseInstanceRequest,
30+
) -> None:
31+
"""Provision a new AI Lake database instance.
32+
33+
Args:
34+
request (CatalogProvisionDatabaseInstanceRequest):
35+
The provision request containing name and storage IDs.
36+
37+
Returns:
38+
None
39+
"""
40+
self._ai_lake_api.provision_ai_lake_database_instance(
41+
request.as_api_model(),
42+
_check_return_type=False,
43+
)
44+
45+
def get_database_instance(self, instance_id: str) -> CatalogDatabaseInstance:
46+
"""Retrieve an AI Lake database instance by ID or name.
47+
48+
Args:
49+
instance_id (str):
50+
Database instance identifier (name preferred, or UUID).
51+
52+
Returns:
53+
CatalogDatabaseInstance:
54+
The database instance.
55+
"""
56+
response = self._ai_lake_api.get_ai_lake_database_instance(
57+
instance_id,
58+
_check_return_type=False,
59+
)
60+
return CatalogDatabaseInstance.from_api(response.to_dict(camel_case=False))
61+
62+
def list_database_instances(self) -> list[CatalogDatabaseInstance]:
63+
"""List all AI Lake database instances.
64+
65+
Returns:
66+
list[CatalogDatabaseInstance]:
67+
All database instances in the organization.
68+
"""
69+
response = self._ai_lake_api.list_ai_lake_database_instances(
70+
_check_return_type=False,
71+
)
72+
data = response.to_dict(camel_case=False)
73+
return [CatalogDatabaseInstance.from_api(db) for db in data.get("databases") or []]
74+
75+
def deprovision_database_instance(self, instance_id: str) -> None:
76+
"""Delete an existing AI Lake database instance.
77+
78+
Args:
79+
instance_id (str):
80+
Database instance identifier (name preferred, or UUID).
81+
82+
Returns:
83+
None
84+
"""
85+
self._ai_lake_api.deprovision_ai_lake_database_instance(
86+
instance_id,
87+
_check_return_type=False,
88+
)
89+
90+
# Pipe table methods
91+
92+
def create_pipe_table(
93+
self,
94+
instance_id: str,
95+
request: CatalogCreatePipeTableRequest,
96+
) -> None:
97+
"""Create a new AI Lake pipe table in the given database instance.
98+
99+
Args:
100+
instance_id (str):
101+
Database instance identifier.
102+
request (CatalogCreatePipeTableRequest):
103+
The create request with path prefix, source storage name, and table name.
104+
105+
Returns:
106+
None
107+
"""
108+
self._ai_lake_pipe_tables_api.create_ai_lake_pipe_table(
109+
instance_id,
110+
request.as_api_model(),
111+
_check_return_type=False,
112+
)
113+
114+
def get_pipe_table(self, instance_id: str, table_name: str) -> CatalogPipeTable:
115+
"""Retrieve a specific AI Lake pipe table.
116+
117+
Args:
118+
instance_id (str):
119+
Database instance identifier.
120+
table_name (str):
121+
OLAP table name.
122+
123+
Returns:
124+
CatalogPipeTable:
125+
The full pipe table details.
126+
"""
127+
response = self._ai_lake_pipe_tables_api.get_ai_lake_pipe_table(
128+
instance_id,
129+
table_name,
130+
_check_return_type=False,
131+
)
132+
return CatalogPipeTable.from_api(response.to_dict(camel_case=False))
133+
134+
def list_pipe_tables(self, instance_id: str) -> list[CatalogPipeTableSummary]:
135+
"""List all AI Lake pipe tables for a database instance.
136+
137+
Args:
138+
instance_id (str):
139+
Database instance identifier.
140+
141+
Returns:
142+
list[CatalogPipeTableSummary]:
143+
All pipe tables in the given database instance.
144+
"""
145+
response = self._ai_lake_pipe_tables_api.list_ai_lake_pipe_tables(
146+
instance_id,
147+
_check_return_type=False,
148+
)
149+
data = response.to_dict(camel_case=False)
150+
return [CatalogPipeTableSummary.from_api(pt) for pt in data.get("pipe_tables") or []]
151+
152+
def delete_pipe_table(self, instance_id: str, table_name: str) -> None:
153+
"""Delete an AI Lake pipe table.
154+
155+
Args:
156+
instance_id (str):
157+
Database instance identifier.
158+
table_name (str):
159+
OLAP table name.
160+
161+
Returns:
162+
None
163+
"""
164+
self._ai_lake_pipe_tables_api.delete_ai_lake_pipe_table(
165+
instance_id,
166+
table_name,
167+
_check_return_type=False,
168+
)
169+
170+
# Service methods
171+
172+
def list_services(self) -> list[CatalogServiceInfo]:
173+
"""List all AI Lake services configured for the organization.
174+
175+
Returns:
176+
list[CatalogServiceInfo]:
177+
All services configured in the organization's AI Lake.
178+
"""
179+
response = self._ai_lake_api.list_ai_lake_services(
180+
_check_return_type=False,
181+
)
182+
data = response.to_dict(camel_case=False)
183+
return [CatalogServiceInfo.from_api(svc) for svc in data.get("services") or []]

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/entity_model/data_source.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,3 +318,12 @@ class CatalogDataSourceGdStorage(CatalogDataSource):
318318
type: str = "GDSTORAGE"
319319
schema: str = ""
320320
credentials: Credentials = field(factory=_NoCredentials, repr=False)
321+
322+
323+
@define(kw_only=True, eq=False)
324+
class CatalogDataSourceAiLakehouse(CatalogDataSource):
325+
"""Data source backed by an AI Lake (StarRocks) database instance."""
326+
327+
type: str = "AILAKEHOUSE"
328+
schema: str = ""
329+
credentials: Credentials = field(factory=_NoCredentials, repr=False)

0 commit comments

Comments
 (0)