From 0dc9bf0fc9f045eb517ac0c823bacd44c15d141f Mon Sep 17 00:00:00 2001 From: Jan Kadlec Date: Sat, 14 Mar 2026 21:06:42 +0100 Subject: [PATCH] feat(gooddata-sdk): add CatalogAppearanceService for theme and color palette management Add sdk.catalog_appearance with CRUD operations (list, get, create, update, delete) for themes and color palettes via the AppearanceApi. Follows the existing service-based facade pattern. The API already exposed these endpoints but the SDK had no wrapper. jira: trivial risk: low --- .../administration/appearance/_index.md | 77 ++++++++ .../appearance/create_color_palette.md | 20 ++ .../administration/appearance/create_theme.md | 20 ++ .../appearance/delete_color_palette.md | 26 +++ .../administration/appearance/delete_theme.md | 26 +++ .../appearance/get_color_palette.md | 22 +++ .../administration/appearance/get_theme.md | 22 +++ .../appearance/list_color_palettes.md | 20 ++ .../administration/appearance/list_themes.md | 20 ++ .../appearance/update_color_palette.md | 26 +++ .../administration/appearance/update_theme.md | 26 +++ packages/gooddata-sdk/README.md | 1 + .../gooddata-sdk/src/gooddata_sdk/__init__.py | 9 + .../catalog/appearance/__init__.py | 1 + .../appearance/entity_model/__init__.py | 1 + .../appearance/entity_model/color_palette.py | 39 ++++ .../catalog/appearance/entity_model/theme.py | 39 ++++ .../catalog/appearance/service.py | 182 ++++++++++++++++++ .../gooddata-sdk/src/gooddata_sdk/client.py | 5 + packages/gooddata-sdk/src/gooddata_sdk/sdk.py | 6 + 20 files changed, 588 insertions(+) create mode 100644 docs/content/en/latest/administration/appearance/_index.md create mode 100644 docs/content/en/latest/administration/appearance/create_color_palette.md create mode 100644 docs/content/en/latest/administration/appearance/create_theme.md create mode 100644 docs/content/en/latest/administration/appearance/delete_color_palette.md create mode 100644 docs/content/en/latest/administration/appearance/delete_theme.md create mode 100644 docs/content/en/latest/administration/appearance/get_color_palette.md create mode 100644 docs/content/en/latest/administration/appearance/get_theme.md create mode 100644 docs/content/en/latest/administration/appearance/list_color_palettes.md create mode 100644 docs/content/en/latest/administration/appearance/list_themes.md create mode 100644 docs/content/en/latest/administration/appearance/update_color_palette.md create mode 100644 docs/content/en/latest/administration/appearance/update_theme.md create mode 100644 packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/__init__.py create mode 100644 packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/__init__.py create mode 100644 packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/color_palette.py create mode 100644 packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/theme.py create mode 100644 packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/service.py diff --git a/docs/content/en/latest/administration/appearance/_index.md b/docs/content/en/latest/administration/appearance/_index.md new file mode 100644 index 000000000..75d289e2d --- /dev/null +++ b/docs/content/en/latest/administration/appearance/_index.md @@ -0,0 +1,77 @@ +--- +title: "Appearance" +linkTitle: "Appearance" +weight: 15 +no_list: true +--- + +Manage themes and color palettes for your organization. + +## Methods + +### Themes + +* [list_themes](./list_themes/) +* [get_theme](./get_theme/) +* [create_theme](./create_theme/) +* [update_theme](./update_theme/) +* [delete_theme](./delete_theme/) + +### Color Palettes + +* [list_color_palettes](./list_color_palettes/) +* [get_color_palette](./get_color_palette/) +* [create_color_palette](./create_color_palette/) +* [update_color_palette](./update_color_palette/) +* [delete_color_palette](./delete_color_palette/) + +## Example + +Create a custom theme and color palette: + +```python +from gooddata_sdk import GoodDataSdk, CatalogTheme, CatalogColorPalette + +host = "https://www.example.com" +token = "some_user_token" +sdk = GoodDataSdk.create(host, token) + +# Create a custom theme +theme = CatalogTheme.init( + theme_id="my_dark_theme", + name="My Dark Theme", + content={ + "palette": { + "primary": {"base": "#14B2E2"}, + }, + "dashboards": { + "content": { + "widget": { + "backgroundColor": "#122330", + } + } + }, + }, +) +sdk.catalog_appearance.create_theme(theme) + +# List all themes +themes = sdk.catalog_appearance.list_themes() + +# Create a custom color palette for charts +palette = CatalogColorPalette.init( + color_palette_id="my_palette", + name="My Palette", + content={ + "colorPalette": [ + {"guid": "01", "fill": {"r": 140, "g": 125, "b": 232}}, + {"guid": "02", "fill": {"r": 125, "g": 219, "b": 232}}, + ] + }, +) +sdk.catalog_appearance.create_color_palette(palette) + +# Clean up +sdk.catalog_appearance.delete_theme("my_dark_theme") +sdk.catalog_appearance.delete_color_palette("my_palette") +``` diff --git a/docs/content/en/latest/administration/appearance/create_color_palette.md b/docs/content/en/latest/administration/appearance/create_color_palette.md new file mode 100644 index 000000000..5b206ec1b --- /dev/null +++ b/docs/content/en/latest/administration/appearance/create_color_palette.md @@ -0,0 +1,20 @@ +--- +title: "create_color_palette" +linkTitle: "create_color_palette" +superheading: "catalog_appearance." +weight: 220 +--- + +``create_color_palette( color_palette: CatalogColorPalette ) -> None`` + +Create a new color palette. + +## Parameters + +| parameter | type | description | +| -- | -- | -- | +| color_palette | CatalogColorPalette | A catalog color palette object to be created. | + +## Returns + +_None_ diff --git a/docs/content/en/latest/administration/appearance/create_theme.md b/docs/content/en/latest/administration/appearance/create_theme.md new file mode 100644 index 000000000..54b7fe0dd --- /dev/null +++ b/docs/content/en/latest/administration/appearance/create_theme.md @@ -0,0 +1,20 @@ +--- +title: "create_theme" +linkTitle: "create_theme" +superheading: "catalog_appearance." +weight: 120 +--- + +``create_theme( theme: CatalogTheme ) -> None`` + +Create a new theme. + +## Parameters + +| parameter | type | description | +| -- | -- | -- | +| theme | CatalogTheme | A catalog theme object to be created. | + +## Returns + +_None_ diff --git a/docs/content/en/latest/administration/appearance/delete_color_palette.md b/docs/content/en/latest/administration/appearance/delete_color_palette.md new file mode 100644 index 000000000..8dced3d02 --- /dev/null +++ b/docs/content/en/latest/administration/appearance/delete_color_palette.md @@ -0,0 +1,26 @@ +--- +title: "delete_color_palette" +linkTitle: "delete_color_palette" +superheading: "catalog_appearance." +weight: 240 +--- + +``delete_color_palette( color_palette_id: str ) -> None`` + +Delete a color palette. + +## Parameters + +| parameter | type | description | +| -- | -- | -- | +| color_palette_id | str | Color palette identification string e.g. "my_palette" | + +## Returns + +_None_ + +## Raises + +| type | description | +| -- | -- | +| ValueError | Color palette does not exist. | diff --git a/docs/content/en/latest/administration/appearance/delete_theme.md b/docs/content/en/latest/administration/appearance/delete_theme.md new file mode 100644 index 000000000..934868b32 --- /dev/null +++ b/docs/content/en/latest/administration/appearance/delete_theme.md @@ -0,0 +1,26 @@ +--- +title: "delete_theme" +linkTitle: "delete_theme" +superheading: "catalog_appearance." +weight: 140 +--- + +``delete_theme( theme_id: str ) -> None`` + +Delete a theme. + +## Parameters + +| parameter | type | description | +| -- | -- | -- | +| theme_id | str | Theme identification string e.g. "my_dark_theme" | + +## Returns + +_None_ + +## Raises + +| type | description | +| -- | -- | +| ValueError | Theme does not exist. | diff --git a/docs/content/en/latest/administration/appearance/get_color_palette.md b/docs/content/en/latest/administration/appearance/get_color_palette.md new file mode 100644 index 000000000..8b76f01db --- /dev/null +++ b/docs/content/en/latest/administration/appearance/get_color_palette.md @@ -0,0 +1,22 @@ +--- +title: "get_color_palette" +linkTitle: "get_color_palette" +superheading: "catalog_appearance." +weight: 210 +--- + +``get_color_palette( color_palette_id: str ) -> CatalogColorPalette`` + +Get an individual color palette. + +## Parameters + +| parameter | type | description | +| -- | -- | -- | +| color_palette_id | str | Color palette identification string e.g. "my_palette" | + +## Returns + +| type | description | +| -- | -- | +| CatalogColorPalette | Catalog color palette object containing structure of the color palette. | diff --git a/docs/content/en/latest/administration/appearance/get_theme.md b/docs/content/en/latest/administration/appearance/get_theme.md new file mode 100644 index 000000000..1f574f79b --- /dev/null +++ b/docs/content/en/latest/administration/appearance/get_theme.md @@ -0,0 +1,22 @@ +--- +title: "get_theme" +linkTitle: "get_theme" +superheading: "catalog_appearance." +weight: 110 +--- + +``get_theme( theme_id: str ) -> CatalogTheme`` + +Get an individual theme. + +## Parameters + +| parameter | type | description | +| -- | -- | -- | +| theme_id | str | Theme identification string e.g. "my_dark_theme" | + +## Returns + +| type | description | +| -- | -- | +| CatalogTheme | Catalog theme object containing structure of the theme. | diff --git a/docs/content/en/latest/administration/appearance/list_color_palettes.md b/docs/content/en/latest/administration/appearance/list_color_palettes.md new file mode 100644 index 000000000..00755f3da --- /dev/null +++ b/docs/content/en/latest/administration/appearance/list_color_palettes.md @@ -0,0 +1,20 @@ +--- +title: "list_color_palettes" +linkTitle: "list_color_palettes" +superheading: "catalog_appearance." +weight: 200 +--- + +``list_color_palettes( ) -> list[CatalogColorPalette]`` + +Returns a list of all color palettes in the current organization. + +## Parameters + +_None_ + +## Returns + +| type | description | +| -- | -- | +| list[CatalogColorPalette] | List of color palettes in the current organization. | diff --git a/docs/content/en/latest/administration/appearance/list_themes.md b/docs/content/en/latest/administration/appearance/list_themes.md new file mode 100644 index 000000000..50c11edde --- /dev/null +++ b/docs/content/en/latest/administration/appearance/list_themes.md @@ -0,0 +1,20 @@ +--- +title: "list_themes" +linkTitle: "list_themes" +superheading: "catalog_appearance." +weight: 100 +--- + +``list_themes( ) -> list[CatalogTheme]`` + +Returns a list of all themes in the current organization. + +## Parameters + +_None_ + +## Returns + +| type | description | +| -- | -- | +| list[CatalogTheme] | List of themes in the current organization. | diff --git a/docs/content/en/latest/administration/appearance/update_color_palette.md b/docs/content/en/latest/administration/appearance/update_color_palette.md new file mode 100644 index 000000000..b0ad0bd56 --- /dev/null +++ b/docs/content/en/latest/administration/appearance/update_color_palette.md @@ -0,0 +1,26 @@ +--- +title: "update_color_palette" +linkTitle: "update_color_palette" +superheading: "catalog_appearance." +weight: 230 +--- + +``update_color_palette( color_palette: CatalogColorPalette ) -> None`` + +Update a color palette. + +## Parameters + +| parameter | type | description | +| -- | -- | -- | +| color_palette | CatalogColorPalette | A catalog color palette object to be updated. | + +## Returns + +_None_ + +## Raises + +| type | description | +| -- | -- | +| ValueError | Color palette does not exist. | diff --git a/docs/content/en/latest/administration/appearance/update_theme.md b/docs/content/en/latest/administration/appearance/update_theme.md new file mode 100644 index 000000000..b394a49b5 --- /dev/null +++ b/docs/content/en/latest/administration/appearance/update_theme.md @@ -0,0 +1,26 @@ +--- +title: "update_theme" +linkTitle: "update_theme" +superheading: "catalog_appearance." +weight: 130 +--- + +``update_theme( theme: CatalogTheme ) -> None`` + +Update a theme. + +## Parameters + +| parameter | type | description | +| -- | -- | -- | +| theme | CatalogTheme | A catalog theme object to be updated. | + +## Returns + +_None_ + +## Raises + +| type | description | +| -- | -- | +| ValueError | Theme does not exist. | diff --git a/packages/gooddata-sdk/README.md b/packages/gooddata-sdk/README.md index dd1a57745..bf0eb63cb 100644 --- a/packages/gooddata-sdk/README.md +++ b/packages/gooddata-sdk/README.md @@ -9,6 +9,7 @@ At the moment the SDK provides services to inspect and interact with the Semanti * Catalog User Service * Catalog Permission Service * Catalog Organization Service +* Catalog Appearance Service * Visualizations Service * Compute Service * Table Service diff --git a/packages/gooddata-sdk/src/gooddata_sdk/__init__.py b/packages/gooddata-sdk/src/gooddata_sdk/__init__.py index 426d8a93e..1be061a11 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/__init__.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/__init__.py @@ -7,6 +7,15 @@ import logging from gooddata_sdk._version import __version__ +from gooddata_sdk.catalog.appearance.entity_model.color_palette import ( + CatalogColorPalette, + CatalogColorPaletteAttributes, +) +from gooddata_sdk.catalog.appearance.entity_model.theme import ( + CatalogTheme, + CatalogThemeAttributes, +) +from gooddata_sdk.catalog.appearance.service import CatalogAppearanceService from gooddata_sdk.catalog.data_source.action_model.requests.ldm_request import ( CatalogGenerateLdmRequest, CatalogPdmLdmRequest, diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/__init__.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/__init__.py new file mode 100644 index 000000000..06549c73b --- /dev/null +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/__init__.py @@ -0,0 +1 @@ +# (C) 2024 GoodData Corporation diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/__init__.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/__init__.py new file mode 100644 index 000000000..06549c73b --- /dev/null +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/__init__.py @@ -0,0 +1 @@ +# (C) 2024 GoodData Corporation diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/color_palette.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/color_palette.py new file mode 100644 index 000000000..4d82505df --- /dev/null +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/color_palette.py @@ -0,0 +1,39 @@ +# (C) 2024 GoodData Corporation +from __future__ import annotations + +from typing import Any + +from attrs import define +from gooddata_api_client.model.json_api_color_palette_in import JsonApiColorPaletteIn +from gooddata_api_client.model.json_api_color_palette_in_attributes import JsonApiColorPaletteInAttributes + +from gooddata_sdk.catalog.base import Base + + +@define(kw_only=True) +class CatalogColorPalette(Base): + id: str + attributes: CatalogColorPaletteAttributes + + @staticmethod + def client_class() -> type[JsonApiColorPaletteIn]: + return JsonApiColorPaletteIn + + @classmethod + def init( + cls, + color_palette_id: str, + name: str, + content: dict[str, Any], + ) -> CatalogColorPalette: + return cls(id=color_palette_id, attributes=CatalogColorPaletteAttributes(content=content, name=name)) + + +@define(kw_only=True) +class CatalogColorPaletteAttributes(Base): + content: dict[str, Any] + name: str + + @staticmethod + def client_class() -> type[JsonApiColorPaletteInAttributes]: + return JsonApiColorPaletteInAttributes diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/theme.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/theme.py new file mode 100644 index 000000000..0fac1430c --- /dev/null +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/entity_model/theme.py @@ -0,0 +1,39 @@ +# (C) 2024 GoodData Corporation +from __future__ import annotations + +from typing import Any + +from attrs import define +from gooddata_api_client.model.json_api_color_palette_in_attributes import JsonApiColorPaletteInAttributes +from gooddata_api_client.model.json_api_theme_in import JsonApiThemeIn + +from gooddata_sdk.catalog.base import Base + + +@define(kw_only=True) +class CatalogTheme(Base): + id: str + attributes: CatalogThemeAttributes + + @staticmethod + def client_class() -> type[JsonApiThemeIn]: + return JsonApiThemeIn + + @classmethod + def init( + cls, + theme_id: str, + name: str, + content: dict[str, Any], + ) -> CatalogTheme: + return cls(id=theme_id, attributes=CatalogThemeAttributes(content=content, name=name)) + + +@define(kw_only=True) +class CatalogThemeAttributes(Base): + content: dict[str, Any] + name: str + + @staticmethod + def client_class() -> type[JsonApiColorPaletteInAttributes]: + return JsonApiColorPaletteInAttributes diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/service.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/service.py new file mode 100644 index 000000000..ef6f0bbcf --- /dev/null +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/appearance/service.py @@ -0,0 +1,182 @@ +# (C) 2024 GoodData Corporation +from __future__ import annotations + +import functools + +from gooddata_api_client.exceptions import NotFoundException +from gooddata_api_client.model.json_api_color_palette_in_document import JsonApiColorPaletteInDocument +from gooddata_api_client.model.json_api_theme_in_document import JsonApiThemeInDocument + +from gooddata_sdk.catalog.appearance.entity_model.color_palette import CatalogColorPalette +from gooddata_sdk.catalog.appearance.entity_model.theme import CatalogTheme +from gooddata_sdk.catalog.catalog_service_base import CatalogServiceBase +from gooddata_sdk.client import GoodDataApiClient +from gooddata_sdk.utils import load_all_entities + + +class CatalogAppearanceService(CatalogServiceBase): + def __init__(self, api_client: GoodDataApiClient) -> None: + super().__init__(api_client) + self._appearance_api = api_client.appearance_api + + # Theme methods + + def list_themes(self) -> list[CatalogTheme]: + """Returns a list of all themes in the current organization. + + Returns: + list[CatalogTheme]: + List of themes in the current organization. + """ + get_themes = functools.partial(self._appearance_api.get_all_entities_themes, _check_return_type=False) + themes = load_all_entities(get_themes) + return [CatalogTheme.from_api(theme) for theme in themes.data] + + def get_theme(self, theme_id: str) -> CatalogTheme: + """Get an individual theme. + + Args: + theme_id (str): + Theme identification string e.g. "my_dark_theme" + + Returns: + CatalogTheme: + Catalog theme object containing structure of the theme. + """ + theme_api = self._appearance_api.get_entity_themes(id=theme_id).data + return CatalogTheme.from_api(theme_api) + + def create_theme(self, theme: CatalogTheme) -> None: + """Create a new theme. + + Args: + theme (CatalogTheme): + A catalog theme object to be created. + + Returns: + None + """ + theme_document = JsonApiThemeInDocument(data=theme.to_api()) + self._appearance_api.create_entity_themes(json_api_theme_in_document=theme_document) + + def update_theme(self, theme: CatalogTheme) -> None: + """Update a theme. + + Args: + theme (CatalogTheme): + A catalog theme object to be updated. + + Returns: + None + + Raises: + ValueError: + Theme does not exist. + """ + try: + theme_document = JsonApiThemeInDocument(data=theme.to_api()) + self._appearance_api.update_entity_themes(theme.id, json_api_theme_in_document=theme_document) + except NotFoundException: + raise ValueError(f"Can not update {theme.id} theme. This theme does not exist.") + + def delete_theme(self, theme_id: str) -> None: + """Delete a theme. + + Args: + theme_id (str): + Theme identification string e.g. "my_dark_theme" + + Returns: + None + + Raises: + ValueError: + Theme does not exist. + """ + try: + self._appearance_api.delete_entity_themes(theme_id) + except NotFoundException: + raise ValueError(f"Can not delete {theme_id} theme. This theme does not exist.") + + # Color palette methods + + def list_color_palettes(self) -> list[CatalogColorPalette]: + """Returns a list of all color palettes in the current organization. + + Returns: + list[CatalogColorPalette]: + List of color palettes in the current organization. + """ + get_color_palettes = functools.partial( + self._appearance_api.get_all_entities_color_palettes, _check_return_type=False + ) + color_palettes = load_all_entities(get_color_palettes) + return [CatalogColorPalette.from_api(color_palette) for color_palette in color_palettes.data] + + def get_color_palette(self, color_palette_id: str) -> CatalogColorPalette: + """Get an individual color palette. + + Args: + color_palette_id (str): + Color palette identification string e.g. "my_palette" + + Returns: + CatalogColorPalette: + Catalog color palette object containing structure of the color palette. + """ + color_palette_api = self._appearance_api.get_entity_color_palettes(id=color_palette_id).data + return CatalogColorPalette.from_api(color_palette_api) + + def create_color_palette(self, color_palette: CatalogColorPalette) -> None: + """Create a new color palette. + + Args: + color_palette (CatalogColorPalette): + A catalog color palette object to be created. + + Returns: + None + """ + color_palette_document = JsonApiColorPaletteInDocument(data=color_palette.to_api()) + self._appearance_api.create_entity_color_palettes(json_api_color_palette_in_document=color_palette_document) + + def update_color_palette(self, color_palette: CatalogColorPalette) -> None: + """Update a color palette. + + Args: + color_palette (CatalogColorPalette): + A catalog color palette object to be updated. + + Returns: + None + + Raises: + ValueError: + Color palette does not exist. + """ + try: + color_palette_document = JsonApiColorPaletteInDocument(data=color_palette.to_api()) + self._appearance_api.update_entity_color_palettes( + color_palette.id, json_api_color_palette_in_document=color_palette_document + ) + except NotFoundException: + raise ValueError(f"Can not update {color_palette.id} color palette. This color palette does not exist.") + + def delete_color_palette(self, color_palette_id: str) -> None: + """Delete a color palette. + + Args: + color_palette_id (str): + Color palette identification string e.g. "my_palette" + + Returns: + None + + Raises: + ValueError: + Color palette does not exist. + """ + try: + self._appearance_api.delete_entity_color_palettes(color_palette_id) + except NotFoundException: + raise ValueError(f"Can not delete {color_palette_id} color palette. This color palette does not exist.") diff --git a/packages/gooddata-sdk/src/gooddata_sdk/client.py b/packages/gooddata-sdk/src/gooddata_sdk/client.py index 62bc12b9b..80ff83925 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/client.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/client.py @@ -70,6 +70,7 @@ def __init__( self._layout_api = apis.LayoutApi(self._api_client) self._actions_api = apis.ActionsApi(self._api_client) self._user_management_api = apis.UserManagementApi(self._api_client) + self._appearance_api = apis.AppearanceApi(self._api_client) self._executions_cancellable = executions_cancellable def _do_post_request( @@ -153,6 +154,10 @@ def actions_api(self) -> apis.ActionsApi: def user_management_api(self) -> apis.UserManagementApi: return self._user_management_api + @property + def appearance_api(self) -> apis.AppearanceApi: + return self._appearance_api + @property def executions_cancellable(self) -> bool: return self._executions_cancellable diff --git a/packages/gooddata-sdk/src/gooddata_sdk/sdk.py b/packages/gooddata-sdk/src/gooddata_sdk/sdk.py index 8c6ea5c48..003840083 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/sdk.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/sdk.py @@ -3,6 +3,7 @@ from pathlib import Path +from gooddata_sdk.catalog.appearance.service import CatalogAppearanceService from gooddata_sdk.catalog.data_source.service import CatalogDataSourceService from gooddata_sdk.catalog.export.service import ExportService from gooddata_sdk.catalog.organization.service import CatalogOrganizationService @@ -76,6 +77,7 @@ def __init__(self, client: GoodDataApiClient) -> None: """ self._client = client + self._catalog_appearance = CatalogAppearanceService(self._client) self._catalog_workspace = CatalogWorkspaceService(self._client) self._catalog_workspace_content = CatalogWorkspaceContentService(self._client) self._catalog_data_source = CatalogDataSourceService(self._client) @@ -88,6 +90,10 @@ def __init__(self, client: GoodDataApiClient) -> None: self._catalog_permission = CatalogPermissionService(self._client) self._export = ExportService(self._client) + @property + def catalog_appearance(self) -> CatalogAppearanceService: + return self._catalog_appearance + @property def catalog_workspace(self) -> CatalogWorkspaceService: return self._catalog_workspace