Skip to content

Commit 78510f8

Browse files
committed
feat: add export template support
JIRA: F1-1268 risk: low
1 parent 92bbdf8 commit 78510f8

File tree

9 files changed

+272
-0
lines changed

9 files changed

+272
-0
lines changed

gooddata-sdk/gooddata_sdk/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,20 @@
7979
CatalogUserIdentifier,
8080
CatalogWorkspaceIdentifier,
8181
)
82+
from gooddata_sdk.catalog.organization.common.dashboard_slides_template import CatalogDashboardSlidesTemplate
83+
from gooddata_sdk.catalog.organization.common.running_section import CatalogRunningSection
84+
from gooddata_sdk.catalog.organization.common.slide_template import (
85+
CatalogContentSlideTemplate,
86+
CatalogCoverSlideTemplate,
87+
CatalogIntroSlideTemplate,
88+
CatalogSectionSlideTemplate,
89+
)
90+
from gooddata_sdk.catalog.organization.common.widget_slides_template import CatalogWidgetSlidesTemplate
8291
from gooddata_sdk.catalog.organization.entity_model.directive import CatalogCspDirective
92+
from gooddata_sdk.catalog.organization.entity_model.export_template import (
93+
CatalogExportTemplate,
94+
CatalogExportTemplateAttributes,
95+
)
8396
from gooddata_sdk.catalog.organization.entity_model.jwk import (
8497
CatalogJwk,
8598
CatalogJwkAttributes,
@@ -88,6 +101,9 @@
88101
)
89102
from gooddata_sdk.catalog.organization.entity_model.organization import CatalogOrganization
90103
from gooddata_sdk.catalog.organization.entity_model.setting import CatalogOrganizationSetting
104+
from gooddata_sdk.catalog.organization.layout.export_template import (
105+
CatalogDeclarativeExportTemplate,
106+
)
91107
from gooddata_sdk.catalog.organization.layout.notification_channel import (
92108
CatalogDeclarativeNotificationChannel,
93109
CatalogWebhook,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# (C) 2025 GoodData Corporation
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# (C) 2025 GoodData Corporation
2+
from typing import Literal, Optional
3+
4+
from attrs import define
5+
6+
from gooddata_sdk.catalog.organization.common.slide_template import (
7+
CatalogContentSlideTemplate,
8+
CatalogCoverSlideTemplate,
9+
CatalogIntroSlideTemplate,
10+
CatalogSectionSlideTemplate,
11+
)
12+
13+
14+
@define
15+
class CatalogDashboardSlidesTemplate:
16+
applied_on: list[Literal["PDF", "PPTX"]]
17+
cover_slide: Optional[CatalogCoverSlideTemplate] = None
18+
intro_slide: Optional[CatalogIntroSlideTemplate] = None
19+
section_slide: Optional[CatalogSectionSlideTemplate] = None
20+
content_slide: Optional[CatalogContentSlideTemplate] = None
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# (C) 2025 GoodData Corporation
2+
from typing import Optional
3+
4+
from attrs import define
5+
6+
7+
@define
8+
class CatalogRunningSection:
9+
left: Optional[str] = None
10+
right: Optional[str] = None
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# (C) 2025 GoodData Corporation
2+
from typing import Optional
3+
4+
from attrs import define
5+
6+
from gooddata_sdk.catalog.base import Base
7+
from gooddata_sdk.catalog.organization.common.running_section import CatalogRunningSection
8+
9+
10+
@define
11+
class CatalogCoverSlideTemplate(Base):
12+
background_image: bool
13+
description_field: Optional[str] = None
14+
header: Optional[CatalogRunningSection] = None
15+
footer: Optional[CatalogRunningSection] = None
16+
17+
18+
@define
19+
class CatalogIntroSlideTemplate(Base):
20+
background_image: bool
21+
title_field: Optional[str] = None
22+
description_field: Optional[str] = None
23+
header: Optional[CatalogRunningSection] = None
24+
footer: Optional[CatalogRunningSection] = None
25+
26+
27+
@define
28+
class CatalogSectionSlideTemplate(Base):
29+
background_image: bool
30+
header: Optional[CatalogRunningSection] = None
31+
footer: Optional[CatalogRunningSection] = None
32+
33+
34+
@define
35+
class CatalogContentSlideTemplate(Base):
36+
description_field: Optional[str] = None
37+
header: Optional[CatalogRunningSection] = None
38+
footer: Optional[CatalogRunningSection] = None
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# (C) 2025 GoodData Corporation
2+
from typing import Literal, Optional
3+
4+
from attrs import define
5+
6+
from gooddata_sdk.catalog.organization.common.slide_template import CatalogContentSlideTemplate
7+
8+
9+
@define
10+
class CatalogWidgetSlidesTemplate:
11+
applied_on: list[Literal["PDF", "PPTX"]]
12+
content_slide: Optional[CatalogContentSlideTemplate] = None
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# (C) 2025 GoodData Corporation
2+
from __future__ import annotations
3+
4+
import builtins
5+
from typing import Optional
6+
7+
from attrs import define
8+
from gooddata_api_client.model.json_api_export_template_in_attributes import JsonApiExportTemplateInAttributes
9+
from gooddata_api_client.model.json_api_export_template_post_optional_id import JsonApiExportTemplatePostOptionalId
10+
11+
from gooddata_sdk.catalog.base import Base
12+
from gooddata_sdk.catalog.organization.common.dashboard_slides_template import CatalogDashboardSlidesTemplate
13+
from gooddata_sdk.catalog.organization.common.widget_slides_template import CatalogWidgetSlidesTemplate
14+
15+
16+
@define(auto_attribs=True, kw_only=True)
17+
class CatalogExportTemplate(Base):
18+
id: str
19+
attributes: Optional[CatalogExportTemplateAttributes] = None
20+
21+
@staticmethod
22+
def client_class() -> builtins.type[JsonApiExportTemplatePostOptionalId]:
23+
return JsonApiExportTemplatePostOptionalId
24+
25+
26+
@define(auto_attribs=True, kw_only=True)
27+
class CatalogExportTemplateAttributes(Base):
28+
name: str
29+
dashboard_slides_template: Optional[CatalogDashboardSlidesTemplate] = None
30+
widget_slides_template: Optional[CatalogWidgetSlidesTemplate] = None
31+
32+
@staticmethod
33+
def client_class() -> builtins.type[JsonApiExportTemplateInAttributes]:
34+
return JsonApiExportTemplateInAttributes
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# (C) 2025 GoodData Corporation
2+
import builtins
3+
from typing import Optional
4+
5+
from attrs import define
6+
from gooddata_api_client.model.declarative_export_template import DeclarativeExportTemplate
7+
8+
from gooddata_sdk.catalog.base import Base
9+
from gooddata_sdk.catalog.organization.common.dashboard_slides_template import CatalogDashboardSlidesTemplate
10+
from gooddata_sdk.catalog.organization.common.widget_slides_template import CatalogWidgetSlidesTemplate
11+
12+
13+
@define
14+
class CatalogDeclarativeExportTemplate(Base):
15+
id: str
16+
name: str
17+
dashboard_slides_template: Optional[CatalogDashboardSlidesTemplate] = None
18+
widget_slides_template: Optional[CatalogWidgetSlidesTemplate] = None
19+
20+
@staticmethod
21+
def client_class() -> builtins.type[DeclarativeExportTemplate]:
22+
return DeclarativeExportTemplate

gooddata-sdk/gooddata_sdk/catalog/organization/service.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@
55
from typing import Optional
66

77
from gooddata_api_client.exceptions import NotFoundException
8+
from gooddata_api_client.model.declarative_export_templates import DeclarativeExportTemplates
89
from gooddata_api_client.model.declarative_notification_channels import DeclarativeNotificationChannels
910
from gooddata_api_client.model.json_api_csp_directive_in_document import JsonApiCspDirectiveInDocument
11+
from gooddata_api_client.model.json_api_export_template_in_document import JsonApiExportTemplateInDocument
12+
from gooddata_api_client.model.json_api_export_template_post_optional_id_document import (
13+
JsonApiExportTemplatePostOptionalIdDocument,
14+
)
1015
from gooddata_api_client.model.json_api_identity_provider_in_document import JsonApiIdentityProviderInDocument
1116
from gooddata_api_client.model.json_api_organization_setting_in_document import JsonApiOrganizationSettingInDocument
1217

18+
from gooddata_sdk import CatalogDeclarativeExportTemplate, CatalogExportTemplate
1319
from gooddata_sdk.catalog.catalog_service_base import CatalogServiceBase
1420
from gooddata_sdk.catalog.organization.entity_model.directive import CatalogCspDirective
1521
from gooddata_sdk.catalog.organization.entity_model.identity_provider import CatalogIdentityProvider
@@ -424,6 +430,86 @@ def patch_identity_provider_attributes(self, identity_provider_id: str, attribut
424430
identity_provider_id, CatalogIdentityProvider.to_api_patch(identity_provider_id, attributes)
425431
)
426432

433+
def create_or_update_export_template(self, export_template: CatalogExportTemplate) -> None:
434+
"""Create a new export template or overwrite an existing export template with the same id.
435+
436+
Args:
437+
export_template (CatalogExportTemplate):
438+
Catalog export template object to be created or updated.
439+
440+
Returns:
441+
None
442+
443+
Raises:
444+
ValueError: Export template cannot be updated.
445+
"""
446+
try:
447+
self.get_export_template(export_template.id)
448+
self._entities_api.update_entity_export_templates(
449+
id=export_template.id,
450+
json_api_export_template_in_document=JsonApiExportTemplateInDocument.from_dict(
451+
{"data": export_template.to_dict()}
452+
),
453+
)
454+
except NotFoundException:
455+
self._entities_api.create_entity_export_templates(
456+
json_api_export_template_post_optional_id_document=JsonApiExportTemplatePostOptionalIdDocument(
457+
data=export_template.to_api()
458+
)
459+
)
460+
461+
def get_export_template(self, export_template_id: str) -> CatalogExportTemplate:
462+
"""Get an individual export template.
463+
464+
Args:
465+
export_template_id (str):
466+
Export template identification string e.g. "demo"
467+
468+
Returns:
469+
CatalogJwk:
470+
Catalog export template object containing the structure of the export template.
471+
"""
472+
export_template_api = self._entities_api.get_entity_export_templates(id=export_template_id).data
473+
return CatalogExportTemplate.from_api(export_template_api)
474+
475+
def delete_export_template(self, export_template_id: str) -> None:
476+
"""Delete an export template.
477+
478+
Args:
479+
export_template_id (str):
480+
Export template identification string e.g. "demo"
481+
482+
Returns:
483+
None
484+
485+
Raises:
486+
ValueError:
487+
Export template does not exist.
488+
"""
489+
try:
490+
self._entities_api.delete_entity_export_templates(export_template_id)
491+
except NotFoundException:
492+
raise ValueError(
493+
f"Can not delete {export_template_id} export template. This export template does not exist."
494+
)
495+
496+
def list_export_templates(self) -> list[CatalogExportTemplate]:
497+
"""Returns a list of all export templates in the current organization.
498+
499+
Returns:
500+
list[CatalogExportTemplate]:
501+
List of export templates in the current organization.
502+
"""
503+
get_export_templates = functools.partial(
504+
self._entities_api.get_all_entities_export_templates,
505+
_check_return_type=False,
506+
)
507+
export_templates = load_all_entities_dict(get_export_templates, camel_case=False)
508+
return [
509+
CatalogExportTemplate.from_dict(export_template, camel_case=False)
510+
for export_template in export_templates["data"]
511+
]
512+
427513
# Layout APIs
428514

429515
def get_declarative_notification_channels(self) -> list[CatalogDeclarativeNotificationChannel]:
@@ -480,3 +566,36 @@ def put_declarative_identity_providers(self, identity_providers: list[CatalogDec
480566
"""
481567
api_idps = [idp.to_api() for idp in identity_providers]
482568
self._layout_api.set_identity_providers(declarative_identity_provider=api_idps)
569+
570+
def get_declarative_export_templates(self) -> list[CatalogDeclarativeExportTemplate]:
571+
"""
572+
Get all declarative export templates in the current organization.
573+
574+
Returns:
575+
list[CatalogDeclarativeExportTemplate]:
576+
List of declarative export templates.
577+
"""
578+
export_templates_api = self._layout_api.get_export_templates_layout()
579+
if hasattr(export_templates_api, "export_templates"):
580+
return [
581+
CatalogDeclarativeExportTemplate.from_api(template)
582+
for template in export_templates_api.export_templates
583+
]
584+
else:
585+
return []
586+
587+
def put_declarative_export_templates(self, export_templates: list[CatalogDeclarativeExportTemplate]) -> None:
588+
"""
589+
Put declarative export templates in the current organization.
590+
591+
Args:
592+
export_templates (list[CatalogDeclarativeExportTemplate]):
593+
List of declarative export templates.
594+
595+
Returns:
596+
None
597+
"""
598+
api_export_templates = [export_template.to_api() for export_template in export_templates]
599+
self._layout_api.set_export_templates(
600+
declarative_export_templates=DeclarativeExportTemplates(export_templates=api_export_templates)
601+
)

0 commit comments

Comments
 (0)