From bbae588244fcac3a032512d5183fb52f764a20cb Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Tue, 3 Nov 2026 14:07:22 +0100 Subject: [PATCH 01/12] chore(gooddata-api-client): regenerate against staging Regenerate the client from the staging specs, which carry the backend's Publisher document permission and layout changes. - CREATE_DOCUMENT joins every workspace permission enum that has CREATE_VISUALIZATION, including the declarative single-workspace and hierarchy permissions. - DeclarativePublisherDocument gains created_at, created_by, modified_at and modified_by. The document template and page template layout types have no author fields. The same download brings unrelated backend changes: a required restrictedCount on ChangeAnalysisResult, a required storages list (ObjectStorageRef) on DatabaseInstance, the MODEL_STATISTICS explain type, relationships on JsonApiPublisherDocumentOut, and the removal of AmplitudeService. No package's source uses the changed or removed models. jira: LX-3447 risk: low Co-Authored-By: Claude Opus 5.5 --- gooddata-api-client/.openapi-generator/FILES | 8 +- gooddata-api-client/README.md | 4 +- gooddata-api-client/docs/ActionsApi.md | 10 +- gooddata-api-client/docs/AnalyticsModelApi.md | 14 +- .../docs/AttributeHeaderAttributeHeader.md | 2 +- .../docs/ChangeAnalysisResult.md | 1 + gooddata-api-client/docs/ComputationApi.md | 4 +- gooddata-api-client/docs/DatabaseInstance.md | 3 +- .../docs/DeclarativePublisherDocument.md | 4 + .../docs/DocumentControllerApi.md | 16 +- .../docs/DocumentTemplateControllerApi.md | 6 +- gooddata-api-client/docs/ElementsResponse.md | 2 +- gooddata-api-client/docs/EntitiesApi.md | 24 +- .../docs/FeatureFlagsContext.md | 3 + ...JsonApiNotificationChannelOutAttributes.md | 2 +- .../docs/JsonApiPublisherDocumentOut.md | 2 +- .../JsonApiPublisherDocumentOutDocument.md | 2 +- .../JsonApiPublisherDocumentOutIncludes.md | 17 + .../docs/JsonApiPublisherDocumentOutList.md | 2 +- ...sonApiPublisherDocumentOutRelationships.md | 17 + .../JsonApiPublisherDocumentOutWithLinks.md | 2 +- ...lisherDocumentPageTemplateOutAttributes.md | 1 + gooddata-api-client/docs/LayoutApi.md | 56 ++- gooddata-api-client/docs/LocalizationApi.md | 6 +- ...mplitudeService.md => ObjectStorageRef.md} | 10 +- .../docs/OrganizationDeclarativeAPIsApi.md | 14 +- .../docs/PageTemplateControllerApi.md | 2 + .../docs/ProvisionDatabaseInstanceRequest.md | 2 +- .../docs/PublisherDocumentObjRef.md | 2 +- .../docs/PublisherDocumentsApi.md | 24 +- gooddata-api-client/docs/TelemetryServices.md | 1 - .../docs/WorkspacesDeclarativeAPIsApi.md | 28 +- .../gooddata_api_client/api/actions_api.py | 9 +- .../api/computation_api.py | 3 +- .../api/document_controller_api.py | 20 + .../gooddata_api_client/api/entities_api.py | 21 + .../api/localization_api.py | 6 +- .../api/page_template_controller_api.py | 1 + .../api/publisher_documents_api.py | 21 + .../attribute_header_attribute_header.py | 4 +- .../model/change_analysis_result.py | 10 +- .../model/database_instance.py | 16 +- .../model/declarative_notification_channel.py | 2 +- .../model/declarative_publisher_document.py | 28 ++ .../model/declarative_setting.py | 1 + ...declarative_single_workspace_permission.py | 1 + ...larative_workspace_hierarchy_permission.py | 1 + .../model/dependent_entities_node.py | 1 + .../model/elements_response.py | 4 +- .../model/entity_identifier.py | 1 + .../model/feature_flags_context.py | 22 +- ..._api_notification_channel_in_attributes.py | 2 +- ...ation_channel_in_attributes_destination.py | 2 +- ...api_notification_channel_out_attributes.py | 3 +- ..._api_organization_setting_in_attributes.py | 1 + .../model/json_api_publisher_document_out.py | 10 +- ...son_api_publisher_document_out_document.py | 10 +- ...son_api_publisher_document_out_includes.py | 368 ++++++++++++++++++ .../json_api_publisher_document_out_list.py | 10 +- ...pi_publisher_document_out_relationships.py | 298 ++++++++++++++ ...n_api_publisher_document_out_with_links.py | 10 +- ...r_document_page_template_out_attributes.py | 7 +- .../json_api_user_setting_in_attributes.py | 1 + .../model/json_api_workspace_out_meta.py | 1 + .../model/notification_channel_destination.py | 2 +- ...itude_service.py => object_storage_ref.py} | 44 +-- .../provision_database_instance_request.py | 4 +- .../model/publisher_document_obj_ref.py | 11 +- .../model/resolved_setting.py | 1 + .../model/telemetry_services.py | 6 - ...agement_workspace_permission_assignment.py | 2 + .../gooddata_api_client/model/webhook.py | 2 +- .../model/webhook_all_of.py | 2 +- .../model/workspace_permission_assignment.py | 2 + .../gooddata_api_client/models/__init__.py | 4 +- schemas/gooddata-afm-client.json | 54 ++- schemas/gooddata-api-client.json | 314 +++++++++++---- schemas/gooddata-automation-client.json | 2 +- schemas/gooddata-metadata-client.json | 258 ++++++++---- 79 files changed, 1569 insertions(+), 325 deletions(-) create mode 100644 gooddata-api-client/docs/JsonApiPublisherDocumentOutIncludes.md create mode 100644 gooddata-api-client/docs/JsonApiPublisherDocumentOutRelationships.md rename gooddata-api-client/docs/{AmplitudeService.md => ObjectStorageRef.md} (53%) create mode 100644 gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_includes.py create mode 100644 gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_relationships.py rename gooddata-api-client/gooddata_api_client/model/{amplitude_service.py => object_storage_ref.py} (85%) diff --git a/gooddata-api-client/.openapi-generator/FILES b/gooddata-api-client/.openapi-generator/FILES index ea05ce376..1cf55578c 100644 --- a/gooddata-api-client/.openapi-generator/FILES +++ b/gooddata-api-client/.openapi-generator/FILES @@ -49,7 +49,6 @@ docs/AlertDescription.md docs/AlertEvaluationRow.md docs/AllTimeDateFilter.md docs/AllTimeDateFilterAllTimeDateFilter.md -docs/AmplitudeService.md docs/AnalyticalDashboardControllerApi.md docs/AnalyticsCatalogCreatedBy.md docs/AnalyticsCatalogTags.md @@ -1077,7 +1076,9 @@ docs/JsonApiPublisherDocumentInDocument.md docs/JsonApiPublisherDocumentOut.md docs/JsonApiPublisherDocumentOutAttributes.md docs/JsonApiPublisherDocumentOutDocument.md +docs/JsonApiPublisherDocumentOutIncludes.md docs/JsonApiPublisherDocumentOutList.md +docs/JsonApiPublisherDocumentOutRelationships.md docs/JsonApiPublisherDocumentOutWithLinks.md docs/JsonApiPublisherDocumentPageTemplateIn.md docs/JsonApiPublisherDocumentPageTemplateInAttributes.md @@ -1432,6 +1433,7 @@ docs/ObjectConditionalFormatting.md docs/ObjectLinks.md docs/ObjectLinksContainer.md docs/ObjectStorageInfo.md +docs/ObjectStorageRef.md docs/ObservabilityApi.md docs/OpenAIProviderConfig.md docs/OpenAiApiKeyAuth.md @@ -1968,7 +1970,6 @@ gooddata_api_client/model/alert_description.py gooddata_api_client/model/alert_evaluation_row.py gooddata_api_client/model/all_time_date_filter.py gooddata_api_client/model/all_time_date_filter_all_time_date_filter.py -gooddata_api_client/model/amplitude_service.py gooddata_api_client/model/analytics_catalog_created_by.py gooddata_api_client/model/analytics_catalog_tags.py gooddata_api_client/model/analytics_catalog_user.py @@ -2925,7 +2926,9 @@ gooddata_api_client/model/json_api_publisher_document_in_document.py gooddata_api_client/model/json_api_publisher_document_out.py gooddata_api_client/model/json_api_publisher_document_out_attributes.py gooddata_api_client/model/json_api_publisher_document_out_document.py +gooddata_api_client/model/json_api_publisher_document_out_includes.py gooddata_api_client/model/json_api_publisher_document_out_list.py +gooddata_api_client/model/json_api_publisher_document_out_relationships.py gooddata_api_client/model/json_api_publisher_document_out_with_links.py gooddata_api_client/model/json_api_publisher_document_page_template_in.py gooddata_api_client/model/json_api_publisher_document_page_template_in_attributes.py @@ -3259,6 +3262,7 @@ gooddata_api_client/model/object_conditional_formatting.py gooddata_api_client/model/object_links.py gooddata_api_client/model/object_links_container.py gooddata_api_client/model/object_storage_info.py +gooddata_api_client/model/object_storage_ref.py gooddata_api_client/model/open_ai_api_key_auth.py gooddata_api_client/model/open_ai_api_key_auth_all_of.py gooddata_api_client/model/open_ai_provider_auth.py diff --git a/gooddata-api-client/README.md b/gooddata-api-client/README.md index a253d9a32..505666e50 100644 --- a/gooddata-api-client/README.md +++ b/gooddata-api-client/README.md @@ -1616,7 +1616,6 @@ Class | Method | HTTP request | Description - [AlertEvaluationRow](docs/AlertEvaluationRow.md) - [AllTimeDateFilter](docs/AllTimeDateFilter.md) - [AllTimeDateFilterAllTimeDateFilter](docs/AllTimeDateFilterAllTimeDateFilter.md) - - [AmplitudeService](docs/AmplitudeService.md) - [AnalyticsCatalogCreatedBy](docs/AnalyticsCatalogCreatedBy.md) - [AnalyticsCatalogTags](docs/AnalyticsCatalogTags.md) - [AnalyticsCatalogUser](docs/AnalyticsCatalogUser.md) @@ -2573,7 +2572,9 @@ Class | Method | HTTP request | Description - [JsonApiPublisherDocumentOut](docs/JsonApiPublisherDocumentOut.md) - [JsonApiPublisherDocumentOutAttributes](docs/JsonApiPublisherDocumentOutAttributes.md) - [JsonApiPublisherDocumentOutDocument](docs/JsonApiPublisherDocumentOutDocument.md) + - [JsonApiPublisherDocumentOutIncludes](docs/JsonApiPublisherDocumentOutIncludes.md) - [JsonApiPublisherDocumentOutList](docs/JsonApiPublisherDocumentOutList.md) + - [JsonApiPublisherDocumentOutRelationships](docs/JsonApiPublisherDocumentOutRelationships.md) - [JsonApiPublisherDocumentOutWithLinks](docs/JsonApiPublisherDocumentOutWithLinks.md) - [JsonApiPublisherDocumentPageTemplateIn](docs/JsonApiPublisherDocumentPageTemplateIn.md) - [JsonApiPublisherDocumentPageTemplateInAttributes](docs/JsonApiPublisherDocumentPageTemplateInAttributes.md) @@ -2907,6 +2908,7 @@ Class | Method | HTTP request | Description - [ObjectLinks](docs/ObjectLinks.md) - [ObjectLinksContainer](docs/ObjectLinksContainer.md) - [ObjectStorageInfo](docs/ObjectStorageInfo.md) + - [ObjectStorageRef](docs/ObjectStorageRef.md) - [OpenAIProviderConfig](docs/OpenAIProviderConfig.md) - [OpenAiApiKeyAuth](docs/OpenAiApiKeyAuth.md) - [OpenAiApiKeyAuthAllOf](docs/OpenAiApiKeyAuthAllOf.md) diff --git a/gooddata-api-client/docs/ActionsApi.md b/gooddata-api-client/docs/ActionsApi.md index 282ea1f19..f09128a59 100644 --- a/gooddata-api-client/docs/ActionsApi.md +++ b/gooddata-api-client/docs/ActionsApi.md @@ -3969,7 +3969,7 @@ with gooddata_api_client.ApiClient() as api_client: timezone="Europe/Prague", ), ) # AfmExecution | - explain_type = "MAQL" # str | Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build (optional) + explain_type = "MAQL" # str | Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `MODEL_STATISTICS` - Physical table statistics of the datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build (optional) # example passing only required values which don't have defaults set try: @@ -3994,7 +3994,7 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **workspace_id** | **str**| Workspace identifier | **afm_execution** | [**AfmExecution**](AfmExecution.md)| | - **explain_type** | **str**| Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build | [optional] + **explain_type** | **str**| Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `MODEL_STATISTICS` - Physical table statistics of the datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build | [optional] ### Return type @@ -8065,7 +8065,7 @@ No authorization required (BETA) Users who set a language themselves. -(BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. Users counted in the usage entry without a language are not listed. +(BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. An empty `value=` means no filter. No value selects the usage entry without a language. ### Example @@ -8143,7 +8143,7 @@ No authorization required (BETA) Workspaces that use a language. -(BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one. +(BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one. Without the value filter, a setting without a language matches too. An empty `value=` means no filter. No value selects the usage entry without a language. ### Example @@ -12579,7 +12579,7 @@ No authorization required (BETA) Workspace members who get a language. -(BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one. +(BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one. An empty `value=` means no filter. No value selects the usage entry without a language. ### Example diff --git a/gooddata-api-client/docs/AnalyticsModelApi.md b/gooddata-api-client/docs/AnalyticsModelApi.md index ff2d4ae27..ac830a795 100644 --- a/gooddata-api-client/docs/AnalyticsModelApi.md +++ b/gooddata-api-client/docs/AnalyticsModelApi.md @@ -237,7 +237,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -393,7 +393,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -533,8 +533,18 @@ with gooddata_api_client.ApiClient() as api_client: gap=PublisherDocumentAreaStyleGap(None), ), ), + created_at="2023-07-20 12:30", + created_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), description="description_example", id="levis-h1-2026", + modified_at="2023-07-20 12:30", + modified_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), period=PublisherDocumentPeriod(), tags=[ "["brand"]", diff --git a/gooddata-api-client/docs/AttributeHeaderAttributeHeader.md b/gooddata-api-client/docs/AttributeHeaderAttributeHeader.md index 1c79ee3b8..62c20e8a1 100644 --- a/gooddata-api-client/docs/AttributeHeaderAttributeHeader.md +++ b/gooddata-api-client/docs/AttributeHeaderAttributeHeader.md @@ -14,7 +14,7 @@ Name | Type | Description | Notes **format** | [**AttributeFormat**](AttributeFormat.md) | | [optional] **geo_area_config** | [**GeoAreaConfig**](GeoAreaConfig.md) | | [optional] **granularity** | **str** | Date granularity of the attribute, only filled for date attributes. | [optional] -**number_format** | **str** | Format to be used to format the attribute values, the same kind of format string as the measure format. Only filled for computed attributes with a format. | [optional] +**number_format** | **str** | Format to be used to format the attribute values, the same kind of format string as the measure format. Only filled for computed attributes with a format and INT or NUMERIC data type. | [optional] **value_type** | **str** | Attribute value type. | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/gooddata-api-client/docs/ChangeAnalysisResult.md b/gooddata-api-client/docs/ChangeAnalysisResult.md index f1463ce08..785719483 100644 --- a/gooddata-api-client/docs/ChangeAnalysisResult.md +++ b/gooddata-api-client/docs/ChangeAnalysisResult.md @@ -6,6 +6,7 @@ Result of a change analysis execution. Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **data** | [**[MetricValueChange]**](MetricValueChange.md) | The change analysis result data containing significant changes. | +**restricted_count** | **int** | Number of attributes and computed attributes left out of the analysis because the user has no access to them. | **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gooddata-api-client/docs/ComputationApi.md b/gooddata-api-client/docs/ComputationApi.md index a951dac04..f7f804454 100644 --- a/gooddata-api-client/docs/ComputationApi.md +++ b/gooddata-api-client/docs/ComputationApi.md @@ -1030,7 +1030,7 @@ with gooddata_api_client.ApiClient() as api_client: timezone="Europe/Prague", ), ) # AfmExecution | - explain_type = "MAQL" # str | Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build (optional) + explain_type = "MAQL" # str | Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `MODEL_STATISTICS` - Physical table statistics of the datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build (optional) # example passing only required values which don't have defaults set try: @@ -1055,7 +1055,7 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **workspace_id** | **str**| Workspace identifier | **afm_execution** | [**AfmExecution**](AfmExecution.md)| | - **explain_type** | **str**| Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build | [optional] + **explain_type** | **str**| Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `MODEL_STATISTICS` - Physical table statistics of the datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build | [optional] ### Return type diff --git a/gooddata-api-client/docs/DatabaseInstance.md b/gooddata-api-client/docs/DatabaseInstance.md index 0d824dd5e..40ae08883 100644 --- a/gooddata-api-client/docs/DatabaseInstance.md +++ b/gooddata-api-client/docs/DatabaseInstance.md @@ -8,7 +8,8 @@ Name | Type | Description | Notes **data_sources** | [**[DataSourceInfo]**](DataSourceInfo.md) | All data source associations for this database instance. | **id** | **str** | Id of the AI Lake Database instance | **name** | **str** | Name of the AI Lake Database instance | -**storage_ids** | **[str]** | Set of ids of the storage instances this database instance should access. | +**storage_ids** | **[str]** | Set of names of the storage instances this database instance accesses. Kept for backward compatibility; use `storages` for the storage ids. | +**storages** | [**[ObjectStorageRef]**](ObjectStorageRef.md) | Storage instances this database instance accesses. | **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gooddata-api-client/docs/DeclarativePublisherDocument.md b/gooddata-api-client/docs/DeclarativePublisherDocument.md index 3f17b53b1..8f4c47734 100644 --- a/gooddata-api-client/docs/DeclarativePublisherDocument.md +++ b/gooddata-api-client/docs/DeclarativePublisherDocument.md @@ -9,7 +9,11 @@ Name | Type | Description | Notes **period** | [**PublisherDocumentPeriod**](PublisherDocumentPeriod.md) | | **title** | **str** | Document title. | **version** | **str** | Version of the content format. | +**created_at** | **str, none_type** | Time of the entity creation. | [optional] +**created_by** | [**DeclarativeUserIdentifier**](DeclarativeUserIdentifier.md) | | [optional] **description** | **str** | Document description. | [optional] +**modified_at** | **str, none_type** | Time of the last entity modification. | [optional] +**modified_by** | [**DeclarativeUserIdentifier**](DeclarativeUserIdentifier.md) | | [optional] **tags** | **[str]** | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/gooddata-api-client/docs/DocumentControllerApi.md b/gooddata-api-client/docs/DocumentControllerApi.md index 50d4aa2d7..434c110d9 100644 --- a/gooddata-api-client/docs/DocumentControllerApi.md +++ b/gooddata-api-client/docs/DocumentControllerApi.md @@ -48,7 +48,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -201,7 +201,7 @@ with gooddata_api_client.ApiClient() as api_client: ), ) # JsonApiPublisherDocumentPostOptionalIdDocument | include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) meta_include = [ "metaInclude=origin,all", @@ -351,7 +351,7 @@ with gooddata_api_client.ApiClient() as api_client: origin = "ALL" # str | (optional) if omitted the server will use the default value of "ALL" filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) page = 0 # int | Zero-based page index (0..N) (optional) if omitted the server will use the default value of 0 size = 20 # int | The size of the page to be returned (optional) if omitted the server will use the default value of 20 @@ -447,7 +447,7 @@ with gooddata_api_client.ApiClient() as api_client: object_id = "objectId_example" # str | filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) x_gdc_validate_relations = False # bool | (optional) if omitted the server will use the default value of False meta_include = [ @@ -543,7 +543,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -697,7 +697,7 @@ with gooddata_api_client.ApiClient() as api_client: ) # JsonApiPublisherDocumentPatchDocument | filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) # example passing only required values which don't have defaults set @@ -788,7 +788,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -942,7 +942,7 @@ with gooddata_api_client.ApiClient() as api_client: ) # JsonApiPublisherDocumentInDocument | filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) # example passing only required values which don't have defaults set diff --git a/gooddata-api-client/docs/DocumentTemplateControllerApi.md b/gooddata-api-client/docs/DocumentTemplateControllerApi.md index 809fbfa5b..77d5b4a80 100644 --- a/gooddata-api-client/docs/DocumentTemplateControllerApi.md +++ b/gooddata-api-client/docs/DocumentTemplateControllerApi.md @@ -48,7 +48,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -542,7 +542,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -786,7 +786,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", diff --git a/gooddata-api-client/docs/ElementsResponse.md b/gooddata-api-client/docs/ElementsResponse.md index 1bd3506e4..9d3607b36 100644 --- a/gooddata-api-client/docs/ElementsResponse.md +++ b/gooddata-api-client/docs/ElementsResponse.md @@ -12,7 +12,7 @@ Name | Type | Description | Notes **data_type** | **str** | Data type of the element values, only filled for computed attributes. | [optional] **format** | [**AttributeFormat**](AttributeFormat.md) | | [optional] **granularity** | **str** | Granularity of requested label in case of date attribute | [optional] -**number_format** | **str** | Format to be used to format the element values, the same kind of format string as the measure format. Only filled for computed attributes with a format. | [optional] +**number_format** | **str** | Format to be used to format the element values, the same kind of format string as the measure format. Only filled for computed attributes with a format and INT or NUMERIC data type. | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gooddata-api-client/docs/EntitiesApi.md b/gooddata-api-client/docs/EntitiesApi.md index ddec52f99..154c98809 100644 --- a/gooddata-api-client/docs/EntitiesApi.md +++ b/gooddata-api-client/docs/EntitiesApi.md @@ -1981,7 +1981,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -2225,7 +2225,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -2378,7 +2378,7 @@ with gooddata_api_client.ApiClient() as api_client: ), ) # JsonApiPublisherDocumentPostOptionalIdDocument | include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) meta_include = [ "metaInclude=origin,all", @@ -10580,7 +10580,7 @@ with gooddata_api_client.ApiClient() as api_client: origin = "ALL" # str | (optional) if omitted the server will use the default value of "ALL" filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) page = 0 # int | Zero-based page index (0..N) (optional) if omitted the server will use the default value of 0 size = 20 # int | The size of the page to be returned (optional) if omitted the server will use the default value of 20 @@ -12304,6 +12304,8 @@ No authorization required Get all Page Templates +Lists the default page templates first, in a fixed order, then the workspace page templates. Paging counts both as one sequence. `filter` and `sort` apply to the workspace page templates only; the default page templates are always listed first and in full, and `isDefault` is not filterable. The default page templates are listed only with `origin=ALL`. + ### Example @@ -15827,7 +15829,7 @@ with gooddata_api_client.ApiClient() as api_client: object_id = "objectId_example" # str | filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) x_gdc_validate_relations = False # bool | (optional) if omitted the server will use the default value of False meta_include = [ @@ -21031,7 +21033,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -21275,7 +21277,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -21429,7 +21431,7 @@ with gooddata_api_client.ApiClient() as api_client: ) # JsonApiPublisherDocumentPatchDocument | filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) # example passing only required values which don't have defaults set @@ -29067,7 +29069,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -29311,7 +29313,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -29465,7 +29467,7 @@ with gooddata_api_client.ApiClient() as api_client: ) # JsonApiPublisherDocumentInDocument | filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) # example passing only required values which don't have defaults set diff --git a/gooddata-api-client/docs/FeatureFlagsContext.md b/gooddata-api-client/docs/FeatureFlagsContext.md index 84f0c8e50..af84ac776 100644 --- a/gooddata-api-client/docs/FeatureFlagsContext.md +++ b/gooddata-api-client/docs/FeatureFlagsContext.md @@ -4,8 +4,11 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**controlled_feature_rollout** | **str** | | +**data_center** | **str** | | **early_access** | **str** | | **early_access_values** | **[str]** | | +**tier** | **str** | | **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gooddata-api-client/docs/JsonApiNotificationChannelOutAttributes.md b/gooddata-api-client/docs/JsonApiNotificationChannelOutAttributes.md index 5646c49cc..8fef32f96 100644 --- a/gooddata-api-client/docs/JsonApiNotificationChannelOutAttributes.md +++ b/gooddata-api-client/docs/JsonApiNotificationChannelOutAttributes.md @@ -9,7 +9,7 @@ Name | Type | Description | Notes **dashboard_link_visibility** | **str** | Dashboard link visibility in notifications. HIDDEN - the link will not be included INTERNAL_ONLY - only internal users will see the link ALL - all users will see the link | [optional] **description** | **str, none_type** | | [optional] **destination** | [**JsonApiNotificationChannelInAttributesDestination**](JsonApiNotificationChannelInAttributesDestination.md) | | [optional] -**destination_type** | **str, none_type** | | [optional] +**destination_type** | **str, none_type** | | [optional] [readonly] **in_platform_notification** | **str** | In-platform notifications configuration. No effect if the destination type is IN_PLATFORM. DISABLED - in-platform notifications are not sent ENABLED - in-platform notifications are sent in addition to the regular notifications | [optional] **name** | **str, none_type** | | [optional] **notification_source** | **str** | Human-readable description of the source of the notification. If specified, this propertywill be included in the notifications to this channel.Allowed placeholders are: {{workspaceId}} {{workspaceName}} {{workspaceDescription}} {{dashboardId}} {{dashboardName}} {{dashboardDescription}} | [optional] diff --git a/gooddata-api-client/docs/JsonApiPublisherDocumentOut.md b/gooddata-api-client/docs/JsonApiPublisherDocumentOut.md index eaa90689d..af2cc9c28 100644 --- a/gooddata-api-client/docs/JsonApiPublisherDocumentOut.md +++ b/gooddata-api-client/docs/JsonApiPublisherDocumentOut.md @@ -9,7 +9,7 @@ Name | Type | Description | Notes **id** | **str** | API identifier of an object | **type** | **str** | Object type | defaults to "document" **meta** | [**JsonApiAggregatedFactOutMeta**](JsonApiAggregatedFactOutMeta.md) | | [optional] -**relationships** | [**JsonApiDashboardPluginOutRelationships**](JsonApiDashboardPluginOutRelationships.md) | | [optional] +**relationships** | [**JsonApiPublisherDocumentOutRelationships**](JsonApiPublisherDocumentOutRelationships.md) | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gooddata-api-client/docs/JsonApiPublisherDocumentOutDocument.md b/gooddata-api-client/docs/JsonApiPublisherDocumentOutDocument.md index ae955c915..86a92205e 100644 --- a/gooddata-api-client/docs/JsonApiPublisherDocumentOutDocument.md +++ b/gooddata-api-client/docs/JsonApiPublisherDocumentOutDocument.md @@ -5,7 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **data** | [**JsonApiPublisherDocumentOut**](JsonApiPublisherDocumentOut.md) | | -**included** | [**[JsonApiUserIdentifierOutWithLinks]**](JsonApiUserIdentifierOutWithLinks.md) | Included resources | [optional] +**included** | [**[JsonApiPublisherDocumentOutIncludes]**](JsonApiPublisherDocumentOutIncludes.md) | Included resources | [optional] **links** | [**ObjectLinks**](ObjectLinks.md) | | [optional] **meta** | [**JsonApiAgentOutDocumentMeta**](JsonApiAgentOutDocumentMeta.md) | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/gooddata-api-client/docs/JsonApiPublisherDocumentOutIncludes.md b/gooddata-api-client/docs/JsonApiPublisherDocumentOutIncludes.md new file mode 100644 index 000000000..67ed7a5e8 --- /dev/null +++ b/gooddata-api-client/docs/JsonApiPublisherDocumentOutIncludes.md @@ -0,0 +1,17 @@ +# JsonApiPublisherDocumentOutIncludes + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**meta** | [**JsonApiAttributeOutMeta**](JsonApiAttributeOutMeta.md) | | [optional] +**relationships** | [**JsonApiComputedAttributeOutRelationships**](JsonApiComputedAttributeOutRelationships.md) | | [optional] +**links** | [**ObjectLinks**](ObjectLinks.md) | | [optional] +**attributes** | [**JsonApiVisualizationObjectOutAttributes**](JsonApiVisualizationObjectOutAttributes.md) | | [optional] +**id** | **str** | API identifier of an object | [optional] +**type** | **str** | Object type | [optional] if omitted the server will use the default value of "visualizationObject" +**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gooddata-api-client/docs/JsonApiPublisherDocumentOutList.md b/gooddata-api-client/docs/JsonApiPublisherDocumentOutList.md index 70d83e56d..3148201b2 100644 --- a/gooddata-api-client/docs/JsonApiPublisherDocumentOutList.md +++ b/gooddata-api-client/docs/JsonApiPublisherDocumentOutList.md @@ -6,7 +6,7 @@ A JSON:API document with a list of resources Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **data** | [**[JsonApiPublisherDocumentOutWithLinks]**](JsonApiPublisherDocumentOutWithLinks.md) | | -**included** | [**[JsonApiUserIdentifierOutWithLinks]**](JsonApiUserIdentifierOutWithLinks.md) | Included resources | [optional] +**included** | [**[JsonApiPublisherDocumentOutIncludes]**](JsonApiPublisherDocumentOutIncludes.md) | Included resources | [optional] **links** | [**ListLinks**](ListLinks.md) | | [optional] **meta** | [**JsonApiAgentOutListMeta**](JsonApiAgentOutListMeta.md) | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/gooddata-api-client/docs/JsonApiPublisherDocumentOutRelationships.md b/gooddata-api-client/docs/JsonApiPublisherDocumentOutRelationships.md new file mode 100644 index 000000000..d5b45d63b --- /dev/null +++ b/gooddata-api-client/docs/JsonApiPublisherDocumentOutRelationships.md @@ -0,0 +1,17 @@ +# JsonApiPublisherDocumentOutRelationships + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**created_by** | [**JsonApiAgentOutRelationshipsCreatedBy**](JsonApiAgentOutRelationshipsCreatedBy.md) | | [optional] +**datasets** | [**JsonApiAnalyticalDashboardOutRelationshipsDatasets**](JsonApiAnalyticalDashboardOutRelationshipsDatasets.md) | | [optional] +**labels** | [**JsonApiAnalyticalDashboardOutRelationshipsLabels**](JsonApiAnalyticalDashboardOutRelationshipsLabels.md) | | [optional] +**metrics** | [**JsonApiAnalyticalDashboardOutRelationshipsMetrics**](JsonApiAnalyticalDashboardOutRelationshipsMetrics.md) | | [optional] +**modified_by** | [**JsonApiAgentOutRelationshipsCreatedBy**](JsonApiAgentOutRelationshipsCreatedBy.md) | | [optional] +**visualization_objects** | [**JsonApiAnalyticalDashboardOutRelationshipsVisualizationObjects**](JsonApiAnalyticalDashboardOutRelationshipsVisualizationObjects.md) | | [optional] +**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gooddata-api-client/docs/JsonApiPublisherDocumentOutWithLinks.md b/gooddata-api-client/docs/JsonApiPublisherDocumentOutWithLinks.md index c26d5af34..1f5e07fe8 100644 --- a/gooddata-api-client/docs/JsonApiPublisherDocumentOutWithLinks.md +++ b/gooddata-api-client/docs/JsonApiPublisherDocumentOutWithLinks.md @@ -8,7 +8,7 @@ Name | Type | Description | Notes **id** | **str** | API identifier of an object | **type** | **str** | Object type | defaults to "document" **meta** | [**JsonApiAggregatedFactOutMeta**](JsonApiAggregatedFactOutMeta.md) | | [optional] -**relationships** | [**JsonApiDashboardPluginOutRelationships**](JsonApiDashboardPluginOutRelationships.md) | | [optional] +**relationships** | [**JsonApiPublisherDocumentOutRelationships**](JsonApiPublisherDocumentOutRelationships.md) | | [optional] **links** | [**ObjectLinks**](ObjectLinks.md) | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/gooddata-api-client/docs/JsonApiPublisherDocumentPageTemplateOutAttributes.md b/gooddata-api-client/docs/JsonApiPublisherDocumentPageTemplateOutAttributes.md index 814f94979..eddb1711e 100644 --- a/gooddata-api-client/docs/JsonApiPublisherDocumentPageTemplateOutAttributes.md +++ b/gooddata-api-client/docs/JsonApiPublisherDocumentPageTemplateOutAttributes.md @@ -5,6 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **content** | [**JsonApiPublisherDocumentPageTemplateInAttributesContent**](JsonApiPublisherDocumentPageTemplateInAttributesContent.md) | | +**is_default** | **bool** | Whether the backend ships this page template as a read-only default. | [readonly] **title** | **str** | | **version** | **str** | Version of the content format. | **are_relations_valid** | **bool** | | [optional] diff --git a/gooddata-api-client/docs/LayoutApi.md b/gooddata-api-client/docs/LayoutApi.md index 335ccd84c..c1a37fe47 100644 --- a/gooddata-api-client/docs/LayoutApi.md +++ b/gooddata-api-client/docs/LayoutApi.md @@ -2420,7 +2420,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -2576,7 +2576,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -2716,8 +2716,18 @@ with gooddata_api_client.ApiClient() as api_client: gap=PublisherDocumentAreaStyleGap(None), ), ), + created_at="2023-07-20 12:30", + created_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), description="description_example", id="levis-h1-2026", + modified_at="2023-07-20 12:30", + modified_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), period=PublisherDocumentPeriod(), tags=[ "["brand"]", @@ -3514,7 +3524,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -3670,7 +3680,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -3810,8 +3820,18 @@ with gooddata_api_client.ApiClient() as api_client: gap=PublisherDocumentAreaStyleGap(None), ), ), + created_at="2023-07-20 12:30", + created_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), description="description_example", id="levis-h1-2026", + modified_at="2023-07-20 12:30", + modified_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), period=PublisherDocumentPeriod(), tags=[ "["brand"]", @@ -6372,7 +6392,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -6528,7 +6548,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -6668,8 +6688,18 @@ with gooddata_api_client.ApiClient() as api_client: gap=PublisherDocumentAreaStyleGap(None), ), ), + created_at="2023-07-20 12:30", + created_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), description="description_example", id="levis-h1-2026", + modified_at="2023-07-20 12:30", + modified_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), period=PublisherDocumentPeriod(), tags=[ "["brand"]", @@ -8409,7 +8439,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -8565,7 +8595,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -8705,8 +8735,18 @@ with gooddata_api_client.ApiClient() as api_client: gap=PublisherDocumentAreaStyleGap(None), ), ), + created_at="2023-07-20 12:30", + created_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), description="description_example", id="levis-h1-2026", + modified_at="2023-07-20 12:30", + modified_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), period=PublisherDocumentPeriod(), tags=[ "["brand"]", diff --git a/gooddata-api-client/docs/LocalizationApi.md b/gooddata-api-client/docs/LocalizationApi.md index fbfd06a4d..5cb66b9da 100644 --- a/gooddata-api-client/docs/LocalizationApi.md +++ b/gooddata-api-client/docs/LocalizationApi.md @@ -144,7 +144,7 @@ No authorization required (BETA) Users who set a language themselves. -(BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. Users counted in the usage entry without a language are not listed. +(BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. An empty `value=` means no filter. No value selects the usage entry without a language. ### Example @@ -222,7 +222,7 @@ No authorization required (BETA) Workspaces that use a language. -(BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one. +(BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one. Without the value filter, a setting without a language matches too. An empty `value=` means no filter. No value selects the usage entry without a language. ### Example @@ -434,7 +434,7 @@ No authorization required (BETA) Workspace members who get a language. -(BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one. +(BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one. An empty `value=` means no filter. No value selects the usage entry without a language. ### Example diff --git a/gooddata-api-client/docs/AmplitudeService.md b/gooddata-api-client/docs/ObjectStorageRef.md similarity index 53% rename from gooddata-api-client/docs/AmplitudeService.md rename to gooddata-api-client/docs/ObjectStorageRef.md index ff4448cd0..5528119df 100644 --- a/gooddata-api-client/docs/AmplitudeService.md +++ b/gooddata-api-client/docs/ObjectStorageRef.md @@ -1,14 +1,12 @@ -# AmplitudeService +# ObjectStorageRef -Amplitude service. +Reference to a registered ObjectStorage. ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**ai_project_api_key** | **str** | API key for AI project - intended for frontend use. | -**endpoint** | **str** | Amplitude endpoint URL. | -**gd_common_api_key** | **str** | API key for GoodData common project - used by backend. | -**reporting_endpoint** | **str** | Optional reporting endpoint for proxying telemetry events. | [optional] +**name** | **str** | Human-readable name of the storage. | +**storage_id** | **str** | Stable identifier of the storage, as returned by the ObjectStorages listing. | **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gooddata-api-client/docs/OrganizationDeclarativeAPIsApi.md b/gooddata-api-client/docs/OrganizationDeclarativeAPIsApi.md index 0f8c08996..5259ee682 100644 --- a/gooddata-api-client/docs/OrganizationDeclarativeAPIsApi.md +++ b/gooddata-api-client/docs/OrganizationDeclarativeAPIsApi.md @@ -1373,7 +1373,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -1529,7 +1529,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -1669,8 +1669,18 @@ with gooddata_api_client.ApiClient() as api_client: gap=PublisherDocumentAreaStyleGap(None), ), ), + created_at="2023-07-20 12:30", + created_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), description="description_example", id="levis-h1-2026", + modified_at="2023-07-20 12:30", + modified_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), period=PublisherDocumentPeriod(), tags=[ "["brand"]", diff --git a/gooddata-api-client/docs/PageTemplateControllerApi.md b/gooddata-api-client/docs/PageTemplateControllerApi.md index 8d04729b5..9dc86644e 100644 --- a/gooddata-api-client/docs/PageTemplateControllerApi.md +++ b/gooddata-api-client/docs/PageTemplateControllerApi.md @@ -221,6 +221,8 @@ No authorization required Get all Page Templates +Lists the default page templates first, in a fixed order, then the workspace page templates. Paging counts both as one sequence. `filter` and `sort` apply to the workspace page templates only; the default page templates are always listed first and in full, and `isDefault` is not filterable. The default page templates are listed only with `origin=ALL`. + ### Example diff --git a/gooddata-api-client/docs/ProvisionDatabaseInstanceRequest.md b/gooddata-api-client/docs/ProvisionDatabaseInstanceRequest.md index daa02c7de..8ba0d8ec1 100644 --- a/gooddata-api-client/docs/ProvisionDatabaseInstanceRequest.md +++ b/gooddata-api-client/docs/ProvisionDatabaseInstanceRequest.md @@ -6,7 +6,7 @@ Request to provision a new AILake Database instance Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | Name of the database instance | -**storage_ids** | **[str]** | Set of ids of the storage instances this database instance should access. | +**storage_ids** | **[str]** | Set of ids of the storage instances this database instance should access. Each entry is a `storageId` from the ObjectStorages listing or, for backward compatibility, a storage name. Must contain exactly one entry. | **data_source_id** | **str** | Identifier for the data source created in metadata-api. Defaults to the database name. | [optional] **data_source_name** | **str** | Display name for the data source created in metadata-api. Defaults to the database name. | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/gooddata-api-client/docs/PublisherDocumentObjRef.md b/gooddata-api-client/docs/PublisherDocumentObjRef.md index 009ccceaf..60e5bf120 100644 --- a/gooddata-api-client/docs/PublisherDocumentObjRef.md +++ b/gooddata-api-client/docs/PublisherDocumentObjRef.md @@ -6,7 +6,7 @@ A flat object reference. Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **identifier** | **str** | | -**type** | **str** | sdk-model object type, such as `displayForm`, `dataSet` or `measure`. | +**type** | **str** | sdk-model object type. | **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/gooddata-api-client/docs/PublisherDocumentsApi.md b/gooddata-api-client/docs/PublisherDocumentsApi.md index 0b6247f94..778a97541 100644 --- a/gooddata-api-client/docs/PublisherDocumentsApi.md +++ b/gooddata-api-client/docs/PublisherDocumentsApi.md @@ -60,7 +60,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -304,7 +304,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -457,7 +457,7 @@ with gooddata_api_client.ApiClient() as api_client: ), ) # JsonApiPublisherDocumentPostOptionalIdDocument | include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) meta_include = [ "metaInclude=origin,all", @@ -972,7 +972,7 @@ with gooddata_api_client.ApiClient() as api_client: origin = "ALL" # str | (optional) if omitted the server will use the default value of "ALL" filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) page = 0 # int | Zero-based page index (0..N) (optional) if omitted the server will use the default value of 0 size = 20 # int | The size of the page to be returned (optional) if omitted the server will use the default value of 20 @@ -1044,6 +1044,8 @@ No authorization required Get all Page Templates +Lists the default page templates first, in a fixed order, then the workspace page templates. Paging counts both as one sequence. `filter` and `sort` apply to the workspace page templates only; the default page templates are always listed first and in full, and `isDefault` is not filterable. The default page templates are listed only with `origin=ALL`. + ### Example @@ -1252,7 +1254,7 @@ with gooddata_api_client.ApiClient() as api_client: object_id = "objectId_example" # str | filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) x_gdc_validate_relations = False # bool | (optional) if omitted the server will use the default value of False meta_include = [ @@ -1436,7 +1438,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -1680,7 +1682,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -1834,7 +1836,7 @@ with gooddata_api_client.ApiClient() as api_client: ) # JsonApiPublisherDocumentPatchDocument | filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) # example passing only required values which don't have defaults set @@ -2064,7 +2066,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -2308,7 +2310,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -2462,7 +2464,7 @@ with gooddata_api_client.ApiClient() as api_client: ) # JsonApiPublisherDocumentInDocument | filter = "version==someString;title==someString;createdBy.id==321;modifiedBy.id==321" # str | Filtering parameter in RSQL. See https://github.com/jirutka/rsql-parser. You can specify any object parameter and parameter of related entity (for example title=='Some Title';description=='desc'). Additionally, if the entity relationship represents a polymorphic entity type, it can be casted to its subtypes (for example relatedEntity::subtype.subtypeProperty=='Value 123'). (optional) include = [ - "createdBy,modifiedBy", + "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", ] # [str] | Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL). __WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together. (optional) # example passing only required values which don't have defaults set diff --git a/gooddata-api-client/docs/TelemetryServices.md b/gooddata-api-client/docs/TelemetryServices.md index 86ec17a79..0f7b1cc6a 100644 --- a/gooddata-api-client/docs/TelemetryServices.md +++ b/gooddata-api-client/docs/TelemetryServices.md @@ -5,7 +5,6 @@ Available telemetry services. ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**amplitude** | [**AmplitudeService**](AmplitudeService.md) | | [optional] **matomo** | [**MatomoService**](MatomoService.md) | | [optional] **open_telemetry** | [**OpenTelemetryService**](OpenTelemetryService.md) | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/gooddata-api-client/docs/WorkspacesDeclarativeAPIsApi.md b/gooddata-api-client/docs/WorkspacesDeclarativeAPIsApi.md index c00b27fe9..b1b79b0fc 100644 --- a/gooddata-api-client/docs/WorkspacesDeclarativeAPIsApi.md +++ b/gooddata-api-client/docs/WorkspacesDeclarativeAPIsApi.md @@ -309,7 +309,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -465,7 +465,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -605,8 +605,18 @@ with gooddata_api_client.ApiClient() as api_client: gap=PublisherDocumentAreaStyleGap(None), ), ), + created_at="2023-07-20 12:30", + created_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), description="description_example", id="levis-h1-2026", + modified_at="2023-07-20 12:30", + modified_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), period=PublisherDocumentPeriod(), tags=[ "["brand"]", @@ -1804,7 +1814,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -1960,7 +1970,7 @@ with gooddata_api_client.ApiClient() as api_client: PublisherDocumentAttributeFilterConfig( display_as_label=PublisherDocumentObjRef( identifier="identifier_example", - type="type_example", + type="insight", ), local_identifier="26bUUGjjNSwg0_bs9ZayIMrKdgNvb6gvxmPb9GcsM61ate1", mode="readonly", @@ -2100,8 +2110,18 @@ with gooddata_api_client.ApiClient() as api_client: gap=PublisherDocumentAreaStyleGap(None), ), ), + created_at="2023-07-20 12:30", + created_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), description="description_example", id="levis-h1-2026", + modified_at="2023-07-20 12:30", + modified_by=DeclarativeUserIdentifier( + id="employee123", + type="user", + ), period=PublisherDocumentPeriod(), tags=[ "["brand"]", diff --git a/gooddata-api-client/gooddata_api_client/api/actions_api.py b/gooddata-api-client/gooddata_api_client/api/actions_api.py index 88cff9c27..567e16f45 100644 --- a/gooddata-api-client/gooddata_api_client/api/actions_api.py +++ b/gooddata-api-client/gooddata_api_client/api/actions_api.py @@ -2807,6 +2807,7 @@ def __init__(self, api_client=None): "MAQL": "MAQL", "GRPC_MODEL": "GRPC_MODEL", + "MODEL_STATISTICS": "MODEL_STATISTICS", "GRPC_MODEL_SVG": "GRPC_MODEL_SVG", "WDF": "WDF", "QT": "QT", @@ -13161,7 +13162,7 @@ def explain_afm( afm_execution (AfmExecution): Keyword Args: - explain_type (str): Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build. [optional] + explain_type (str): Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `MODEL_STATISTICS` - Physical table statistics of the datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build. [optional] _return_http_data_only (bool): response data without head status code and headers. Default is True. _preload_content (bool): if False, the urllib3.HTTPResponse object @@ -17962,7 +17963,7 @@ def organization_localization_usage_users( ): """(BETA) Users who set a language themselves. # noqa: E501 - (BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. Users counted in the usage entry without a language are not listed. # noqa: E501 + (BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. An empty `value=` means no filter. No value selects the usage entry without a language. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True @@ -18046,7 +18047,7 @@ def organization_localization_usage_workspaces( ): """(BETA) Workspaces that use a language. # noqa: E501 - (BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one. # noqa: E501 + (BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one. Without the value filter, a setting without a language matches too. An empty `value=` means no filter. No value selects the usage entry without a language. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True @@ -22771,7 +22772,7 @@ def workspace_localization_usage_users( ): """(BETA) Workspace members who get a language. # noqa: E501 - (BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one. # noqa: E501 + (BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one. An empty `value=` means no filter. No value selects the usage entry without a language. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True diff --git a/gooddata-api-client/gooddata_api_client/api/computation_api.py b/gooddata-api-client/gooddata_api_client/api/computation_api.py index a8d221310..9c1f8c4a2 100644 --- a/gooddata-api-client/gooddata_api_client/api/computation_api.py +++ b/gooddata-api-client/gooddata_api_client/api/computation_api.py @@ -706,6 +706,7 @@ def __init__(self, api_client=None): "MAQL": "MAQL", "GRPC_MODEL": "GRPC_MODEL", + "MODEL_STATISTICS": "MODEL_STATISTICS", "GRPC_MODEL_SVG": "GRPC_MODEL_SVG", "WDF": "WDF", "QT": "QT", @@ -2058,7 +2059,7 @@ def explain_afm( afm_execution (AfmExecution): Keyword Args: - explain_type (str): Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build. [optional] + explain_type (str): Requested explain type. If not specified all types are bundled in a ZIP archive. `MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info `GRPC_MODEL` - Datasets used in execution `MODEL_STATISTICS` - Physical table statistics of the datasets used in execution `GRPC_MODEL_SVG` - Generated SVG image of the datasets `COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query `WDF` - Workspace data filters in execution workspace context `QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL `QT_SVG` - Generated SVG image of the Query Tree `OPT_QT` - Optimized Query Tree `OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree `SQL` - Final SQL to be executed `COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets `SETTINGS` - Settings used to execute explain request `GIT` - Git properties of current build. [optional] _return_http_data_only (bool): response data without head status code and headers. Default is True. _preload_content (bool): if False, the urllib3.HTTPResponse object diff --git a/gooddata-api-client/gooddata_api_client/api/document_controller_api.py b/gooddata-api-client/gooddata_api_client/api/document_controller_api.py index 02381030a..746f899ab 100644 --- a/gooddata-api-client/gooddata_api_client/api/document_controller_api.py +++ b/gooddata-api-client/gooddata_api_client/api/document_controller_api.py @@ -80,6 +80,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -233,6 +237,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -344,6 +352,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -436,6 +448,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -519,6 +535,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" diff --git a/gooddata-api-client/gooddata_api_client/api/entities_api.py b/gooddata-api-client/gooddata_api_client/api/entities_api.py index 8b35abb90..8bdf6d7db 100644 --- a/gooddata-api-client/gooddata_api_client/api/entities_api.py +++ b/gooddata-api-client/gooddata_api_client/api/entities_api.py @@ -1408,6 +1408,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -8559,6 +8563,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -14396,6 +14404,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -19041,6 +19053,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -24685,6 +24701,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -38993,6 +39013,7 @@ def get_all_entities_page_templates( ): """Get all Page Templates # noqa: E501 + Lists the default page templates first, in a fixed order, then the workspace page templates. Paging counts both as one sequence. `filter` and `sort` apply to the workspace page templates only; the default page templates are always listed first and in full, and `isDefault` is not filterable. The default page templates are listed only with `origin=ALL`. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True diff --git a/gooddata-api-client/gooddata_api_client/api/localization_api.py b/gooddata-api-client/gooddata_api_client/api/localization_api.py index b591ebd91..1e28978a3 100644 --- a/gooddata-api-client/gooddata_api_client/api/localization_api.py +++ b/gooddata-api-client/gooddata_api_client/api/localization_api.py @@ -659,7 +659,7 @@ def organization_localization_usage_users( ): """(BETA) Users who set a language themselves. # noqa: E501 - (BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. Users counted in the usage entry without a language are not listed. # noqa: E501 + (BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. An empty `value=` means no filter. No value selects the usage entry without a language. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True @@ -743,7 +743,7 @@ def organization_localization_usage_workspaces( ): """(BETA) Workspaces that use a language. # noqa: E501 - (BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one. # noqa: E501 + (BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one. Without the value filter, a setting without a language matches too. An empty `value=` means no filter. No value selects the usage entry without a language. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True @@ -994,7 +994,7 @@ def workspace_localization_usage_users( ): """(BETA) Workspace members who get a language. # noqa: E501 - (BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one. # noqa: E501 + (BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one. An empty `value=` means no filter. No value selects the usage entry without a language. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True diff --git a/gooddata-api-client/gooddata_api_client/api/page_template_controller_api.py b/gooddata-api-client/gooddata_api_client/api/page_template_controller_api.py index 77225217d..26466e7b7 100644 --- a/gooddata-api-client/gooddata_api_client/api/page_template_controller_api.py +++ b/gooddata-api-client/gooddata_api_client/api/page_template_controller_api.py @@ -747,6 +747,7 @@ def get_all_entities_page_templates( ): """Get all Page Templates # noqa: E501 + Lists the default page templates first, in a fixed order, then the workspace page templates. Paging counts both as one sequence. `filter` and `sort` apply to the workspace page templates only; the default page templates are always listed first and in full, and `isDefault` is not filterable. The default page templates are listed only with `origin=ALL`. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True diff --git a/gooddata-api-client/gooddata_api_client/api/publisher_documents_api.py b/gooddata-api-client/gooddata_api_client/api/publisher_documents_api.py index 13bb9c90c..b46e03b72 100644 --- a/gooddata-api-client/gooddata_api_client/api/publisher_documents_api.py +++ b/gooddata-api-client/gooddata_api_client/api/publisher_documents_api.py @@ -179,6 +179,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -647,6 +651,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -975,6 +983,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -1247,6 +1259,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -1496,6 +1512,10 @@ def __init__(self, api_client=None): ('include',): { "USERIDENTIFIERS": "userIdentifiers", + "VISUALIZATIONOBJECTS": "visualizationObjects", + "LABELS": "labels", + "DATASETS": "datasets", + "METRICS": "metrics", "CREATEDBY": "createdBy", "MODIFIEDBY": "modifiedBy", "ALL": "ALL" @@ -2335,6 +2355,7 @@ def get_all_entities_page_templates( ): """Get all Page Templates # noqa: E501 + Lists the default page templates first, in a fixed order, then the workspace page templates. Paging counts both as one sequence. `filter` and `sort` apply to the workspace page templates only; the default page templates are always listed first and in full, and `isDefault` is not filterable. The default page templates are listed only with `origin=ALL`. # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True diff --git a/gooddata-api-client/gooddata_api_client/model/attribute_header_attribute_header.py b/gooddata-api-client/gooddata_api_client/model/attribute_header_attribute_header.py index 6de74fda0..513ee61ee 100644 --- a/gooddata-api-client/gooddata_api_client/model/attribute_header_attribute_header.py +++ b/gooddata-api-client/gooddata_api_client/model/attribute_header_attribute_header.py @@ -247,7 +247,7 @@ def _from_openapi_data(cls, attribute, attribute_name, label, label_name, local_ format (AttributeFormat): [optional] # noqa: E501 geo_area_config (GeoAreaConfig): [optional] # noqa: E501 granularity (str): Date granularity of the attribute, only filled for date attributes.. [optional] # noqa: E501 - number_format (str): Format to be used to format the attribute values, the same kind of format string as the measure format. Only filled for computed attributes with a format.. [optional] # noqa: E501 + number_format (str): Format to be used to format the attribute values, the same kind of format string as the measure format. Only filled for computed attributes with a format and INT or NUMERIC data type.. [optional] # noqa: E501 value_type (str): Attribute value type.. [optional] # noqa: E501 """ @@ -352,7 +352,7 @@ def __init__(self, attribute, attribute_name, label, label_name, local_identifie format (AttributeFormat): [optional] # noqa: E501 geo_area_config (GeoAreaConfig): [optional] # noqa: E501 granularity (str): Date granularity of the attribute, only filled for date attributes.. [optional] # noqa: E501 - number_format (str): Format to be used to format the attribute values, the same kind of format string as the measure format. Only filled for computed attributes with a format.. [optional] # noqa: E501 + number_format (str): Format to be used to format the attribute values, the same kind of format string as the measure format. Only filled for computed attributes with a format and INT or NUMERIC data type.. [optional] # noqa: E501 value_type (str): Attribute value type.. [optional] # noqa: E501 """ diff --git a/gooddata-api-client/gooddata_api_client/model/change_analysis_result.py b/gooddata-api-client/gooddata_api_client/model/change_analysis_result.py index 41c1caf4a..6189740d4 100644 --- a/gooddata-api-client/gooddata_api_client/model/change_analysis_result.py +++ b/gooddata-api-client/gooddata_api_client/model/change_analysis_result.py @@ -89,6 +89,7 @@ def openapi_types(): lazy_import() return { 'data': ([MetricValueChange],), # noqa: E501 + 'restricted_count': (int,), # noqa: E501 } @cached_property @@ -98,6 +99,7 @@ def discriminator(): attribute_map = { 'data': 'data', # noqa: E501 + 'restricted_count': 'restrictedCount', # noqa: E501 } read_only_vars = { @@ -107,11 +109,12 @@ def discriminator(): @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, data, *args, **kwargs): # noqa: E501 + def _from_openapi_data(cls, data, restricted_count, *args, **kwargs): # noqa: E501 """ChangeAnalysisResult - a model defined in OpenAPI Args: data ([MetricValueChange]): The change analysis result data containing significant changes. + restricted_count (int): Number of attributes and computed attributes left out of the analysis because the user has no access to them. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -176,6 +179,7 @@ def _from_openapi_data(cls, data, *args, **kwargs): # noqa: E501 self._visited_composed_classes = _visited_composed_classes + (self.__class__,) self.data = data + self.restricted_count = restricted_count for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ @@ -196,11 +200,12 @@ def _from_openapi_data(cls, data, *args, **kwargs): # noqa: E501 ]) @convert_js_args_to_python_args - def __init__(self, data, *args, **kwargs): # noqa: E501 + def __init__(self, data, restricted_count, *args, **kwargs): # noqa: E501 """ChangeAnalysisResult - a model defined in OpenAPI Args: data ([MetricValueChange]): The change analysis result data containing significant changes. + restricted_count (int): Number of attributes and computed attributes left out of the analysis because the user has no access to them. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -263,6 +268,7 @@ def __init__(self, data, *args, **kwargs): # noqa: E501 self._visited_composed_classes = _visited_composed_classes + (self.__class__,) self.data = data + self.restricted_count = restricted_count for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ diff --git a/gooddata-api-client/gooddata_api_client/model/database_instance.py b/gooddata-api-client/gooddata_api_client/model/database_instance.py index 7c00cd129..22b3b49b5 100644 --- a/gooddata-api-client/gooddata_api_client/model/database_instance.py +++ b/gooddata-api-client/gooddata_api_client/model/database_instance.py @@ -32,7 +32,9 @@ def lazy_import(): from gooddata_api_client.model.data_source_info import DataSourceInfo + from gooddata_api_client.model.object_storage_ref import ObjectStorageRef globals()['DataSourceInfo'] = DataSourceInfo + globals()['ObjectStorageRef'] = ObjectStorageRef class DatabaseInstance(ModelNormal): @@ -94,6 +96,7 @@ def openapi_types(): 'id': (str,), # noqa: E501 'name': (str,), # noqa: E501 'storage_ids': ([str],), # noqa: E501 + 'storages': ([ObjectStorageRef],), # noqa: E501 } @cached_property @@ -106,6 +109,7 @@ def discriminator(): 'id': 'id', # noqa: E501 'name': 'name', # noqa: E501 'storage_ids': 'storageIds', # noqa: E501 + 'storages': 'storages', # noqa: E501 } read_only_vars = { @@ -115,14 +119,15 @@ def discriminator(): @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, data_sources, id, name, storage_ids, *args, **kwargs): # noqa: E501 + def _from_openapi_data(cls, data_sources, id, name, storage_ids, storages, *args, **kwargs): # noqa: E501 """DatabaseInstance - a model defined in OpenAPI Args: data_sources ([DataSourceInfo]): All data source associations for this database instance. id (str): Id of the AI Lake Database instance name (str): Name of the AI Lake Database instance - storage_ids ([str]): Set of ids of the storage instances this database instance should access. + storage_ids ([str]): Set of names of the storage instances this database instance accesses. Kept for backward compatibility; use `storages` for the storage ids. + storages ([ObjectStorageRef]): Storage instances this database instance accesses. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -190,6 +195,7 @@ def _from_openapi_data(cls, data_sources, id, name, storage_ids, *args, **kwargs self.id = id self.name = name self.storage_ids = storage_ids + self.storages = storages for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ @@ -210,14 +216,15 @@ def _from_openapi_data(cls, data_sources, id, name, storage_ids, *args, **kwargs ]) @convert_js_args_to_python_args - def __init__(self, data_sources, id, name, storage_ids, *args, **kwargs): # noqa: E501 + def __init__(self, data_sources, id, name, storage_ids, storages, *args, **kwargs): # noqa: E501 """DatabaseInstance - a model defined in OpenAPI Args: data_sources ([DataSourceInfo]): All data source associations for this database instance. id (str): Id of the AI Lake Database instance name (str): Name of the AI Lake Database instance - storage_ids ([str]): Set of ids of the storage instances this database instance should access. + storage_ids ([str]): Set of names of the storage instances this database instance accesses. Kept for backward compatibility; use `storages` for the storage ids. + storages ([ObjectStorageRef]): Storage instances this database instance accesses. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -283,6 +290,7 @@ def __init__(self, data_sources, id, name, storage_ids, *args, **kwargs): # noq self.id = id self.name = name self.storage_ids = storage_ids + self.storages = storages for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ diff --git a/gooddata-api-client/gooddata_api_client/model/declarative_notification_channel.py b/gooddata-api-client/gooddata_api_client/model/declarative_notification_channel.py index 8fc3004bc..f0cd0bd41 100644 --- a/gooddata-api-client/gooddata_api_client/model/declarative_notification_channel.py +++ b/gooddata-api-client/gooddata_api_client/model/declarative_notification_channel.py @@ -90,7 +90,7 @@ class DeclarativeNotificationChannel(ModelNormal): }, }, ('custom_dashboard_url',): { - 'max_length': 255, + 'max_length': 2048, }, ('description',): { 'max_length': 10000, diff --git a/gooddata-api-client/gooddata_api_client/model/declarative_publisher_document.py b/gooddata-api-client/gooddata_api_client/model/declarative_publisher_document.py index e46150be6..298599072 100644 --- a/gooddata-api-client/gooddata_api_client/model/declarative_publisher_document.py +++ b/gooddata-api-client/gooddata_api_client/model/declarative_publisher_document.py @@ -31,8 +31,10 @@ def lazy_import(): + from gooddata_api_client.model.declarative_user_identifier import DeclarativeUserIdentifier from gooddata_api_client.model.publisher_document_content import PublisherDocumentContent from gooddata_api_client.model.publisher_document_period import PublisherDocumentPeriod + globals()['DeclarativeUserIdentifier'] = DeclarativeUserIdentifier globals()['PublisherDocumentContent'] = PublisherDocumentContent globals()['PublisherDocumentPeriod'] = PublisherDocumentPeriod @@ -73,9 +75,19 @@ class DeclarativePublisherDocument(ModelNormal): ('title',): { 'max_length': 255, }, + ('created_at',): { + 'regex': { + 'pattern': r'[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}', # noqa: E501 + }, + }, ('description',): { 'max_length': 10000, }, + ('modified_at',): { + 'regex': { + 'pattern': r'[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}', # noqa: E501 + }, + }, ('tags',): { }, } @@ -108,7 +120,11 @@ def openapi_types(): 'period': (PublisherDocumentPeriod,), # noqa: E501 'title': (str,), # noqa: E501 'version': (str,), # noqa: E501 + 'created_at': (str, none_type,), # noqa: E501 + 'created_by': (DeclarativeUserIdentifier,), # noqa: E501 'description': (str,), # noqa: E501 + 'modified_at': (str, none_type,), # noqa: E501 + 'modified_by': (DeclarativeUserIdentifier,), # noqa: E501 'tags': ([str],), # noqa: E501 } @@ -123,7 +139,11 @@ def discriminator(): 'period': 'period', # noqa: E501 'title': 'title', # noqa: E501 'version': 'version', # noqa: E501 + 'created_at': 'createdAt', # noqa: E501 + 'created_by': 'createdBy', # noqa: E501 'description': 'description', # noqa: E501 + 'modified_at': 'modifiedAt', # noqa: E501 + 'modified_by': 'modifiedBy', # noqa: E501 'tags': 'tags', # noqa: E501 } @@ -175,7 +195,11 @@ def _from_openapi_data(cls, content, id, period, title, version, *args, **kwargs Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) + created_at (str, none_type): Time of the entity creation.. [optional] # noqa: E501 + created_by (DeclarativeUserIdentifier): [optional] # noqa: E501 description (str): Document description.. [optional] # noqa: E501 + modified_at (str, none_type): Time of the last entity modification.. [optional] # noqa: E501 + modified_by (DeclarativeUserIdentifier): [optional] # noqa: E501 tags ([str]): [optional] # noqa: E501 """ @@ -274,7 +298,11 @@ def __init__(self, content, id, period, title, version, *args, **kwargs): # noq Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) + created_at (str, none_type): Time of the entity creation.. [optional] # noqa: E501 + created_by (DeclarativeUserIdentifier): [optional] # noqa: E501 description (str): Document description.. [optional] # noqa: E501 + modified_at (str, none_type): Time of the last entity modification.. [optional] # noqa: E501 + modified_by (DeclarativeUserIdentifier): [optional] # noqa: E501 tags ([str]): [optional] # noqa: E501 """ diff --git a/gooddata-api-client/gooddata_api_client/model/declarative_setting.py b/gooddata-api-client/gooddata_api_client/model/declarative_setting.py index f9bf69d84..ff7f45c0d 100644 --- a/gooddata-api-client/gooddata_api_client/model/declarative_setting.py +++ b/gooddata-api-client/gooddata_api_client/model/declarative_setting.py @@ -121,6 +121,7 @@ class DeclarativeSetting(ModelNormal): 'DEFAULT_VISUALIZATION_VISIBILITY': "DEFAULT_VISUALIZATION_VISIBILITY", 'DEFAULT_METRIC_VISIBILITY': "DEFAULT_METRIC_VISIBILITY", 'GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE': "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + 'QUERY_ENGINE': "QUERY_ENGINE", }, } diff --git a/gooddata-api-client/gooddata_api_client/model/declarative_single_workspace_permission.py b/gooddata-api-client/gooddata_api_client/model/declarative_single_workspace_permission.py index 7984b3242..32c9175d9 100644 --- a/gooddata-api-client/gooddata_api_client/model/declarative_single_workspace_permission.py +++ b/gooddata-api-client/gooddata_api_client/model/declarative_single_workspace_permission.py @@ -75,6 +75,7 @@ class DeclarativeSingleWorkspacePermission(ModelNormal): 'MANAGE_VISUALIZATIONS': "MANAGE_VISUALIZATIONS", 'CREATE_VISUALIZATION': "CREATE_VISUALIZATION", 'CREATE_COMPUTED_ATTRIBUTE': "CREATE_COMPUTED_ATTRIBUTE", + 'CREATE_DOCUMENT': "CREATE_DOCUMENT", 'VIEW': "VIEW", }, } diff --git a/gooddata-api-client/gooddata_api_client/model/declarative_workspace_hierarchy_permission.py b/gooddata-api-client/gooddata_api_client/model/declarative_workspace_hierarchy_permission.py index 4b53f43dc..b6206e00a 100644 --- a/gooddata-api-client/gooddata_api_client/model/declarative_workspace_hierarchy_permission.py +++ b/gooddata-api-client/gooddata_api_client/model/declarative_workspace_hierarchy_permission.py @@ -75,6 +75,7 @@ class DeclarativeWorkspaceHierarchyPermission(ModelNormal): 'MANAGE_VISUALIZATIONS': "MANAGE_VISUALIZATIONS", 'CREATE_VISUALIZATION': "CREATE_VISUALIZATION", 'CREATE_COMPUTED_ATTRIBUTE': "CREATE_COMPUTED_ATTRIBUTE", + 'CREATE_DOCUMENT': "CREATE_DOCUMENT", 'VIEW': "VIEW", }, } diff --git a/gooddata-api-client/gooddata_api_client/model/dependent_entities_node.py b/gooddata-api-client/gooddata_api_client/model/dependent_entities_node.py index ebaa0a0a5..613eb1ee7 100644 --- a/gooddata-api-client/gooddata_api_client/model/dependent_entities_node.py +++ b/gooddata-api-client/gooddata_api_client/model/dependent_entities_node.py @@ -74,6 +74,7 @@ class DependentEntitiesNode(ModelNormal): 'VISUALIZATIONOBJECT': "visualizationObject", 'FILTERCONTEXT': "filterContext", 'FILTERVIEW': "filterView", + 'DOCUMENT': "document", }, } diff --git a/gooddata-api-client/gooddata_api_client/model/elements_response.py b/gooddata-api-client/gooddata_api_client/model/elements_response.py index da3d16fcf..88796ef8e 100644 --- a/gooddata-api-client/gooddata_api_client/model/elements_response.py +++ b/gooddata-api-client/gooddata_api_client/model/elements_response.py @@ -222,7 +222,7 @@ def _from_openapi_data(cls, elements, paging, primary_label, *args, **kwargs): data_type (str): Data type of the element values, only filled for computed attributes.. [optional] # noqa: E501 format (AttributeFormat): [optional] # noqa: E501 granularity (str): Granularity of requested label in case of date attribute. [optional] # noqa: E501 - number_format (str): Format to be used to format the element values, the same kind of format string as the measure format. Only filled for computed attributes with a format.. [optional] # noqa: E501 + number_format (str): Format to be used to format the element values, the same kind of format string as the measure format. Only filled for computed attributes with a format and INT or NUMERIC data type.. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -320,7 +320,7 @@ def __init__(self, elements, paging, primary_label, *args, **kwargs): # noqa: E data_type (str): Data type of the element values, only filled for computed attributes.. [optional] # noqa: E501 format (AttributeFormat): [optional] # noqa: E501 granularity (str): Granularity of requested label in case of date attribute. [optional] # noqa: E501 - number_format (str): Format to be used to format the element values, the same kind of format string as the measure format. Only filled for computed attributes with a format.. [optional] # noqa: E501 + number_format (str): Format to be used to format the element values, the same kind of format string as the measure format. Only filled for computed attributes with a format and INT or NUMERIC data type.. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) diff --git a/gooddata-api-client/gooddata_api_client/model/entity_identifier.py b/gooddata-api-client/gooddata_api_client/model/entity_identifier.py index ddbe536e8..d31053663 100644 --- a/gooddata-api-client/gooddata_api_client/model/entity_identifier.py +++ b/gooddata-api-client/gooddata_api_client/model/entity_identifier.py @@ -74,6 +74,7 @@ class EntityIdentifier(ModelNormal): 'VISUALIZATIONOBJECT': "visualizationObject", 'FILTERCONTEXT': "filterContext", 'FILTERVIEW': "filterView", + 'DOCUMENT': "document", }, } diff --git a/gooddata-api-client/gooddata_api_client/model/feature_flags_context.py b/gooddata-api-client/gooddata_api_client/model/feature_flags_context.py index e97c75dd8..b860518c5 100644 --- a/gooddata-api-client/gooddata_api_client/model/feature_flags_context.py +++ b/gooddata-api-client/gooddata_api_client/model/feature_flags_context.py @@ -84,8 +84,11 @@ def openapi_types(): and the value is attribute type. """ return { + 'controlled_feature_rollout': (str,), # noqa: E501 + 'data_center': (str,), # noqa: E501 'early_access': (str,), # noqa: E501 'early_access_values': ([str],), # noqa: E501 + 'tier': (str,), # noqa: E501 } @cached_property @@ -94,8 +97,11 @@ def discriminator(): attribute_map = { + 'controlled_feature_rollout': 'controlledFeatureRollout', # noqa: E501 + 'data_center': 'dataCenter', # noqa: E501 'early_access': 'earlyAccess', # noqa: E501 'early_access_values': 'earlyAccessValues', # noqa: E501 + 'tier': 'tier', # noqa: E501 } read_only_vars = { @@ -105,12 +111,15 @@ def discriminator(): @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, early_access, early_access_values, *args, **kwargs): # noqa: E501 + def _from_openapi_data(cls, controlled_feature_rollout, data_center, early_access, early_access_values, tier, *args, **kwargs): # noqa: E501 """FeatureFlagsContext - a model defined in OpenAPI Args: + controlled_feature_rollout (str): + data_center (str): early_access (str): early_access_values ([str]): + tier (str): Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -174,8 +183,11 @@ def _from_openapi_data(cls, early_access, early_access_values, *args, **kwargs): self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + self.controlled_feature_rollout = controlled_feature_rollout + self.data_center = data_center self.early_access = early_access self.early_access_values = early_access_values + self.tier = tier for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ @@ -196,12 +208,15 @@ def _from_openapi_data(cls, early_access, early_access_values, *args, **kwargs): ]) @convert_js_args_to_python_args - def __init__(self, early_access, early_access_values, *args, **kwargs): # noqa: E501 + def __init__(self, controlled_feature_rollout, data_center, early_access, early_access_values, tier, *args, **kwargs): # noqa: E501 """FeatureFlagsContext - a model defined in OpenAPI Args: + controlled_feature_rollout (str): + data_center (str): early_access (str): early_access_values ([str]): + tier (str): Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -263,8 +278,11 @@ def __init__(self, early_access, early_access_values, *args, **kwargs): # noqa: self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + self.controlled_feature_rollout = controlled_feature_rollout + self.data_center = data_center self.early_access = early_access self.early_access_values = early_access_values + self.tier = tier for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_in_attributes.py b/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_in_attributes.py index 7717d6ba1..981cb2991 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_in_attributes.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_in_attributes.py @@ -78,7 +78,7 @@ class JsonApiNotificationChannelInAttributes(ModelNormal): validations = { ('custom_dashboard_url',): { - 'max_length': 255, + 'max_length': 2048, }, ('description',): { 'max_length': 10000, diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_in_attributes_destination.py b/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_in_attributes_destination.py index 7bc9e12b4..803520dcb 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_in_attributes_destination.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_in_attributes_destination.py @@ -89,7 +89,7 @@ class JsonApiNotificationChannelInAttributesDestination(ModelComposed): 'max_length': 10000, }, ('url',): { - 'max_length': 255, + 'max_length': 2048, 'regex': { 'pattern': r'https?\:\/\/.*', # noqa: E501 }, diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_out_attributes.py b/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_out_attributes.py index 3454871ad..a626f5aba 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_out_attributes.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_notification_channel_out_attributes.py @@ -85,7 +85,7 @@ class JsonApiNotificationChannelOutAttributes(ModelNormal): validations = { ('custom_dashboard_url',): { - 'max_length': 255, + 'max_length': 2048, }, ('description',): { 'max_length': 10000, @@ -150,6 +150,7 @@ def discriminator(): } read_only_vars = { + 'destination_type', # noqa: E501 } _composed_schemas = {} diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_organization_setting_in_attributes.py b/gooddata-api-client/gooddata_api_client/model/json_api_organization_setting_in_attributes.py index a5bb095f2..a02aa031f 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_organization_setting_in_attributes.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_organization_setting_in_attributes.py @@ -117,6 +117,7 @@ class JsonApiOrganizationSettingInAttributes(ModelNormal): 'DEFAULT_VISUALIZATION_VISIBILITY': "DEFAULT_VISUALIZATION_VISIBILITY", 'DEFAULT_METRIC_VISIBILITY': "DEFAULT_METRIC_VISIBILITY", 'GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE': "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + 'QUERY_ENGINE': "QUERY_ENGINE", }, } diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out.py b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out.py index a3bd9b683..6417ad397 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out.py @@ -32,11 +32,11 @@ def lazy_import(): from gooddata_api_client.model.json_api_aggregated_fact_out_meta import JsonApiAggregatedFactOutMeta - from gooddata_api_client.model.json_api_dashboard_plugin_out_relationships import JsonApiDashboardPluginOutRelationships from gooddata_api_client.model.json_api_publisher_document_out_attributes import JsonApiPublisherDocumentOutAttributes + from gooddata_api_client.model.json_api_publisher_document_out_relationships import JsonApiPublisherDocumentOutRelationships globals()['JsonApiAggregatedFactOutMeta'] = JsonApiAggregatedFactOutMeta - globals()['JsonApiDashboardPluginOutRelationships'] = JsonApiDashboardPluginOutRelationships globals()['JsonApiPublisherDocumentOutAttributes'] = JsonApiPublisherDocumentOutAttributes + globals()['JsonApiPublisherDocumentOutRelationships'] = JsonApiPublisherDocumentOutRelationships class JsonApiPublisherDocumentOut(ModelNormal): @@ -104,7 +104,7 @@ def openapi_types(): 'id': (str,), # noqa: E501 'type': (str,), # noqa: E501 'meta': (JsonApiAggregatedFactOutMeta,), # noqa: E501 - 'relationships': (JsonApiDashboardPluginOutRelationships,), # noqa: E501 + 'relationships': (JsonApiPublisherDocumentOutRelationships,), # noqa: E501 } @cached_property @@ -167,7 +167,7 @@ def _from_openapi_data(cls, attributes, id, *args, **kwargs): # noqa: E501 through its discriminator because we passed in _visited_composed_classes = (Animal,) meta (JsonApiAggregatedFactOutMeta): [optional] # noqa: E501 - relationships (JsonApiDashboardPluginOutRelationships): [optional] # noqa: E501 + relationships (JsonApiPublisherDocumentOutRelationships): [optional] # noqa: E501 """ type = kwargs.get('type', "document") @@ -263,7 +263,7 @@ def __init__(self, attributes, id, *args, **kwargs): # noqa: E501 through its discriminator because we passed in _visited_composed_classes = (Animal,) meta (JsonApiAggregatedFactOutMeta): [optional] # noqa: E501 - relationships (JsonApiDashboardPluginOutRelationships): [optional] # noqa: E501 + relationships (JsonApiPublisherDocumentOutRelationships): [optional] # noqa: E501 """ type = kwargs.get('type', "document") diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_document.py b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_document.py index 206c79bb5..f08b98793 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_document.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_document.py @@ -33,11 +33,11 @@ def lazy_import(): from gooddata_api_client.model.json_api_agent_out_document_meta import JsonApiAgentOutDocumentMeta from gooddata_api_client.model.json_api_publisher_document_out import JsonApiPublisherDocumentOut - from gooddata_api_client.model.json_api_user_identifier_out_with_links import JsonApiUserIdentifierOutWithLinks + from gooddata_api_client.model.json_api_publisher_document_out_includes import JsonApiPublisherDocumentOutIncludes from gooddata_api_client.model.object_links import ObjectLinks globals()['JsonApiAgentOutDocumentMeta'] = JsonApiAgentOutDocumentMeta globals()['JsonApiPublisherDocumentOut'] = JsonApiPublisherDocumentOut - globals()['JsonApiUserIdentifierOutWithLinks'] = JsonApiUserIdentifierOutWithLinks + globals()['JsonApiPublisherDocumentOutIncludes'] = JsonApiPublisherDocumentOutIncludes globals()['ObjectLinks'] = ObjectLinks @@ -97,7 +97,7 @@ def openapi_types(): lazy_import() return { 'data': (JsonApiPublisherDocumentOut,), # noqa: E501 - 'included': ([JsonApiUserIdentifierOutWithLinks],), # noqa: E501 + 'included': ([JsonApiPublisherDocumentOutIncludes],), # noqa: E501 'links': (ObjectLinks,), # noqa: E501 'meta': (JsonApiAgentOutDocumentMeta,), # noqa: E501 } @@ -158,7 +158,7 @@ def _from_openapi_data(cls, data, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - included ([JsonApiUserIdentifierOutWithLinks]): Included resources. [optional] # noqa: E501 + included ([JsonApiPublisherDocumentOutIncludes]): Included resources. [optional] # noqa: E501 links (ObjectLinks): [optional] # noqa: E501 meta (JsonApiAgentOutDocumentMeta): [optional] # noqa: E501 """ @@ -250,7 +250,7 @@ def __init__(self, data, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - included ([JsonApiUserIdentifierOutWithLinks]): Included resources. [optional] # noqa: E501 + included ([JsonApiPublisherDocumentOutIncludes]): Included resources. [optional] # noqa: E501 links (ObjectLinks): [optional] # noqa: E501 meta (JsonApiAgentOutDocumentMeta): [optional] # noqa: E501 """ diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_includes.py b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_includes.py new file mode 100644 index 000000000..6cece7782 --- /dev/null +++ b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_includes.py @@ -0,0 +1,368 @@ +""" + OpenAPI definition + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) # noqa: E501 + + The version of the OpenAPI document: v0 + Contact: support@gooddata.com + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from gooddata_api_client.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel +) +from gooddata_api_client.exceptions import ApiAttributeError + + +def lazy_import(): + from gooddata_api_client.model.json_api_attribute_out_meta import JsonApiAttributeOutMeta + from gooddata_api_client.model.json_api_computed_attribute_out_relationships import JsonApiComputedAttributeOutRelationships + from gooddata_api_client.model.json_api_dataset_out_with_links import JsonApiDatasetOutWithLinks + from gooddata_api_client.model.json_api_label_out_with_links import JsonApiLabelOutWithLinks + from gooddata_api_client.model.json_api_metric_out_with_links import JsonApiMetricOutWithLinks + from gooddata_api_client.model.json_api_user_identifier_out_with_links import JsonApiUserIdentifierOutWithLinks + from gooddata_api_client.model.json_api_visualization_object_out_attributes import JsonApiVisualizationObjectOutAttributes + from gooddata_api_client.model.json_api_visualization_object_out_with_links import JsonApiVisualizationObjectOutWithLinks + from gooddata_api_client.model.object_links import ObjectLinks + globals()['JsonApiAttributeOutMeta'] = JsonApiAttributeOutMeta + globals()['JsonApiComputedAttributeOutRelationships'] = JsonApiComputedAttributeOutRelationships + globals()['JsonApiDatasetOutWithLinks'] = JsonApiDatasetOutWithLinks + globals()['JsonApiLabelOutWithLinks'] = JsonApiLabelOutWithLinks + globals()['JsonApiMetricOutWithLinks'] = JsonApiMetricOutWithLinks + globals()['JsonApiUserIdentifierOutWithLinks'] = JsonApiUserIdentifierOutWithLinks + globals()['JsonApiVisualizationObjectOutAttributes'] = JsonApiVisualizationObjectOutAttributes + globals()['JsonApiVisualizationObjectOutWithLinks'] = JsonApiVisualizationObjectOutWithLinks + globals()['ObjectLinks'] = ObjectLinks + + +class JsonApiPublisherDocumentOutIncludes(ModelComposed): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + ('type',): { + 'VISUALIZATIONOBJECT': "visualizationObject", + }, + } + + validations = { + ('id',): { + 'regex': { + 'pattern': r'^(?!\.)[.A-Za-z0-9_-]{1,255}$', # noqa: E501 + }, + }, + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + lazy_import() + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + lazy_import() + return { + 'meta': (JsonApiAttributeOutMeta,), # noqa: E501 + 'relationships': (JsonApiComputedAttributeOutRelationships,), # noqa: E501 + 'links': (ObjectLinks,), # noqa: E501 + 'attributes': (JsonApiVisualizationObjectOutAttributes,), # noqa: E501 + 'id': (str,), # noqa: E501 + 'type': (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'meta': 'meta', # noqa: E501 + 'relationships': 'relationships', # noqa: E501 + 'links': 'links', # noqa: E501 + 'attributes': 'attributes', # noqa: E501 + 'id': 'id', # noqa: E501 + 'type': 'type', # noqa: E501 + } + + read_only_vars = { + } + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 + """JsonApiPublisherDocumentOutIncludes - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + meta (JsonApiAttributeOutMeta): [optional] # noqa: E501 + relationships (JsonApiComputedAttributeOutRelationships): [optional] # noqa: E501 + links (ObjectLinks): [optional] # noqa: E501 + attributes (JsonApiVisualizationObjectOutAttributes): [optional] # noqa: E501 + id (str): API identifier of an object. [optional] # noqa: E501 + type (str): Object type. [optional] if omitted the server will use the default value of "visualizationObject" # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + constant_args = { + '_check_type': _check_type, + '_path_to_item': _path_to_item, + '_spec_property_naming': _spec_property_naming, + '_configuration': _configuration, + '_visited_composed_classes': self._visited_composed_classes, + } + composed_info = validate_get_composed_info( + constant_args, kwargs, self) + self._composed_instances = composed_info[0] + self._var_name_to_model_instances = composed_info[1] + self._additional_properties_model_instances = composed_info[2] + discarded_args = composed_info[3] + + for var_name, var_value in kwargs.items(): + if var_name in discarded_args and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self._additional_properties_model_instances: + # discard variable. + continue + setattr(self, var_name, var_value) + + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + '_composed_instances', + '_var_name_to_model_instances', + '_additional_properties_model_instances', + ]) + + @convert_js_args_to_python_args + def __init__(self, *args, **kwargs): # noqa: E501 + """JsonApiPublisherDocumentOutIncludes - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + meta (JsonApiAttributeOutMeta): [optional] # noqa: E501 + relationships (JsonApiComputedAttributeOutRelationships): [optional] # noqa: E501 + links (ObjectLinks): [optional] # noqa: E501 + attributes (JsonApiVisualizationObjectOutAttributes): [optional] # noqa: E501 + id (str): API identifier of an object. [optional] # noqa: E501 + type (str): Object type. [optional] if omitted the server will use the default value of "visualizationObject" # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + constant_args = { + '_check_type': _check_type, + '_path_to_item': _path_to_item, + '_spec_property_naming': _spec_property_naming, + '_configuration': _configuration, + '_visited_composed_classes': self._visited_composed_classes, + } + composed_info = validate_get_composed_info( + constant_args, kwargs, self) + self._composed_instances = composed_info[0] + self._var_name_to_model_instances = composed_info[1] + self._additional_properties_model_instances = composed_info[2] + discarded_args = composed_info[3] + + for var_name, var_value in kwargs.items(): + if var_name in discarded_args and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self._additional_properties_model_instances: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") + + @cached_property + def _composed_schemas(): + # we need this here to make our import statements work + # we must store _composed_schemas in here so the code is only run + # when we invoke this method. If we kept this at the class + # level we would get an error because the class level + # code would be run when this module is imported, and these composed + # classes don't exist yet because their module has not finished + # loading + lazy_import() + return { + 'anyOf': [ + ], + 'allOf': [ + ], + 'oneOf': [ + JsonApiDatasetOutWithLinks, + JsonApiLabelOutWithLinks, + JsonApiMetricOutWithLinks, + JsonApiUserIdentifierOutWithLinks, + JsonApiVisualizationObjectOutWithLinks, + ], + } diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_list.py b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_list.py index 640074553..bda9ffc0f 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_list.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_list.py @@ -32,12 +32,12 @@ def lazy_import(): from gooddata_api_client.model.json_api_agent_out_list_meta import JsonApiAgentOutListMeta + from gooddata_api_client.model.json_api_publisher_document_out_includes import JsonApiPublisherDocumentOutIncludes from gooddata_api_client.model.json_api_publisher_document_out_with_links import JsonApiPublisherDocumentOutWithLinks - from gooddata_api_client.model.json_api_user_identifier_out_with_links import JsonApiUserIdentifierOutWithLinks from gooddata_api_client.model.list_links import ListLinks globals()['JsonApiAgentOutListMeta'] = JsonApiAgentOutListMeta + globals()['JsonApiPublisherDocumentOutIncludes'] = JsonApiPublisherDocumentOutIncludes globals()['JsonApiPublisherDocumentOutWithLinks'] = JsonApiPublisherDocumentOutWithLinks - globals()['JsonApiUserIdentifierOutWithLinks'] = JsonApiUserIdentifierOutWithLinks globals()['ListLinks'] = ListLinks @@ -99,7 +99,7 @@ def openapi_types(): lazy_import() return { 'data': ([JsonApiPublisherDocumentOutWithLinks],), # noqa: E501 - 'included': ([JsonApiUserIdentifierOutWithLinks],), # noqa: E501 + 'included': ([JsonApiPublisherDocumentOutIncludes],), # noqa: E501 'links': (ListLinks,), # noqa: E501 'meta': (JsonApiAgentOutListMeta,), # noqa: E501 } @@ -160,7 +160,7 @@ def _from_openapi_data(cls, data, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - included ([JsonApiUserIdentifierOutWithLinks]): Included resources. [optional] # noqa: E501 + included ([JsonApiPublisherDocumentOutIncludes]): Included resources. [optional] # noqa: E501 links (ListLinks): [optional] # noqa: E501 meta (JsonApiAgentOutListMeta): [optional] # noqa: E501 """ @@ -252,7 +252,7 @@ def __init__(self, data, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - included ([JsonApiUserIdentifierOutWithLinks]): Included resources. [optional] # noqa: E501 + included ([JsonApiPublisherDocumentOutIncludes]): Included resources. [optional] # noqa: E501 links (ListLinks): [optional] # noqa: E501 meta (JsonApiAgentOutListMeta): [optional] # noqa: E501 """ diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_relationships.py b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_relationships.py new file mode 100644 index 000000000..799a22c33 --- /dev/null +++ b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_relationships.py @@ -0,0 +1,298 @@ +""" + OpenAPI definition + + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) # noqa: E501 + + The version of the OpenAPI document: v0 + Contact: support@gooddata.com + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from gooddata_api_client.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel +) +from gooddata_api_client.exceptions import ApiAttributeError + + +def lazy_import(): + from gooddata_api_client.model.json_api_agent_out_relationships_created_by import JsonApiAgentOutRelationshipsCreatedBy + from gooddata_api_client.model.json_api_analytical_dashboard_out_relationships_datasets import JsonApiAnalyticalDashboardOutRelationshipsDatasets + from gooddata_api_client.model.json_api_analytical_dashboard_out_relationships_labels import JsonApiAnalyticalDashboardOutRelationshipsLabels + from gooddata_api_client.model.json_api_analytical_dashboard_out_relationships_metrics import JsonApiAnalyticalDashboardOutRelationshipsMetrics + from gooddata_api_client.model.json_api_analytical_dashboard_out_relationships_visualization_objects import JsonApiAnalyticalDashboardOutRelationshipsVisualizationObjects + globals()['JsonApiAgentOutRelationshipsCreatedBy'] = JsonApiAgentOutRelationshipsCreatedBy + globals()['JsonApiAnalyticalDashboardOutRelationshipsDatasets'] = JsonApiAnalyticalDashboardOutRelationshipsDatasets + globals()['JsonApiAnalyticalDashboardOutRelationshipsLabels'] = JsonApiAnalyticalDashboardOutRelationshipsLabels + globals()['JsonApiAnalyticalDashboardOutRelationshipsMetrics'] = JsonApiAnalyticalDashboardOutRelationshipsMetrics + globals()['JsonApiAnalyticalDashboardOutRelationshipsVisualizationObjects'] = JsonApiAnalyticalDashboardOutRelationshipsVisualizationObjects + + +class JsonApiPublisherDocumentOutRelationships(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + } + + validations = { + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + lazy_import() + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + lazy_import() + return { + 'created_by': (JsonApiAgentOutRelationshipsCreatedBy,), # noqa: E501 + 'datasets': (JsonApiAnalyticalDashboardOutRelationshipsDatasets,), # noqa: E501 + 'labels': (JsonApiAnalyticalDashboardOutRelationshipsLabels,), # noqa: E501 + 'metrics': (JsonApiAnalyticalDashboardOutRelationshipsMetrics,), # noqa: E501 + 'modified_by': (JsonApiAgentOutRelationshipsCreatedBy,), # noqa: E501 + 'visualization_objects': (JsonApiAnalyticalDashboardOutRelationshipsVisualizationObjects,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'created_by': 'createdBy', # noqa: E501 + 'datasets': 'datasets', # noqa: E501 + 'labels': 'labels', # noqa: E501 + 'metrics': 'metrics', # noqa: E501 + 'modified_by': 'modifiedBy', # noqa: E501 + 'visualization_objects': 'visualizationObjects', # noqa: E501 + } + + read_only_vars = { + } + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 + """JsonApiPublisherDocumentOutRelationships - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + created_by (JsonApiAgentOutRelationshipsCreatedBy): [optional] # noqa: E501 + datasets (JsonApiAnalyticalDashboardOutRelationshipsDatasets): [optional] # noqa: E501 + labels (JsonApiAnalyticalDashboardOutRelationshipsLabels): [optional] # noqa: E501 + metrics (JsonApiAnalyticalDashboardOutRelationshipsMetrics): [optional] # noqa: E501 + modified_by (JsonApiAgentOutRelationshipsCreatedBy): [optional] # noqa: E501 + visualization_objects (JsonApiAnalyticalDashboardOutRelationshipsVisualizationObjects): [optional] # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', True) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, *args, **kwargs): # noqa: E501 + """JsonApiPublisherDocumentOutRelationships - a model defined in OpenAPI + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + created_by (JsonApiAgentOutRelationshipsCreatedBy): [optional] # noqa: E501 + datasets (JsonApiAnalyticalDashboardOutRelationshipsDatasets): [optional] # noqa: E501 + labels (JsonApiAnalyticalDashboardOutRelationshipsLabels): [optional] # noqa: E501 + metrics (JsonApiAnalyticalDashboardOutRelationshipsMetrics): [optional] # noqa: E501 + modified_by (JsonApiAgentOutRelationshipsCreatedBy): [optional] # noqa: E501 + visualization_objects (JsonApiAnalyticalDashboardOutRelationshipsVisualizationObjects): [optional] # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + for arg in args: + if isinstance(arg, dict): + kwargs.update(arg) + else: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_with_links.py b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_with_links.py index d920c40ec..8e6eafc8e 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_with_links.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_out_with_links.py @@ -32,15 +32,15 @@ def lazy_import(): from gooddata_api_client.model.json_api_aggregated_fact_out_meta import JsonApiAggregatedFactOutMeta - from gooddata_api_client.model.json_api_dashboard_plugin_out_relationships import JsonApiDashboardPluginOutRelationships from gooddata_api_client.model.json_api_publisher_document_out import JsonApiPublisherDocumentOut from gooddata_api_client.model.json_api_publisher_document_out_attributes import JsonApiPublisherDocumentOutAttributes + from gooddata_api_client.model.json_api_publisher_document_out_relationships import JsonApiPublisherDocumentOutRelationships from gooddata_api_client.model.object_links import ObjectLinks from gooddata_api_client.model.object_links_container import ObjectLinksContainer globals()['JsonApiAggregatedFactOutMeta'] = JsonApiAggregatedFactOutMeta - globals()['JsonApiDashboardPluginOutRelationships'] = JsonApiDashboardPluginOutRelationships globals()['JsonApiPublisherDocumentOut'] = JsonApiPublisherDocumentOut globals()['JsonApiPublisherDocumentOutAttributes'] = JsonApiPublisherDocumentOutAttributes + globals()['JsonApiPublisherDocumentOutRelationships'] = JsonApiPublisherDocumentOutRelationships globals()['ObjectLinks'] = ObjectLinks globals()['ObjectLinksContainer'] = ObjectLinksContainer @@ -110,7 +110,7 @@ def openapi_types(): 'id': (str,), # noqa: E501 'type': (str,), # noqa: E501 'meta': (JsonApiAggregatedFactOutMeta,), # noqa: E501 - 'relationships': (JsonApiDashboardPluginOutRelationships,), # noqa: E501 + 'relationships': (JsonApiPublisherDocumentOutRelationships,), # noqa: E501 'links': (ObjectLinks,), # noqa: E501 } @@ -171,7 +171,7 @@ def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 through its discriminator because we passed in _visited_composed_classes = (Animal,) meta (JsonApiAggregatedFactOutMeta): [optional] # noqa: E501 - relationships (JsonApiDashboardPluginOutRelationships): [optional] # noqa: E501 + relationships (JsonApiPublisherDocumentOutRelationships): [optional] # noqa: E501 links (ObjectLinks): [optional] # noqa: E501 """ @@ -281,7 +281,7 @@ def __init__(self, *args, **kwargs): # noqa: E501 through its discriminator because we passed in _visited_composed_classes = (Animal,) meta (JsonApiAggregatedFactOutMeta): [optional] # noqa: E501 - relationships (JsonApiDashboardPluginOutRelationships): [optional] # noqa: E501 + relationships (JsonApiPublisherDocumentOutRelationships): [optional] # noqa: E501 links (ObjectLinks): [optional] # noqa: E501 """ diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_page_template_out_attributes.py b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_page_template_out_attributes.py index ff9e7c4f1..1c64b3df3 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_page_template_out_attributes.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_publisher_document_page_template_out_attributes.py @@ -105,6 +105,7 @@ def openapi_types(): lazy_import() return { 'content': (JsonApiPublisherDocumentPageTemplateInAttributesContent,), # noqa: E501 + 'is_default': (bool,), # noqa: E501 'title': (str,), # noqa: E501 'version': (str,), # noqa: E501 'are_relations_valid': (bool,), # noqa: E501 @@ -121,6 +122,7 @@ def discriminator(): attribute_map = { 'content': 'content', # noqa: E501 + 'is_default': 'isDefault', # noqa: E501 'title': 'title', # noqa: E501 'version': 'version', # noqa: E501 'are_relations_valid': 'areRelationsValid', # noqa: E501 @@ -131,17 +133,19 @@ def discriminator(): } read_only_vars = { + 'is_default', # noqa: E501 } _composed_schemas = {} @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, content, title, version, *args, **kwargs): # noqa: E501 + def _from_openapi_data(cls, content, is_default, title, version, *args, **kwargs): # noqa: E501 """JsonApiPublisherDocumentPageTemplateOutAttributes - a model defined in OpenAPI Args: content (JsonApiPublisherDocumentPageTemplateInAttributesContent): + is_default (bool): Whether the backend ships this page template as a read-only default. title (str): version (str): Version of the content format. @@ -213,6 +217,7 @@ def _from_openapi_data(cls, content, title, version, *args, **kwargs): # noqa: self._visited_composed_classes = _visited_composed_classes + (self.__class__,) self.content = content + self.is_default = is_default self.title = title self.version = version for var_name, var_value in kwargs.items(): diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_user_setting_in_attributes.py b/gooddata-api-client/gooddata_api_client/model/json_api_user_setting_in_attributes.py index b5b920abb..42844f607 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_user_setting_in_attributes.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_user_setting_in_attributes.py @@ -116,6 +116,7 @@ class JsonApiUserSettingInAttributes(ModelNormal): 'DEFAULT_VISUALIZATION_VISIBILITY': "DEFAULT_VISUALIZATION_VISIBILITY", 'DEFAULT_METRIC_VISIBILITY': "DEFAULT_METRIC_VISIBILITY", 'GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE': "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + 'QUERY_ENGINE': "QUERY_ENGINE", }, } diff --git a/gooddata-api-client/gooddata_api_client/model/json_api_workspace_out_meta.py b/gooddata-api-client/gooddata_api_client/model/json_api_workspace_out_meta.py index 71a01738c..d4119bf1f 100644 --- a/gooddata-api-client/gooddata_api_client/model/json_api_workspace_out_meta.py +++ b/gooddata-api-client/gooddata_api_client/model/json_api_workspace_out_meta.py @@ -79,6 +79,7 @@ class JsonApiWorkspaceOutMeta(ModelNormal): 'MANAGE_VISUALIZATIONS': "MANAGE_VISUALIZATIONS", 'CREATE_VISUALIZATION': "CREATE_VISUALIZATION", 'CREATE_COMPUTED_ATTRIBUTE': "CREATE_COMPUTED_ATTRIBUTE", + 'CREATE_DOCUMENT': "CREATE_DOCUMENT", 'VIEW': "VIEW", }, } diff --git a/gooddata-api-client/gooddata_api_client/model/notification_channel_destination.py b/gooddata-api-client/gooddata_api_client/model/notification_channel_destination.py index 4bebe59c9..7e74b5d18 100644 --- a/gooddata-api-client/gooddata_api_client/model/notification_channel_destination.py +++ b/gooddata-api-client/gooddata_api_client/model/notification_channel_destination.py @@ -89,7 +89,7 @@ class NotificationChannelDestination(ModelComposed): 'max_length': 10000, }, ('url',): { - 'max_length': 255, + 'max_length': 2048, 'regex': { 'pattern': r'https?\:\/\/.*', # noqa: E501 }, diff --git a/gooddata-api-client/gooddata_api_client/model/amplitude_service.py b/gooddata-api-client/gooddata_api_client/model/object_storage_ref.py similarity index 85% rename from gooddata-api-client/gooddata_api_client/model/amplitude_service.py rename to gooddata-api-client/gooddata_api_client/model/object_storage_ref.py index 5f2a3a6ae..94fdc21ea 100644 --- a/gooddata-api-client/gooddata_api_client/model/amplitude_service.py +++ b/gooddata-api-client/gooddata_api_client/model/object_storage_ref.py @@ -31,7 +31,7 @@ -class AmplitudeService(ModelNormal): +class ObjectStorageRef(ModelNormal): """NOTE: This class is auto generated by OpenAPI Generator. Ref: https://openapi-generator.tech @@ -82,10 +82,8 @@ def openapi_types(): and the value is attribute type. """ return { - 'ai_project_api_key': (str,), # noqa: E501 - 'endpoint': (str,), # noqa: E501 - 'gd_common_api_key': (str,), # noqa: E501 - 'reporting_endpoint': (str,), # noqa: E501 + 'name': (str,), # noqa: E501 + 'storage_id': (str,), # noqa: E501 } @cached_property @@ -94,10 +92,8 @@ def discriminator(): attribute_map = { - 'ai_project_api_key': 'aiProjectApiKey', # noqa: E501 - 'endpoint': 'endpoint', # noqa: E501 - 'gd_common_api_key': 'gdCommonApiKey', # noqa: E501 - 'reporting_endpoint': 'reportingEndpoint', # noqa: E501 + 'name': 'name', # noqa: E501 + 'storage_id': 'storageId', # noqa: E501 } read_only_vars = { @@ -107,13 +103,12 @@ def discriminator(): @classmethod @convert_js_args_to_python_args - def _from_openapi_data(cls, ai_project_api_key, endpoint, gd_common_api_key, *args, **kwargs): # noqa: E501 - """AmplitudeService - a model defined in OpenAPI + def _from_openapi_data(cls, name, storage_id, *args, **kwargs): # noqa: E501 + """ObjectStorageRef - a model defined in OpenAPI Args: - ai_project_api_key (str): API key for AI project - intended for frontend use. - endpoint (str): Amplitude endpoint URL. - gd_common_api_key (str): API key for GoodData common project - used by backend. + name (str): Human-readable name of the storage. + storage_id (str): Stable identifier of the storage, as returned by the ObjectStorages listing. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -146,7 +141,6 @@ def _from_openapi_data(cls, ai_project_api_key, endpoint, gd_common_api_key, *ar Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - reporting_endpoint (str): Optional reporting endpoint for proxying telemetry events.. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -178,9 +172,8 @@ def _from_openapi_data(cls, ai_project_api_key, endpoint, gd_common_api_key, *ar self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) - self.ai_project_api_key = ai_project_api_key - self.endpoint = endpoint - self.gd_common_api_key = gd_common_api_key + self.name = name + self.storage_id = storage_id for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ @@ -201,13 +194,12 @@ def _from_openapi_data(cls, ai_project_api_key, endpoint, gd_common_api_key, *ar ]) @convert_js_args_to_python_args - def __init__(self, ai_project_api_key, endpoint, gd_common_api_key, *args, **kwargs): # noqa: E501 - """AmplitudeService - a model defined in OpenAPI + def __init__(self, name, storage_id, *args, **kwargs): # noqa: E501 + """ObjectStorageRef - a model defined in OpenAPI Args: - ai_project_api_key (str): API key for AI project - intended for frontend use. - endpoint (str): Amplitude endpoint URL. - gd_common_api_key (str): API key for GoodData common project - used by backend. + name (str): Human-readable name of the storage. + storage_id (str): Stable identifier of the storage, as returned by the ObjectStorages listing. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -240,7 +232,6 @@ def __init__(self, ai_project_api_key, endpoint, gd_common_api_key, *args, **kwa Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - reporting_endpoint (str): Optional reporting endpoint for proxying telemetry events.. [optional] # noqa: E501 """ _check_type = kwargs.pop('_check_type', True) @@ -270,9 +261,8 @@ def __init__(self, ai_project_api_key, endpoint, gd_common_api_key, *args, **kwa self._configuration = _configuration self._visited_composed_classes = _visited_composed_classes + (self.__class__,) - self.ai_project_api_key = ai_project_api_key - self.endpoint = endpoint - self.gd_common_api_key = gd_common_api_key + self.name = name + self.storage_id = storage_id for var_name, var_value in kwargs.items(): if var_name not in self.attribute_map and \ self._configuration is not None and \ diff --git a/gooddata-api-client/gooddata_api_client/model/provision_database_instance_request.py b/gooddata-api-client/gooddata_api_client/model/provision_database_instance_request.py index 1e065f09c..535cfada6 100644 --- a/gooddata-api-client/gooddata_api_client/model/provision_database_instance_request.py +++ b/gooddata-api-client/gooddata_api_client/model/provision_database_instance_request.py @@ -114,7 +114,7 @@ def _from_openapi_data(cls, name, storage_ids, *args, **kwargs): # noqa: E501 Args: name (str): Name of the database instance - storage_ids ([str]): Set of ids of the storage instances this database instance should access. + storage_ids ([str]): Set of ids of the storage instances this database instance should access. Each entry is a `storageId` from the ObjectStorages listing or, for backward compatibility, a storage name. Must contain exactly one entry. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -207,7 +207,7 @@ def __init__(self, name, storage_ids, *args, **kwargs): # noqa: E501 Args: name (str): Name of the database instance - storage_ids ([str]): Set of ids of the storage instances this database instance should access. + storage_ids ([str]): Set of ids of the storage instances this database instance should access. Each entry is a `storageId` from the ObjectStorages listing or, for backward compatibility, a storage name. Must contain exactly one entry. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types diff --git a/gooddata-api-client/gooddata_api_client/model/publisher_document_obj_ref.py b/gooddata-api-client/gooddata_api_client/model/publisher_document_obj_ref.py index 08627710a..817ae6183 100644 --- a/gooddata-api-client/gooddata_api_client/model/publisher_document_obj_ref.py +++ b/gooddata-api-client/gooddata_api_client/model/publisher_document_obj_ref.py @@ -56,6 +56,13 @@ class PublisherDocumentObjRef(ModelNormal): """ allowed_values = { + ('type',): { + 'INSIGHT': "insight", + 'DISPLAYFORM': "displayForm", + 'DATASET': "dataSet", + 'MEASURE': "measure", + 'ATTRIBUTE': "attribute", + }, } validations = { @@ -108,7 +115,7 @@ def _from_openapi_data(cls, identifier, type, *args, **kwargs): # noqa: E501 Args: identifier (str): - type (str): sdk-model object type, such as `displayForm`, `dataSet` or `measure`. + type (str): sdk-model object type. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types @@ -199,7 +206,7 @@ def __init__(self, identifier, type, *args, **kwargs): # noqa: E501 Args: identifier (str): - type (str): sdk-model object type, such as `displayForm`, `dataSet` or `measure`. + type (str): sdk-model object type. Keyword Args: _check_type (bool): if True, values for parameters in openapi_types diff --git a/gooddata-api-client/gooddata_api_client/model/resolved_setting.py b/gooddata-api-client/gooddata_api_client/model/resolved_setting.py index 84f5cd4b6..3e8a57ffa 100644 --- a/gooddata-api-client/gooddata_api_client/model/resolved_setting.py +++ b/gooddata-api-client/gooddata_api_client/model/resolved_setting.py @@ -121,6 +121,7 @@ class ResolvedSetting(ModelNormal): 'DEFAULT_VISUALIZATION_VISIBILITY': "DEFAULT_VISUALIZATION_VISIBILITY", 'DEFAULT_METRIC_VISIBILITY': "DEFAULT_METRIC_VISIBILITY", 'GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE': "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + 'QUERY_ENGINE': "QUERY_ENGINE", }, } diff --git a/gooddata-api-client/gooddata_api_client/model/telemetry_services.py b/gooddata-api-client/gooddata_api_client/model/telemetry_services.py index d92406f64..effb85bc5 100644 --- a/gooddata-api-client/gooddata_api_client/model/telemetry_services.py +++ b/gooddata-api-client/gooddata_api_client/model/telemetry_services.py @@ -31,10 +31,8 @@ def lazy_import(): - from gooddata_api_client.model.amplitude_service import AmplitudeService from gooddata_api_client.model.matomo_service import MatomoService from gooddata_api_client.model.open_telemetry_service import OpenTelemetryService - globals()['AmplitudeService'] = AmplitudeService globals()['MatomoService'] = MatomoService globals()['OpenTelemetryService'] = OpenTelemetryService @@ -92,7 +90,6 @@ def openapi_types(): """ lazy_import() return { - 'amplitude': (AmplitudeService,), # noqa: E501 'matomo': (MatomoService,), # noqa: E501 'open_telemetry': (OpenTelemetryService,), # noqa: E501 } @@ -103,7 +100,6 @@ def discriminator(): attribute_map = { - 'amplitude': 'amplitude', # noqa: E501 'matomo': 'matomo', # noqa: E501 'open_telemetry': 'openTelemetry', # noqa: E501 } @@ -149,7 +145,6 @@ def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - amplitude (AmplitudeService): [optional] # noqa: E501 matomo (MatomoService): [optional] # noqa: E501 open_telemetry (OpenTelemetryService): [optional] # noqa: E501 """ @@ -237,7 +232,6 @@ def __init__(self, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) - amplitude (AmplitudeService): [optional] # noqa: E501 matomo (MatomoService): [optional] # noqa: E501 open_telemetry (OpenTelemetryService): [optional] # noqa: E501 """ diff --git a/gooddata-api-client/gooddata_api_client/model/user_management_workspace_permission_assignment.py b/gooddata-api-client/gooddata_api_client/model/user_management_workspace_permission_assignment.py index e6f5fab96..165f00a7d 100644 --- a/gooddata-api-client/gooddata_api_client/model/user_management_workspace_permission_assignment.py +++ b/gooddata-api-client/gooddata_api_client/model/user_management_workspace_permission_assignment.py @@ -71,6 +71,7 @@ class UserManagementWorkspacePermissionAssignment(ModelNormal): 'MANAGE_VISUALIZATIONS': "MANAGE_VISUALIZATIONS", 'CREATE_VISUALIZATION': "CREATE_VISUALIZATION", 'CREATE_COMPUTED_ATTRIBUTE': "CREATE_COMPUTED_ATTRIBUTE", + 'CREATE_DOCUMENT': "CREATE_DOCUMENT", 'VIEW': "VIEW", }, ('permissions',): { @@ -88,6 +89,7 @@ class UserManagementWorkspacePermissionAssignment(ModelNormal): 'MANAGE_VISUALIZATIONS': "MANAGE_VISUALIZATIONS", 'CREATE_VISUALIZATION': "CREATE_VISUALIZATION", 'CREATE_COMPUTED_ATTRIBUTE': "CREATE_COMPUTED_ATTRIBUTE", + 'CREATE_DOCUMENT': "CREATE_DOCUMENT", 'VIEW': "VIEW", }, ('access_source',): { diff --git a/gooddata-api-client/gooddata_api_client/model/webhook.py b/gooddata-api-client/gooddata_api_client/model/webhook.py index 50ba1edf1..f8e508150 100644 --- a/gooddata-api-client/gooddata_api_client/model/webhook.py +++ b/gooddata-api-client/gooddata_api_client/model/webhook.py @@ -77,7 +77,7 @@ class Webhook(ModelComposed): 'max_length': 10000, }, ('url',): { - 'max_length': 255, + 'max_length': 2048, 'regex': { 'pattern': r'https?\:\/\/.*', # noqa: E501 }, diff --git a/gooddata-api-client/gooddata_api_client/model/webhook_all_of.py b/gooddata-api-client/gooddata_api_client/model/webhook_all_of.py index 20a568dcd..fbdba1d5d 100644 --- a/gooddata-api-client/gooddata_api_client/model/webhook_all_of.py +++ b/gooddata-api-client/gooddata_api_client/model/webhook_all_of.py @@ -73,7 +73,7 @@ class WebhookAllOf(ModelNormal): 'max_length': 10000, }, ('url',): { - 'max_length': 255, + 'max_length': 2048, 'regex': { 'pattern': r'https?\:\/\/.*', # noqa: E501 }, diff --git a/gooddata-api-client/gooddata_api_client/model/workspace_permission_assignment.py b/gooddata-api-client/gooddata_api_client/model/workspace_permission_assignment.py index 1fcec692a..7f89aed6f 100644 --- a/gooddata-api-client/gooddata_api_client/model/workspace_permission_assignment.py +++ b/gooddata-api-client/gooddata_api_client/model/workspace_permission_assignment.py @@ -75,6 +75,7 @@ class WorkspacePermissionAssignment(ModelNormal): 'MANAGE_VISUALIZATIONS': "MANAGE_VISUALIZATIONS", 'CREATE_VISUALIZATION': "CREATE_VISUALIZATION", 'CREATE_COMPUTED_ATTRIBUTE': "CREATE_COMPUTED_ATTRIBUTE", + 'CREATE_DOCUMENT': "CREATE_DOCUMENT", 'VIEW': "VIEW", }, ('permissions',): { @@ -92,6 +93,7 @@ class WorkspacePermissionAssignment(ModelNormal): 'MANAGE_VISUALIZATIONS': "MANAGE_VISUALIZATIONS", 'CREATE_VISUALIZATION': "CREATE_VISUALIZATION", 'CREATE_COMPUTED_ATTRIBUTE': "CREATE_COMPUTED_ATTRIBUTE", + 'CREATE_DOCUMENT': "CREATE_DOCUMENT", 'VIEW': "VIEW", }, } diff --git a/gooddata-api-client/gooddata_api_client/models/__init__.py b/gooddata-api-client/gooddata_api_client/models/__init__.py index d346f8a26..f330391f3 100644 --- a/gooddata-api-client/gooddata_api_client/models/__init__.py +++ b/gooddata-api-client/gooddata_api_client/models/__init__.py @@ -50,7 +50,6 @@ from gooddata_api_client.model.alert_evaluation_row import AlertEvaluationRow from gooddata_api_client.model.all_time_date_filter import AllTimeDateFilter from gooddata_api_client.model.all_time_date_filter_all_time_date_filter import AllTimeDateFilterAllTimeDateFilter -from gooddata_api_client.model.amplitude_service import AmplitudeService from gooddata_api_client.model.analytics_catalog_created_by import AnalyticsCatalogCreatedBy from gooddata_api_client.model.analytics_catalog_tags import AnalyticsCatalogTags from gooddata_api_client.model.analytics_catalog_user import AnalyticsCatalogUser @@ -1007,7 +1006,9 @@ from gooddata_api_client.model.json_api_publisher_document_out import JsonApiPublisherDocumentOut from gooddata_api_client.model.json_api_publisher_document_out_attributes import JsonApiPublisherDocumentOutAttributes from gooddata_api_client.model.json_api_publisher_document_out_document import JsonApiPublisherDocumentOutDocument +from gooddata_api_client.model.json_api_publisher_document_out_includes import JsonApiPublisherDocumentOutIncludes from gooddata_api_client.model.json_api_publisher_document_out_list import JsonApiPublisherDocumentOutList +from gooddata_api_client.model.json_api_publisher_document_out_relationships import JsonApiPublisherDocumentOutRelationships from gooddata_api_client.model.json_api_publisher_document_out_with_links import JsonApiPublisherDocumentOutWithLinks from gooddata_api_client.model.json_api_publisher_document_page_template_in import JsonApiPublisherDocumentPageTemplateIn from gooddata_api_client.model.json_api_publisher_document_page_template_in_attributes import JsonApiPublisherDocumentPageTemplateInAttributes @@ -1341,6 +1342,7 @@ from gooddata_api_client.model.object_links import ObjectLinks from gooddata_api_client.model.object_links_container import ObjectLinksContainer from gooddata_api_client.model.object_storage_info import ObjectStorageInfo +from gooddata_api_client.model.object_storage_ref import ObjectStorageRef from gooddata_api_client.model.open_ai_provider_config import OpenAIProviderConfig from gooddata_api_client.model.open_ai_api_key_auth import OpenAiApiKeyAuth from gooddata_api_client.model.open_ai_api_key_auth_all_of import OpenAiApiKeyAuthAllOf diff --git a/schemas/gooddata-afm-client.json b/schemas/gooddata-afm-client.json index 0d6f0f7f1..133e36bad 100644 --- a/schemas/gooddata-afm-client.json +++ b/schemas/gooddata-afm-client.json @@ -1011,7 +1011,7 @@ "type": "string" }, "numberFormat": { - "description": "Format to be used to format the attribute values, the same kind of format string as the measure format. Only filled for computed attributes with a format.", + "description": "Format to be used to format the attribute values, the same kind of format string as the measure format. Only filled for computed attributes with a format and INT or NUMERIC data type.", "type": "string" }, "primaryLabel": { @@ -1391,10 +1391,16 @@ "$ref": "#/components/schemas/MetricValueChange" }, "type": "array" + }, + "restrictedCount": { + "description": "Number of attributes and computed attributes left out of the analysis because the user has no access to them.", + "format": "int32", + "type": "integer" } }, "required": [ - "data" + "data", + "restrictedCount" ], "type": "object" }, @@ -1683,20 +1689,28 @@ "type": "string" }, "storageIds": { - "description": "Set of ids of the storage instances this database instance should access.", + "description": "Set of names of the storage instances this database instance accesses. Kept for backward compatibility; use `storages` for the storage ids.", "items": { - "description": "Set of ids of the storage instances this database instance should access.", + "description": "Set of names of the storage instances this database instance accesses. Kept for backward compatibility; use `storages` for the storage ids.", "type": "string" }, "type": "array", "uniqueItems": true + }, + "storages": { + "description": "Storage instances this database instance accesses.", + "items": { + "$ref": "#/components/schemas/ObjectStorageRef" + }, + "type": "array" } }, "required": [ "dataSources", "id", "name", - "storageIds" + "storageIds", + "storages" ], "type": "object" }, @@ -2045,7 +2059,7 @@ "type": "string" }, "numberFormat": { - "description": "Format to be used to format the element values, the same kind of format string as the measure format. Only filled for computed attributes with a format.", + "description": "Format to be used to format the element values, the same kind of format string as the measure format. Only filled for computed attributes with a format and INT or NUMERIC data type.", "type": "string" }, "paging": { @@ -3950,6 +3964,25 @@ ], "type": "object" }, + "ObjectStorageRef": { + "description": "Reference to a registered ObjectStorage.", + "properties": { + "name": { + "description": "Human-readable name of the storage.", + "example": "s3-data-lake", + "type": "string" + }, + "storageId": { + "description": "Stable identifier of the storage, as returned by the ObjectStorages listing.", + "type": "string" + } + }, + "required": [ + "name", + "storageId" + ], + "type": "object" + }, "OpenAIProviderConfig": { "description": "Configuration for OpenAI provider.", "properties": { @@ -4410,9 +4443,9 @@ "type": "string" }, "storageIds": { - "description": "Set of ids of the storage instances this database instance should access.", + "description": "Set of ids of the storage instances this database instance should access. Each entry is a `storageId` from the ObjectStorages listing or, for backward compatibility, a storage name. Must contain exactly one entry.", "items": { - "description": "Set of ids of the storage instances this database instance should access.", + "description": "Set of ids of the storage instances this database instance should access. Each entry is a `storageId` from the ObjectStorages listing or, for backward compatibility, a storage name. Must contain exactly one entry.", "type": "string" }, "type": "array", @@ -6639,7 +6672,7 @@ } }, { - "description": "Requested explain type. If not specified all types are bundled in a ZIP archive.\n\n`MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info\n\n`GRPC_MODEL` - Datasets used in execution\n\n`GRPC_MODEL_SVG` - Generated SVG image of the datasets\n\n`COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query\n\n`WDF` - Workspace data filters in execution workspace context\n\n`QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL\n\n`QT_SVG` - Generated SVG image of the Query Tree\n\n`OPT_QT` - Optimized Query Tree\n\n`OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree\n\n`SQL` - Final SQL to be executed\n\n`COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets\n\n`SETTINGS` - Settings used to execute explain request\n\n`GIT` - Git properties of current build", + "description": "Requested explain type. If not specified all types are bundled in a ZIP archive.\n\n`MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info\n\n`GRPC_MODEL` - Datasets used in execution\n\n`MODEL_STATISTICS` - Physical table statistics of the datasets used in execution\n\n`GRPC_MODEL_SVG` - Generated SVG image of the datasets\n\n`COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query\n\n`WDF` - Workspace data filters in execution workspace context\n\n`QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL\n\n`QT_SVG` - Generated SVG image of the Query Tree\n\n`OPT_QT` - Optimized Query Tree\n\n`OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree\n\n`SQL` - Final SQL to be executed\n\n`COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets\n\n`SETTINGS` - Settings used to execute explain request\n\n`GIT` - Git properties of current build", "in": "query", "name": "explainType", "required": false, @@ -6647,6 +6680,7 @@ "enum": [ "MAQL", "GRPC_MODEL", + "MODEL_STATISTICS", "GRPC_MODEL_SVG", "WDF", "QT", @@ -6680,7 +6714,7 @@ "application/sql": {}, "application/zip": { "schema": { - "description": "ZIP with MAQL, GRPC_MODEL, GRPC_MODEL_SVG, WDF, QT, QT_SVG, OPT_QT, OPT_QT_SVG and SQL files", + "description": "ZIP with MAQL, GRPC_MODEL, MODEL_STATISTICS, GRPC_MODEL_SVG, WDF, QT, QT_SVG, OPT_QT, OPT_QT_SVG and SQL files", "format": "binary", "type": "string" } diff --git a/schemas/gooddata-api-client.json b/schemas/gooddata-api-client.json index 7bb0cc87a..dc4e82fb1 100644 --- a/schemas/gooddata-api-client.json +++ b/schemas/gooddata-api-client.json @@ -1060,33 +1060,6 @@ ], "type": "object" }, - "AmplitudeService": { - "description": "Amplitude service.", - "properties": { - "aiProjectApiKey": { - "description": "API key for AI project - intended for frontend use.", - "type": "string" - }, - "endpoint": { - "description": "Amplitude endpoint URL.", - "type": "string" - }, - "gdCommonApiKey": { - "description": "API key for GoodData common project - used by backend.", - "type": "string" - }, - "reportingEndpoint": { - "description": "Optional reporting endpoint for proxying telemetry events.", - "type": "string" - } - }, - "required": [ - "aiProjectApiKey", - "endpoint", - "gdCommonApiKey" - ], - "type": "object" - }, "AnalyticsCatalogCreatedBy": { "description": "List of users who created catalog objects in the workspace hierarchy.", "properties": { @@ -1966,7 +1939,7 @@ "type": "string" }, "numberFormat": { - "description": "Format to be used to format the attribute values, the same kind of format string as the measure format. Only filled for computed attributes with a format.", + "description": "Format to be used to format the attribute values, the same kind of format string as the measure format. Only filled for computed attributes with a format and INT or NUMERIC data type.", "type": "string" }, "primaryLabel": { @@ -2857,10 +2830,16 @@ "$ref": "#/components/schemas/MetricValueChange" }, "type": "array" + }, + "restrictedCount": { + "description": "Number of attributes and computed attributes left out of the analysis because the user has no access to them.", + "format": "int32", + "type": "integer" } }, "required": [ - "data" + "data", + "restrictedCount" ], "type": "object" }, @@ -5231,20 +5210,28 @@ "type": "string" }, "storageIds": { - "description": "Set of ids of the storage instances this database instance should access.", + "description": "Set of names of the storage instances this database instance accesses. Kept for backward compatibility; use `storages` for the storage ids.", "items": { - "description": "Set of ids of the storage instances this database instance should access.", + "description": "Set of names of the storage instances this database instance accesses. Kept for backward compatibility; use `storages` for the storage ids.", "type": "string" }, "type": "array", "uniqueItems": true + }, + "storages": { + "description": "Storage instances this database instance accesses.", + "items": { + "$ref": "#/components/schemas/ObjectStorageRef" + }, + "type": "array" } }, "required": [ "dataSources", "id", "name", - "storageIds" + "storageIds", + "storages" ], "type": "object" }, @@ -8079,7 +8066,7 @@ }, "customDashboardUrl": { "description": "Custom dashboard url that is going to be used in the notification. If not specified it is going to be deduced based on the context. Allowed placeholders are:\n{workspaceId}\n{dashboardId}\n{automationId}\n{asOfDate}\n", - "maxLength": 255, + "maxLength": 2048, "type": "string" }, "dashboardLinkVisibility": { @@ -8446,6 +8433,16 @@ "content": { "$ref": "#/components/schemas/PublisherDocumentContent" }, + "createdAt": { + "description": "Time of the entity creation.", + "example": "2023-07-20 12:30", + "nullable": true, + "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}", + "type": "string" + }, + "createdBy": { + "$ref": "#/components/schemas/DeclarativeUserIdentifier" + }, "description": { "description": "Document description.", "maxLength": 10000, @@ -8457,6 +8454,16 @@ "pattern": "^(?!\\.)[.A-Za-z0-9_-]{1,255}$", "type": "string" }, + "modifiedAt": { + "description": "Time of the last entity modification.", + "example": "2023-07-20 12:30", + "nullable": true, + "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}", + "type": "string" + }, + "modifiedBy": { + "$ref": "#/components/schemas/DeclarativeUserIdentifier" + }, "period": { "$ref": "#/components/schemas/PublisherDocumentPeriod" }, @@ -8950,7 +8957,8 @@ "AUTHORIZATION_SERVER_REDIRECT_POLICY", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "example": "TIMEZONE", "type": "string" @@ -8983,6 +8991,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -9988,6 +9997,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -10194,7 +10204,8 @@ "knowledgeRecommendation", "visualizationObject", "filterContext", - "filterView" + "filterView", + "document" ], "example": "metric", "type": "string" @@ -10567,7 +10578,7 @@ "type": "string" }, "numberFormat": { - "description": "Format to be used to format the element values, the same kind of format string as the measure format. Only filled for computed attributes with a format.", + "description": "Format to be used to format the element values, the same kind of format string as the measure format. Only filled for computed attributes with a format and INT or NUMERIC data type.", "type": "string" }, "paging": { @@ -10661,7 +10672,8 @@ "knowledgeRecommendation", "visualizationObject", "filterContext", - "filterView" + "filterView", + "document" ], "example": "metric", "type": "string" @@ -11246,6 +11258,12 @@ }, "FeatureFlagsContext": { "properties": { + "controlledFeatureRollout": { + "type": "string" + }, + "dataCenter": { + "type": "string" + }, "earlyAccess": { "type": "string" }, @@ -11255,11 +11273,17 @@ }, "type": "array", "uniqueItems": true + }, + "tier": { + "type": "string" } }, "required": [ + "controlledFeatureRollout", + "dataCenter", "earlyAccess", - "earlyAccessValues" + "earlyAccessValues", + "tier" ], "type": "object" }, @@ -27265,7 +27289,7 @@ }, "customDashboardUrl": { "description": "Custom dashboard url that is going to be used in the notification. If not specified it is going to be deduced based on the context. Allowed placeholders are:\n{workspaceId}\n{dashboardId}\n{automationId}\n{asOfDate}\n", - "maxLength": 255, + "maxLength": 2048, "type": "string" }, "dashboardLinkVisibility": { @@ -27387,7 +27411,7 @@ }, "customDashboardUrl": { "description": "Custom dashboard url that is going to be used in the notification. If not specified it is going to be deduced based on the context. Allowed placeholders are:\n{workspaceId}\n{dashboardId}\n{automationId}\n{asOfDate}\n", - "maxLength": 255, + "maxLength": 2048, "type": "string" }, "dashboardLinkVisibility": { @@ -27429,6 +27453,7 @@ "IN_PLATFORM" ], "nullable": true, + "readOnly": true, "type": "string" }, "inPlatformNotification": { @@ -27540,7 +27565,7 @@ }, "customDashboardUrl": { "description": "Custom dashboard url that is going to be used in the notification. If not specified it is going to be deduced based on the context. Allowed placeholders are:\n{workspaceId}\n{dashboardId}\n{automationId}\n{asOfDate}\n", - "maxLength": 255, + "maxLength": 2048, "type": "string" }, "dashboardLinkVisibility": { @@ -27643,7 +27668,7 @@ }, "customDashboardUrl": { "description": "Custom dashboard url that is going to be used in the notification. If not specified it is going to be deduced based on the context. Allowed placeholders are:\n{workspaceId}\n{dashboardId}\n{automationId}\n{asOfDate}\n", - "maxLength": 255, + "maxLength": 2048, "type": "string" }, "dashboardLinkVisibility": { @@ -28526,7 +28551,8 @@ "AUTHORIZATION_SERVER_REDIRECT_POLICY", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -28636,7 +28662,8 @@ "AUTHORIZATION_SERVER_REDIRECT_POLICY", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -28786,7 +28813,8 @@ "AUTHORIZATION_SERVER_REDIRECT_POLICY", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -29921,6 +29949,39 @@ ], "type": "object" }, + "datasets": { + "properties": { + "data": { + "$ref": "#/components/schemas/JsonApiDatasetToManyLinkage" + } + }, + "required": [ + "data" + ], + "type": "object" + }, + "labels": { + "properties": { + "data": { + "$ref": "#/components/schemas/JsonApiLabelToManyLinkage" + } + }, + "required": [ + "data" + ], + "type": "object" + }, + "metrics": { + "properties": { + "data": { + "$ref": "#/components/schemas/JsonApiMetricToManyLinkage" + } + }, + "required": [ + "data" + ], + "type": "object" + }, "modifiedBy": { "properties": { "data": { @@ -29931,6 +29992,17 @@ "data" ], "type": "object" + }, + "visualizationObjects": { + "properties": { + "data": { + "$ref": "#/components/schemas/JsonApiVisualizationObjectToManyLinkage" + } + }, + "required": [ + "data" + ], + "type": "object" } }, "type": "object" @@ -29959,7 +30031,7 @@ "included": { "description": "Included resources", "items": { - "$ref": "#/components/schemas/JsonApiUserIdentifierOutWithLinks" + "$ref": "#/components/schemas/JsonApiPublisherDocumentOutIncludes" }, "type": "array", "uniqueItems": true @@ -29986,6 +30058,25 @@ ], "type": "object" }, + "JsonApiPublisherDocumentOutIncludes": { + "oneOf": [ + { + "$ref": "#/components/schemas/JsonApiDatasetOutWithLinks" + }, + { + "$ref": "#/components/schemas/JsonApiLabelOutWithLinks" + }, + { + "$ref": "#/components/schemas/JsonApiMetricOutWithLinks" + }, + { + "$ref": "#/components/schemas/JsonApiUserIdentifierOutWithLinks" + }, + { + "$ref": "#/components/schemas/JsonApiVisualizationObjectOutWithLinks" + } + ] + }, "JsonApiPublisherDocumentOutList": { "description": "A JSON:API document with a list of resources", "properties": { @@ -29999,7 +30090,7 @@ "included": { "description": "Included resources", "items": { - "$ref": "#/components/schemas/JsonApiUserIdentifierOutWithLinks" + "$ref": "#/components/schemas/JsonApiPublisherDocumentOutIncludes" }, "type": "array", "uniqueItems": true @@ -30393,6 +30484,11 @@ "maxLength": 10000, "type": "string" }, + "isDefault": { + "description": "Whether the backend ships this page template as a read-only default.", + "readOnly": true, + "type": "boolean" + }, "modifiedAt": { "description": "Time of the last entity modification.", "example": "2023-07-20 12:30", @@ -30419,6 +30515,7 @@ }, "required": [ "content", + "isDefault", "title", "version" ], @@ -38053,7 +38150,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -38162,7 +38260,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -41088,6 +41187,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -41402,7 +41502,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -41511,7 +41612,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -41686,7 +41788,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -41795,7 +41898,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -43771,6 +43875,25 @@ ], "type": "object" }, + "ObjectStorageRef": { + "description": "Reference to a registered ObjectStorage.", + "properties": { + "name": { + "description": "Human-readable name of the storage.", + "example": "s3-data-lake", + "type": "string" + }, + "storageId": { + "description": "Stable identifier of the storage, as returned by the ObjectStorages listing.", + "type": "string" + } + }, + "required": [ + "name", + "storageId" + ], + "type": "object" + }, "OpenAIProviderConfig": { "description": "Configuration for OpenAI provider.", "properties": { @@ -44758,9 +44881,9 @@ "type": "string" }, "storageIds": { - "description": "Set of ids of the storage instances this database instance should access.", + "description": "Set of ids of the storage instances this database instance should access. Each entry is a `storageId` from the ObjectStorages listing or, for backward compatibility, a storage name. Must contain exactly one entry.", "items": { - "description": "Set of ids of the storage instances this database instance should access.", + "description": "Set of ids of the storage instances this database instance should access. Each entry is a `storageId` from the ObjectStorages listing or, for backward compatibility, a storage name. Must contain exactly one entry.", "type": "string" }, "type": "array", @@ -46791,7 +46914,14 @@ "type": "string" }, "type": { - "description": "sdk-model object type, such as `displayForm`, `dataSet` or `measure`.", + "description": "sdk-model object type.", + "enum": [ + "insight", + "displayForm", + "dataSet", + "measure", + "attribute" + ], "type": "string" } }, @@ -49458,7 +49588,8 @@ "AUTHORIZATION_SERVER_REDIRECT_POLICY", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "example": "TIMEZONE", "type": "string" @@ -50904,9 +51035,6 @@ "TelemetryServices": { "description": "Available telemetry services.", "properties": { - "amplitude": { - "$ref": "#/components/schemas/AmplitudeService" - }, "matomo": { "$ref": "#/components/schemas/MatomoService" }, @@ -51863,6 +51991,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -51893,6 +52022,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -52190,7 +52320,7 @@ "url": { "description": "The webhook URL.", "example": "https://webhook.site/something", - "maxLength": 255, + "maxLength": 2048, "pattern": "https?\\://.*", "type": "string" } @@ -52240,7 +52370,7 @@ "url": { "description": "The webhook URL.", "example": "https://webhook.site/something", - "maxLength": 255, + "maxLength": 2048, "pattern": "https?\\://.*", "type": "string" } @@ -52646,6 +52776,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -52669,6 +52800,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -54755,7 +54887,7 @@ }, "/api/v1/actions/organization/localization/usage/users": { "get": { - "description": "(BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. Users counted in the usage entry without a language are not listed.", + "description": "(BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. An empty `value=` means no filter. No value selects the usage entry without a language.", "operationId": "organizationLocalizationUsageUsers", "parameters": [ { @@ -54864,7 +54996,7 @@ }, "/api/v1/actions/organization/localization/usage/workspaces": { "get": { - "description": "(BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one.", + "description": "(BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one. Without the value filter, a setting without a language matches too. An empty `value=` means no filter. No value selects the usage entry without a language.", "operationId": "organizationLocalizationUsageWorkspaces", "parameters": [ { @@ -57493,7 +57625,7 @@ } }, { - "description": "Requested explain type. If not specified all types are bundled in a ZIP archive.\n\n`MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info\n\n`GRPC_MODEL` - Datasets used in execution\n\n`GRPC_MODEL_SVG` - Generated SVG image of the datasets\n\n`COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query\n\n`WDF` - Workspace data filters in execution workspace context\n\n`QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL\n\n`QT_SVG` - Generated SVG image of the Query Tree\n\n`OPT_QT` - Optimized Query Tree\n\n`OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree\n\n`SQL` - Final SQL to be executed\n\n`COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets\n\n`SETTINGS` - Settings used to execute explain request\n\n`GIT` - Git properties of current build", + "description": "Requested explain type. If not specified all types are bundled in a ZIP archive.\n\n`MAQL` - MAQL Abstract Syntax Tree, execution dimensions and related info\n\n`GRPC_MODEL` - Datasets used in execution\n\n`MODEL_STATISTICS` - Physical table statistics of the datasets used in execution\n\n`GRPC_MODEL_SVG` - Generated SVG image of the datasets\n\n`COMPRESSED_GRPC_MODEL_SVG` - Generated SVG image of the model fragment used in the query\n\n`WDF` - Workspace data filters in execution workspace context\n\n`QT` - Query Tree, created from MAQL AST using Logical Data Model, contains all information needed to generate SQL\n\n`QT_SVG` - Generated SVG image of the Query Tree\n\n`OPT_QT` - Optimized Query Tree\n\n`OPT_QT_SVG` - Generated SVG image of the Optimized Query Tree\n\n`SQL` - Final SQL to be executed\n\n`COMPRESSED_SQL` - Final SQL to be executed with rolled SQL datasets\n\n`SETTINGS` - Settings used to execute explain request\n\n`GIT` - Git properties of current build", "in": "query", "name": "explainType", "required": false, @@ -57501,6 +57633,7 @@ "enum": [ "MAQL", "GRPC_MODEL", + "MODEL_STATISTICS", "GRPC_MODEL_SVG", "WDF", "QT", @@ -57534,7 +57667,7 @@ "application/sql": {}, "application/zip": { "schema": { - "description": "ZIP with MAQL, GRPC_MODEL, GRPC_MODEL_SVG, WDF, QT, QT_SVG, OPT_QT, OPT_QT_SVG and SQL files", + "description": "ZIP with MAQL, GRPC_MODEL, MODEL_STATISTICS, GRPC_MODEL_SVG, WDF, QT, QT_SVG, OPT_QT, OPT_QT_SVG and SQL files", "format": "binary", "type": "string" } @@ -60535,7 +60668,7 @@ }, "/api/v1/actions/workspaces/{workspaceId}/localization/usage/users": { "get": { - "description": "(BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one.", + "description": "(BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one. An empty `value=` means no filter. No value selects the usage entry without a language.", "operationId": "workspaceLocalizationUsageUsers", "parameters": [ { @@ -75972,7 +76105,7 @@ }, { "description": "Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL).\n\n__WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together.", - "example": "createdBy,modifiedBy", + "example": "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", "explode": false, "in": "query", "name": "include", @@ -75981,6 +76114,10 @@ "items": { "enum": [ "userIdentifiers", + "visualizationObjects", + "labels", + "datasets", + "metrics", "createdBy", "modifiedBy", "ALL" @@ -76076,7 +76213,7 @@ }, { "description": "Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL).\n\n__WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together.", - "example": "createdBy,modifiedBy", + "example": "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", "explode": false, "in": "query", "name": "include", @@ -76085,6 +76222,10 @@ "items": { "enum": [ "userIdentifiers", + "visualizationObjects", + "labels", + "datasets", + "metrics", "createdBy", "modifiedBy", "ALL" @@ -76157,9 +76298,9 @@ "document-controller" ], "x-gdc-security-info": { - "description": "Contains minimal permission level required to manage this object type.", + "description": "Contains minimal permission level required to create Documents", "permissions": [ - "MANAGE" + "CREATE_DOCUMENT" ] } } @@ -76197,7 +76338,7 @@ "document-controller" ], "x-gdc-security-info": { - "description": "Contains minimal permission level required to manage this object type.", + "description": "Contains minimal permission level required to update and delete Documents: MANAGE, or VIEW for the Document's creator.", "permissions": [ "MANAGE" ] @@ -76233,7 +76374,7 @@ }, { "description": "Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL).\n\n__WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together.", - "example": "createdBy,modifiedBy", + "example": "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", "explode": false, "in": "query", "name": "include", @@ -76242,6 +76383,10 @@ "items": { "enum": [ "userIdentifiers", + "visualizationObjects", + "labels", + "datasets", + "metrics", "createdBy", "modifiedBy", "ALL" @@ -76344,7 +76489,7 @@ }, { "description": "Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL).\n\n__WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together.", - "example": "createdBy,modifiedBy", + "example": "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", "explode": false, "in": "query", "name": "include", @@ -76353,6 +76498,10 @@ "items": { "enum": [ "userIdentifiers", + "visualizationObjects", + "labels", + "datasets", + "metrics", "createdBy", "modifiedBy", "ALL" @@ -76403,7 +76552,7 @@ "document-controller" ], "x-gdc-security-info": { - "description": "Contains minimal permission level required to manage this object type.", + "description": "Contains minimal permission level required to update and delete Documents: MANAGE, or VIEW for the Document's creator.", "permissions": [ "MANAGE" ] @@ -76439,7 +76588,7 @@ }, { "description": "Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL).\n\n__WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together.", - "example": "createdBy,modifiedBy", + "example": "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", "explode": false, "in": "query", "name": "include", @@ -76448,6 +76597,10 @@ "items": { "enum": [ "userIdentifiers", + "visualizationObjects", + "labels", + "datasets", + "metrics", "createdBy", "modifiedBy", "ALL" @@ -76498,7 +76651,7 @@ "document-controller" ], "x-gdc-security-info": { - "description": "Contains minimal permission level required to manage this object type.", + "description": "Contains minimal permission level required to update and delete Documents: MANAGE, or VIEW for the Document's creator.", "permissions": [ "MANAGE" ] @@ -81470,6 +81623,7 @@ }, "/api/v1/entities/workspaces/{workspaceId}/pageTemplates": { "get": { + "description": "Lists the default page templates first, in a fixed order, then the workspace page templates. Paging counts both as one sequence. `filter` and `sort` apply to the workspace page templates only; the default page templates are always listed first and in full, and `isDefault` is not filterable. The default page templates are listed only with `origin=ALL`.", "operationId": "getAllEntities@PageTemplates", "parameters": [ { @@ -90165,7 +90319,7 @@ "x-gdc-security-info": { "description": "Permissions required to read the layout.", "permissions": [ - "ANALYZE" + "MANAGE" ] } }, @@ -90260,7 +90414,7 @@ "x-gdc-security-info": { "description": "Permissions to read the analytics layout.", "permissions": [ - "ANALYZE" + "MANAGE" ] } }, @@ -90301,7 +90455,7 @@ "x-gdc-security-info": { "description": "Permissions to modify the analytics layout.", "permissions": [ - "ANALYZE" + "MANAGE" ] } } diff --git a/schemas/gooddata-automation-client.json b/schemas/gooddata-automation-client.json index 5e45a8462..8ecc69af9 100644 --- a/schemas/gooddata-automation-client.json +++ b/schemas/gooddata-automation-client.json @@ -4502,7 +4502,7 @@ "url": { "description": "The webhook URL.", "example": "https://webhook.site/something", - "maxLength": 255, + "maxLength": 2048, "pattern": "https?\\://.*", "type": "string" } diff --git a/schemas/gooddata-metadata-client.json b/schemas/gooddata-metadata-client.json index 0336e3246..2d6dfe0ce 100644 --- a/schemas/gooddata-metadata-client.json +++ b/schemas/gooddata-metadata-client.json @@ -687,33 +687,6 @@ ], "type": "object" }, - "AmplitudeService": { - "description": "Amplitude service.", - "properties": { - "aiProjectApiKey": { - "description": "API key for AI project - intended for frontend use.", - "type": "string" - }, - "endpoint": { - "description": "Amplitude endpoint URL.", - "type": "string" - }, - "gdCommonApiKey": { - "description": "API key for GoodData common project - used by backend.", - "type": "string" - }, - "reportingEndpoint": { - "description": "Optional reporting endpoint for proxying telemetry events.", - "type": "string" - } - }, - "required": [ - "aiProjectApiKey", - "endpoint", - "gdCommonApiKey" - ], - "type": "object" - }, "AnalyticsCatalogCreatedBy": { "description": "List of users who created catalog objects in the workspace hierarchy.", "properties": { @@ -6219,7 +6192,7 @@ }, "customDashboardUrl": { "description": "Custom dashboard url that is going to be used in the notification. If not specified it is going to be deduced based on the context. Allowed placeholders are:\n{workspaceId}\n{dashboardId}\n{automationId}\n{asOfDate}\n", - "maxLength": 255, + "maxLength": 2048, "type": "string" }, "dashboardLinkVisibility": { @@ -6586,6 +6559,16 @@ "content": { "$ref": "#/components/schemas/PublisherDocumentContent" }, + "createdAt": { + "description": "Time of the entity creation.", + "example": "2023-07-20 12:30", + "nullable": true, + "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}", + "type": "string" + }, + "createdBy": { + "$ref": "#/components/schemas/DeclarativeUserIdentifier" + }, "description": { "description": "Document description.", "maxLength": 10000, @@ -6597,6 +6580,16 @@ "pattern": "^(?!\\.)[.A-Za-z0-9_-]{1,255}$", "type": "string" }, + "modifiedAt": { + "description": "Time of the last entity modification.", + "example": "2023-07-20 12:30", + "nullable": true, + "pattern": "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}", + "type": "string" + }, + "modifiedBy": { + "$ref": "#/components/schemas/DeclarativeUserIdentifier" + }, "period": { "$ref": "#/components/schemas/PublisherDocumentPeriod" }, @@ -7090,7 +7083,8 @@ "AUTHORIZATION_SERVER_REDIRECT_POLICY", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "example": "TIMEZONE", "type": "string" @@ -7123,6 +7117,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -8112,6 +8107,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -8281,7 +8277,8 @@ "knowledgeRecommendation", "visualizationObject", "filterContext", - "filterView" + "filterView", + "document" ], "example": "metric", "type": "string" @@ -8404,7 +8401,8 @@ "knowledgeRecommendation", "visualizationObject", "filterContext", - "filterView" + "filterView", + "document" ], "example": "metric", "type": "string" @@ -8636,6 +8634,12 @@ }, "FeatureFlagsContext": { "properties": { + "controlledFeatureRollout": { + "type": "string" + }, + "dataCenter": { + "type": "string" + }, "earlyAccess": { "type": "string" }, @@ -8645,11 +8649,17 @@ }, "type": "array", "uniqueItems": true + }, + "tier": { + "type": "string" } }, "required": [ + "controlledFeatureRollout", + "dataCenter", "earlyAccess", - "earlyAccessValues" + "earlyAccessValues", + "tier" ], "type": "object" }, @@ -23496,7 +23506,7 @@ }, "customDashboardUrl": { "description": "Custom dashboard url that is going to be used in the notification. If not specified it is going to be deduced based on the context. Allowed placeholders are:\n{workspaceId}\n{dashboardId}\n{automationId}\n{asOfDate}\n", - "maxLength": 255, + "maxLength": 2048, "type": "string" }, "dashboardLinkVisibility": { @@ -23618,7 +23628,7 @@ }, "customDashboardUrl": { "description": "Custom dashboard url that is going to be used in the notification. If not specified it is going to be deduced based on the context. Allowed placeholders are:\n{workspaceId}\n{dashboardId}\n{automationId}\n{asOfDate}\n", - "maxLength": 255, + "maxLength": 2048, "type": "string" }, "dashboardLinkVisibility": { @@ -23660,6 +23670,7 @@ "IN_PLATFORM" ], "nullable": true, + "readOnly": true, "type": "string" }, "inPlatformNotification": { @@ -23771,7 +23782,7 @@ }, "customDashboardUrl": { "description": "Custom dashboard url that is going to be used in the notification. If not specified it is going to be deduced based on the context. Allowed placeholders are:\n{workspaceId}\n{dashboardId}\n{automationId}\n{asOfDate}\n", - "maxLength": 255, + "maxLength": 2048, "type": "string" }, "dashboardLinkVisibility": { @@ -23874,7 +23885,7 @@ }, "customDashboardUrl": { "description": "Custom dashboard url that is going to be used in the notification. If not specified it is going to be deduced based on the context. Allowed placeholders are:\n{workspaceId}\n{dashboardId}\n{automationId}\n{asOfDate}\n", - "maxLength": 255, + "maxLength": 2048, "type": "string" }, "dashboardLinkVisibility": { @@ -24757,7 +24768,8 @@ "AUTHORIZATION_SERVER_REDIRECT_POLICY", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -24867,7 +24879,8 @@ "AUTHORIZATION_SERVER_REDIRECT_POLICY", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -25017,7 +25030,8 @@ "AUTHORIZATION_SERVER_REDIRECT_POLICY", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -26122,6 +26136,39 @@ ], "type": "object" }, + "datasets": { + "properties": { + "data": { + "$ref": "#/components/schemas/JsonApiDatasetToManyLinkage" + } + }, + "required": [ + "data" + ], + "type": "object" + }, + "labels": { + "properties": { + "data": { + "$ref": "#/components/schemas/JsonApiLabelToManyLinkage" + } + }, + "required": [ + "data" + ], + "type": "object" + }, + "metrics": { + "properties": { + "data": { + "$ref": "#/components/schemas/JsonApiMetricToManyLinkage" + } + }, + "required": [ + "data" + ], + "type": "object" + }, "modifiedBy": { "properties": { "data": { @@ -26132,6 +26179,17 @@ "data" ], "type": "object" + }, + "visualizationObjects": { + "properties": { + "data": { + "$ref": "#/components/schemas/JsonApiVisualizationObjectToManyLinkage" + } + }, + "required": [ + "data" + ], + "type": "object" } }, "type": "object" @@ -26160,7 +26218,7 @@ "included": { "description": "Included resources", "items": { - "$ref": "#/components/schemas/JsonApiUserIdentifierOutWithLinks" + "$ref": "#/components/schemas/JsonApiPublisherDocumentOutIncludes" }, "type": "array", "uniqueItems": true @@ -26187,6 +26245,25 @@ ], "type": "object" }, + "JsonApiPublisherDocumentOutIncludes": { + "oneOf": [ + { + "$ref": "#/components/schemas/JsonApiDatasetOutWithLinks" + }, + { + "$ref": "#/components/schemas/JsonApiLabelOutWithLinks" + }, + { + "$ref": "#/components/schemas/JsonApiMetricOutWithLinks" + }, + { + "$ref": "#/components/schemas/JsonApiUserIdentifierOutWithLinks" + }, + { + "$ref": "#/components/schemas/JsonApiVisualizationObjectOutWithLinks" + } + ] + }, "JsonApiPublisherDocumentOutList": { "description": "A JSON:API document with a list of resources", "properties": { @@ -26200,7 +26277,7 @@ "included": { "description": "Included resources", "items": { - "$ref": "#/components/schemas/JsonApiUserIdentifierOutWithLinks" + "$ref": "#/components/schemas/JsonApiPublisherDocumentOutIncludes" }, "type": "array", "uniqueItems": true @@ -26594,6 +26671,11 @@ "maxLength": 10000, "type": "string" }, + "isDefault": { + "description": "Whether the backend ships this page template as a read-only default.", + "readOnly": true, + "type": "boolean" + }, "modifiedAt": { "description": "Time of the last entity modification.", "example": "2023-07-20 12:30", @@ -26620,6 +26702,7 @@ }, "required": [ "content", + "isDefault", "title", "version" ], @@ -34254,7 +34337,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -34363,7 +34447,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -37289,6 +37374,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -37603,7 +37689,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -37712,7 +37799,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -37887,7 +37975,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -37996,7 +38085,8 @@ "ENABLE_TIMEZONE_CHANGE", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "type": "string" } @@ -42073,7 +42163,14 @@ "type": "string" }, "type": { - "description": "sdk-model object type, such as `displayForm`, `dataSet` or `measure`.", + "description": "sdk-model object type.", + "enum": [ + "insight", + "displayForm", + "dataSet", + "measure", + "attribute" + ], "type": "string" } }, @@ -44476,7 +44573,8 @@ "AUTHORIZATION_SERVER_REDIRECT_POLICY", "DEFAULT_VISUALIZATION_VISIBILITY", "DEFAULT_METRIC_VISIBILITY", - "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE" + "GRANT_MANAGE_VISUALIZATIONS_WITH_ANALYZE", + "QUERY_ENGINE" ], "example": "TIMEZONE", "type": "string" @@ -45326,9 +45424,6 @@ "TelemetryServices": { "description": "Available telemetry services.", "properties": { - "amplitude": { - "$ref": "#/components/schemas/AmplitudeService" - }, "matomo": { "$ref": "#/components/schemas/MatomoService" }, @@ -45672,6 +45767,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -45702,6 +45798,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -45965,7 +46062,7 @@ "url": { "description": "The webhook URL.", "example": "https://webhook.site/something", - "maxLength": 255, + "maxLength": 2048, "pattern": "https?\\://.*", "type": "string" } @@ -46160,6 +46257,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -46183,6 +46281,7 @@ "MANAGE_VISUALIZATIONS", "CREATE_VISUALIZATION", "CREATE_COMPUTED_ATTRIBUTE", + "CREATE_DOCUMENT", "VIEW" ], "type": "string" @@ -46839,7 +46938,7 @@ }, "/api/v1/actions/organization/localization/usage/users": { "get": { - "description": "(BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. Users counted in the usage entry without a language are not listed.", + "description": "(BETA) Lists the users behind the counts of the organization localization usage, sorted by name. Users without a name come last. Users count under the value they get in the organization. That value depends on the workspace, so only the settings that users set themselves match. Only the source USER returns users. Without the setting filter, a user matches when any of the display, metadata and data language settings matches. An empty `value=` means no filter. No value selects the usage entry without a language.", "operationId": "organizationLocalizationUsageUsers", "parameters": [ { @@ -46948,7 +47047,7 @@ }, "/api/v1/actions/organization/localization/usage/workspaces": { "get": { - "description": "(BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one.", + "description": "(BETA) Lists the workspaces behind the counts of the organization localization usage, sorted by name. Without the setting filter, a workspace matches when any of the display, metadata and data language settings matches, and its source is the strongest one. Without the value filter, a setting without a language matches too. An empty `value=` means no filter. No value selects the usage entry without a language.", "operationId": "organizationLocalizationUsageWorkspaces", "parameters": [ { @@ -48898,7 +48997,7 @@ }, "/api/v1/actions/workspaces/{workspaceId}/localization/usage/users": { "get": { - "description": "(BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one.", + "description": "(BETA) Lists the workspace members behind the counts of the workspace localization usage, sorted by name. Users without a name come last. Members count under the value they get in the workspace: their own setting, otherwise the value of the workspace. So every source can match. Without the setting filter, a member matches when any of the display, metadata and data language settings matches. Its source is then the strongest one. An empty `value=` means no filter. No value selects the usage entry without a language.", "operationId": "workspaceLocalizationUsageUsers", "parameters": [ { @@ -63479,7 +63578,7 @@ }, { "description": "Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL).\n\n__WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together.", - "example": "createdBy,modifiedBy", + "example": "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", "explode": false, "in": "query", "name": "include", @@ -63488,6 +63587,10 @@ "items": { "enum": [ "userIdentifiers", + "visualizationObjects", + "labels", + "datasets", + "metrics", "createdBy", "modifiedBy", "ALL" @@ -63583,7 +63686,7 @@ }, { "description": "Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL).\n\n__WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together.", - "example": "createdBy,modifiedBy", + "example": "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", "explode": false, "in": "query", "name": "include", @@ -63592,6 +63695,10 @@ "items": { "enum": [ "userIdentifiers", + "visualizationObjects", + "labels", + "datasets", + "metrics", "createdBy", "modifiedBy", "ALL" @@ -63664,9 +63771,9 @@ "document-controller" ], "x-gdc-security-info": { - "description": "Contains minimal permission level required to manage this object type.", + "description": "Contains minimal permission level required to create Documents", "permissions": [ - "MANAGE" + "CREATE_DOCUMENT" ] } } @@ -63704,7 +63811,7 @@ "document-controller" ], "x-gdc-security-info": { - "description": "Contains minimal permission level required to manage this object type.", + "description": "Contains minimal permission level required to update and delete Documents: MANAGE, or VIEW for the Document's creator.", "permissions": [ "MANAGE" ] @@ -63740,7 +63847,7 @@ }, { "description": "Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL).\n\n__WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together.", - "example": "createdBy,modifiedBy", + "example": "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", "explode": false, "in": "query", "name": "include", @@ -63749,6 +63856,10 @@ "items": { "enum": [ "userIdentifiers", + "visualizationObjects", + "labels", + "datasets", + "metrics", "createdBy", "modifiedBy", "ALL" @@ -63851,7 +63962,7 @@ }, { "description": "Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL).\n\n__WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together.", - "example": "createdBy,modifiedBy", + "example": "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", "explode": false, "in": "query", "name": "include", @@ -63860,6 +63971,10 @@ "items": { "enum": [ "userIdentifiers", + "visualizationObjects", + "labels", + "datasets", + "metrics", "createdBy", "modifiedBy", "ALL" @@ -63910,7 +64025,7 @@ "document-controller" ], "x-gdc-security-info": { - "description": "Contains minimal permission level required to manage this object type.", + "description": "Contains minimal permission level required to update and delete Documents: MANAGE, or VIEW for the Document's creator.", "permissions": [ "MANAGE" ] @@ -63946,7 +64061,7 @@ }, { "description": "Array of included collections or individual relationships. Includes are separated by commas (e.g. include=entity1s,entity2s). Collection include represents the inclusion of every relationship between this entity and the given collection. Relationship include represents the inclusion of the particular relationships only. If single parameter \"ALL\" is present, all possible includes are used (include=ALL).\n\n__WARNING:__ Individual include types (collection, relationship or ALL) cannot be combined together.", - "example": "createdBy,modifiedBy", + "example": "createdBy,modifiedBy,visualizationObjects,labels,datasets,metrics", "explode": false, "in": "query", "name": "include", @@ -63955,6 +64070,10 @@ "items": { "enum": [ "userIdentifiers", + "visualizationObjects", + "labels", + "datasets", + "metrics", "createdBy", "modifiedBy", "ALL" @@ -64005,7 +64124,7 @@ "document-controller" ], "x-gdc-security-info": { - "description": "Contains minimal permission level required to manage this object type.", + "description": "Contains minimal permission level required to update and delete Documents: MANAGE, or VIEW for the Document's creator.", "permissions": [ "MANAGE" ] @@ -68977,6 +69096,7 @@ }, "/api/v1/entities/workspaces/{workspaceId}/pageTemplates": { "get": { + "description": "Lists the default page templates first, in a fixed order, then the workspace page templates. Paging counts both as one sequence. `filter` and `sort` apply to the workspace page templates only; the default page templates are always listed first and in full, and `isDefault` is not filterable. The default page templates are listed only with `origin=ALL`.", "operationId": "getAllEntities@PageTemplates", "parameters": [ { @@ -77672,7 +77792,7 @@ "x-gdc-security-info": { "description": "Permissions required to read the layout.", "permissions": [ - "ANALYZE" + "MANAGE" ] } }, @@ -77767,7 +77887,7 @@ "x-gdc-security-info": { "description": "Permissions to read the analytics layout.", "permissions": [ - "ANALYZE" + "MANAGE" ] } }, @@ -77808,7 +77928,7 @@ "x-gdc-security-info": { "description": "Permissions to modify the analytics layout.", "permissions": [ - "ANALYZE" + "MANAGE" ] } } From 5a2eebdee8a0cf304c0844c0868ebb401d955764 Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Tue, 3 Nov 2026 14:09:00 +0100 Subject: [PATCH 02/12] test(gooddata-sdk): read CREATE_DOCUMENT permission assignments Assert that a declarative single-workspace permission and a workspace hierarchy permission named CREATE_DOCUMENT survive the round trip: from_dict reads the assignment, to_api builds the client model, and to_dict gives back the input. The regenerated client allows the value, and the validation tests would otherwise only cover it through the enum sweep, without a typed read of the assignment. The shared declarative_workspace_permissions.json fixture stays as it is: the recorded PUT tests replay it, and adding the value there would change their cassettes and the permission counts they assert. jira: LX-3447 risk: nonprod Co-Authored-By: Claude Opus 5.5 --- .../tests/catalog/test_catalog_permission.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/gooddata-sdk/tests/catalog/test_catalog_permission.py b/packages/gooddata-sdk/tests/catalog/test_catalog_permission.py index cafdff2ab..e30e78733 100644 --- a/packages/gooddata-sdk/tests/catalog/test_catalog_permission.py +++ b/packages/gooddata-sdk/tests/catalog/test_catalog_permission.py @@ -133,10 +133,20 @@ def _rollback_dashboard_permissions(sdk: GoodDataSdk) -> None: def test_single_workspace_permission_validation(test_config): _validation_helper(CatalogDeclarativeSingleWorkspacePermission, "name") + data = {"name": "CREATE_DOCUMENT", "assignee": {"id": "demo2", "type": "user"}} + permission = CatalogDeclarativeSingleWorkspacePermission.from_dict(data) + assert permission.name == "CREATE_DOCUMENT" + assert permission.to_api().name == "CREATE_DOCUMENT" + assert permission.to_dict(camel_case=True) == data def test_workspace_hierarchy_permission(test_config): _validation_helper(CatalogDeclarativeWorkspaceHierarchyPermission, "name") + data = {"name": "CREATE_DOCUMENT", "assignee": {"id": "demo2", "type": "user"}} + permission = CatalogDeclarativeWorkspaceHierarchyPermission.from_dict(data) + assert permission.name == "CREATE_DOCUMENT" + assert permission.to_api().name == "CREATE_DOCUMENT" + assert permission.to_dict(camel_case=True) == data def test_data_source_permission(test_config): From 1e22129ed1581ee10c26f4359c89008b986eea9d Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Tue, 3 Nov 2026 14:36:38 +0100 Subject: [PATCH 03/12] fix(gooddata-api-client): resolve discriminated oneOf via python names Building a model whose property is a discriminated oneOf, such as the Publisher document layout node, failed when the input used python names: `PublisherDocumentColumn._from_openapi_data() missing 1 required positional argument: 'children'`, whatever the node's `type` was. In python-name mode (`_spec_property_naming=False`) `get_possible_classes` replaced a discriminated composed model by all its members without reading the discriminator. `attempt_convert_item` then tried them in order, and the first member missing a required argument raised a plain `TypeError`, which it does not catch. With JSON names the composed class stays the only candidate and `_new_from_openapi_data` dispatches on the discriminator. `Base.to_api()` in the SDK builds client models with `camel_case=False` (python names), so a discriminated composed model must resolve through its discriminator in that mode too. `get_possible_classes` now keeps such a model as the single candidate in both modes. Discriminated `ModelNormal` classes and undiscriminated unions are unchanged, and a member instance is still accepted, since `is_valid_type` already walks the discriminator map. jira: LX-3447 risk: low Co-Authored-By: Claude Opus 5.5 --- .../custom_templates/model_utils.mustache | 7 +++ .../gooddata_api_client/model_utils.py | 7 +++ .../unit_tests/test_composed_oneof_unions.py | 52 +++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/.openapi-generator/custom_templates/model_utils.mustache b/.openapi-generator/custom_templates/model_utils.mustache index 223a4c55b..a73fe96ec 100644 --- a/.openapi-generator/custom_templates/model_utils.mustache +++ b/.openapi-generator/custom_templates/model_utils.mustache @@ -884,6 +884,13 @@ def get_possible_classes(cls, from_server_context): if from_server_context: return possible_classes if hasattr(cls, 'discriminator') and cls.discriminator is not None: + if issubclass(cls, ModelComposed): + # A discriminated oneOf must stay a single candidate so that + # _new_from_openapi_data dispatches on the discriminator value. + # Listing its members instead makes attempt_convert_item try each + # in turn, and a member missing a required argument raises a + # plain TypeError, which that function does not catch. + return possible_classes possible_classes = [] possible_classes.extend(get_discriminated_classes(cls)) elif issubclass(cls, ModelComposed): diff --git a/gooddata-api-client/gooddata_api_client/model_utils.py b/gooddata-api-client/gooddata_api_client/model_utils.py index 8340bc084..8663eaee8 100644 --- a/gooddata-api-client/gooddata_api_client/model_utils.py +++ b/gooddata-api-client/gooddata_api_client/model_utils.py @@ -1226,6 +1226,13 @@ def get_possible_classes(cls, from_server_context): if from_server_context: return possible_classes if hasattr(cls, 'discriminator') and cls.discriminator is not None: + if issubclass(cls, ModelComposed): + # A discriminated oneOf must stay a single candidate so that + # _new_from_openapi_data dispatches on the discriminator value. + # Listing its members instead makes attempt_convert_item try each + # in turn, and a member missing a required argument raises a + # plain TypeError, which that function does not catch. + return possible_classes possible_classes = [] possible_classes.extend(get_discriminated_classes(cls)) elif issubclass(cls, ModelComposed): diff --git a/packages/gooddata-sdk/tests/catalog/unit_tests/test_composed_oneof_unions.py b/packages/gooddata-sdk/tests/catalog/unit_tests/test_composed_oneof_unions.py index 7e7a05897..5119432ad 100644 --- a/packages/gooddata-sdk/tests/catalog/unit_tests/test_composed_oneof_unions.py +++ b/packages/gooddata-sdk/tests/catalog/unit_tests/test_composed_oneof_unions.py @@ -23,7 +23,12 @@ from __future__ import annotations +from typing import Any + import pytest +from gooddata_api_client.model.declarative_publisher_document_page_template import ( + DeclarativePublisherDocumentPageTemplate, +) from gooddata_api_client.model.json_api_llm_provider_in_attributes_provider_config import ( JsonApiLlmProviderInAttributesProviderConfig, ) @@ -177,3 +182,50 @@ def test_union_helpers_tolerate_a_non_model_member(union_helper, monkeypatch) -> # Must not raise, and must still report what the real members declare. assert union_helper(model, "type") + + +_TEXT = {"type": "text", "id": "t1", "markdown": "Hello"} +_ROW = {"type": "row", "children": [_TEXT]} +_COLUMN = {"type": "column", "children": [_TEXT, _ROW]} + + +def _page_template_from_python_names(layout: dict[str, Any]) -> DeclarativePublisherDocumentPageTemplate: + """Builds a page template the way `Base.to_api()` does: python names, `camel_case=False`.""" + return DeclarativePublisherDocumentPageTemplate.from_dict( + {"id": "pt", "title": "PT", "version": "1", "content": {"layout": layout}}, + camel_case=False, + ) + + +@pytest.mark.parametrize("layout", [_TEXT, _ROW, _COLUMN], ids=["text", "row", "column"]) +def test_layout_node_resolves_from_python_names(layout: dict[str, Any]) -> None: + """A discriminated composed model must dispatch on `type`, not try every member. + + `PublisherDocumentLayoutNode` is a `oneOf` with a `type` discriminator. Built + from python names, it must resolve to the member `type` names; trying the + members in turn fails on the first one whose required arguments are missing. + """ + template = _page_template_from_python_names(layout) + + assert template.to_dict(camel_case=True)["content"]["layout"] == layout + + +def test_text_layout_node_keeps_its_fields_from_python_names() -> None: + template = _page_template_from_python_names(_TEXT) + + assert template.content.layout.markdown == "Hello" + + +def test_nested_layout_nodes_resolve_from_python_names() -> None: + template = _page_template_from_python_names(_COLUMN) + + text, row = template.content.layout.children + assert text.markdown == "Hello" + assert row.children[0].markdown == "Hello" + + +def test_image_layout_node_maps_python_names_to_json_names() -> None: + template = _page_template_from_python_names({"type": "image", "id": "i1", "alt_text": "A chart"}) + + layout = template.to_dict(camel_case=True)["content"]["layout"] + assert layout == {"type": "image", "id": "i1", "altText": "A chart"} From 7d65ad8c1157c60f5502971544edf10982f2b969 Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Fri, 6 Nov 2026 13:38:02 +0100 Subject: [PATCH 04/12] feat(gooddata-sdk): write keyword attributes under client names The generated client names an attribute whose API name is a Python keyword with a leading underscore (`from` becomes `_from`), while an attrs class can only spell it with a trailing one (`from_`). `Base._get_snake_dict` used `attrs.asdict`, which keeps the attrs name, so the client took `from_` as an unknown extra property and the request body silently lacked `from`. `_get_snake_dict` now walks attrs fields itself and writes `_` under `_` at every depth, keeping the old filtering of None and private attributes. Only attrs field names are renamed: keys inside a `dict` value, such as an analytics object's opaque `content`, are user JSON and pass untouched. `to_dict`, `to_api` and the workspace layout's `to_api(include_nested_structures)` all go through it. No SDK attribute is named this way yet; the publisher document period is the first. jira: LX-3447 risk: low Co-Authored-By: Claude Opus 5.5 --- .../src/gooddata_sdk/catalog/base.py | 41 +++++++++-- .../unit_tests/test_base_snake_dict.py | 69 +++++++++++++++++++ 2 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 packages/gooddata-sdk/tests/catalog/unit_tests/test_base_snake_dict.py diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/base.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/base.py index ffcf495e4..fb98b2b6e 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/base.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/base.py @@ -2,9 +2,10 @@ from __future__ import annotations import builtins +import keyword from typing import Any, TypeVar -from attrs import Attribute, asdict, define, field +from attrs import Attribute, define, field, fields, has from cattrs import structure from gooddata_sdk.utils import AllPagedEntities @@ -24,6 +25,17 @@ def value_in_allowed(instance: type[Base], attribute: Attribute, value: str, cli ) +def _client_attribute_name(name: str) -> str: + """ + Returns the generated client's attribute name for an attrs attribute name. + + The client prefixes a keyword-named attribute with an underscore (``_from``); attrs code suffixes it (``from_``). + """ + if name.endswith("_") and keyword.iskeyword(name[:-1]): + return f"_{name[:-1]}" + return name + + @define class Base: @classmethod @@ -57,9 +69,30 @@ def _is_attribute_private(attribute: Attribute) -> bool: return attribute.name.startswith("_") def _get_snake_dict(self) -> dict[str, Any]: - return asdict( - self, filter=lambda attribute, value: value is not None and not self._is_attribute_private(attribute) - ) + """ + Converts object into a snake_case dictionary keyed by the generated client's attribute names. + + Attributes that are None or private are left out at every depth. An attribute named after a Python keyword + plus a trailing underscore (``from_``) is written under the client's name for it (``_from``); keys inside a + ``dict`` value are user data and are never renamed. + """ + return self._snake_value(self) + + @classmethod + def _snake_value(cls, value: Any) -> Any: + if has(type(value)): + dictionary: dict[str, Any] = {} + for attribute in fields(type(value)): + attribute_value = getattr(value, attribute.name) + if attribute_value is None or cls._is_attribute_private(attribute): + continue + dictionary[_client_attribute_name(attribute.name)] = cls._snake_value(attribute_value) + return dictionary + if isinstance(value, dict): + return {key: cls._snake_value(item) for key, item in value.items()} + if isinstance(value, (list, tuple, set, frozenset)): + return [cls._snake_value(item) for item in value] + return value @staticmethod def client_class() -> Any: diff --git a/packages/gooddata-sdk/tests/catalog/unit_tests/test_base_snake_dict.py b/packages/gooddata-sdk/tests/catalog/unit_tests/test_base_snake_dict.py new file mode 100644 index 000000000..434c3a655 --- /dev/null +++ b/packages/gooddata-sdk/tests/catalog/unit_tests/test_base_snake_dict.py @@ -0,0 +1,69 @@ +# (C) 2026 GoodData Corporation +"""Unit test: ``Base`` writes keyword-named attributes under the generated client's names. + +The generated client names an attribute whose API name is a Python keyword with a +leading underscore (``from`` becomes ``_from``), while an attrs class names it with a +trailing one (``from_``). Only attrs field names are renamed; keys of a ``dict`` value +are user data and pass through as they are. +""" + +from __future__ import annotations + +from typing import Any + +from attrs import define, field +from gooddata_sdk.catalog.base import Base + + +@define(kw_only=True) +class _Range(Base): + from_: str + to: str + + +@define(kw_only=True) +class _Holder(Base): + from_: int + range: _Range + ranges: list[_Range] = field(factory=list) + content: dict[str, Any] = field(factory=dict) + note: str | None = None + + +def test_top_level_keyword_attribute_is_written_as_client_name() -> None: + holder = _Holder(from_=-1, range=_Range(from_="2026-01-01", to="2026-01-31")) + + snake = holder.to_dict(camel_case=False) + + assert snake["_from"] == -1 + assert "from_" not in snake + + +def test_nested_keyword_attribute_is_written_as_client_name() -> None: + holder = _Holder( + from_=-1, + range=_Range(from_="2026-01-01", to="2026-01-31"), + ranges=[_Range(from_="2026-02-01", to="2026-02-28")], + ) + + snake = holder.to_dict(camel_case=False) + + assert snake["range"] == {"_from": "2026-01-01", "to": "2026-01-31"} + assert snake["ranges"] == [{"_from": "2026-02-01", "to": "2026-02-28"}] + + +def test_dict_value_keys_are_not_renamed() -> None: + content = {"class_": 1, "from_": {"in_": [{"is_": True}]}} + holder = _Holder(from_=0, range=_Range(from_="a", to="b"), content=content) + + snake = holder.to_dict(camel_case=False) + + assert snake["content"] == content + + +def test_none_attributes_are_left_out() -> None: + holder = _Holder(from_=0, range=_Range(from_="a", to="b")) + + snake = holder.to_dict(camel_case=False) + + assert "note" not in snake From 554a5cf62a16413707d545bf079f901ccaa93856 Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Tue, 3 Nov 2026 14:44:51 +0100 Subject: [PATCH 05/12] feat(gooddata-sdk): model publisher documents in the analytics layer Add CatalogDeclarativePublisherDocument, CatalogDeclarativePublisherDocumentTemplate and CatalogDeclarativePublisherDocumentPageTemplate, exported from gooddata_sdk, and the documents, document_templates and page_templates lists on CatalogDeclarativeAnalyticsLayer. A layout read from the API or a dict now keeps its Publisher documents, document templates and page templates through to_api() instead of dropping them. A document's period is the typed CatalogPublisherDocumentPeriod, a union of CatalogAbsolutePublisherDocumentPeriod (ISO dates) and CatalogRelativePublisherDocumentPeriod (offsets in granularity units), all three exported from gooddata_sdk. A structure hook on the global converter dispatches on type, the way dashboard permissions do, so nested reads through the analytics and workspace layouts are typed too. Without it, a read handed back the generated client's names and types (_from, datetime.date). The keyword field is from_, which Base writes as the client's _from, so the request body carries from. Content stays an opaque dict, so keys the SDK does not model survive the round trip. The document carries the created/modified author fields through CatalogAnalyticsBaseMeta, like memory items. The templates carry no author fields, because the layout API exposes none on them. reports, reportTemplates, reportPageLayouts and computedAttributes are still not modelled in the analytics layer, until LX-3244. jira: LX-3447 risk: low Co-Authored-By: Claude Opus 5.5 --- .../gooddata-sdk/src/gooddata_sdk/__init__.py | 18 ++ .../analytics_model/analytics_model.py | 102 +++++++++ .../test_declarative_analytics_documents.py | 216 ++++++++++++++++++ 3 files changed, 336 insertions(+) create mode 100644 packages/gooddata-sdk/tests/catalog/unit_tests/test_declarative_analytics_documents.py diff --git a/packages/gooddata-sdk/src/gooddata_sdk/__init__.py b/packages/gooddata-sdk/src/gooddata_sdk/__init__.py index eb049fcb5..93567b214 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/__init__.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/__init__.py @@ -232,10 +232,16 @@ CatalogWorkspaceContentService, ) from gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model import ( + CatalogAbsolutePublisherDocumentPeriod, CatalogDeclarativeAnalytics, CatalogDeclarativeMemoryItem, CatalogDeclarativeMetric, CatalogDeclarativeParameter, + CatalogDeclarativePublisherDocument, + CatalogDeclarativePublisherDocumentPageTemplate, + CatalogDeclarativePublisherDocumentTemplate, + CatalogPublisherDocumentPeriod, + CatalogRelativePublisherDocumentPeriod, ) from gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.export_definition import ( CatalogDeclarativeExportDefinition, @@ -389,6 +395,7 @@ "CatalogAILakeOperation": "gooddata_sdk.catalog.ai_lake.service", "CatalogAILakeOperationError": "gooddata_sdk.catalog.ai_lake.service", "CatalogAILakeService": "gooddata_sdk.catalog.ai_lake.service", + "CatalogAbsolutePublisherDocumentPeriod": "gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model", "CatalogAppearanceService": "gooddata_sdk.catalog.appearance.service", "CatalogAssigneeIdentifier": "gooddata_sdk.catalog.identifier", "CatalogAssigneeRule": "gooddata_sdk.catalog.rule", @@ -452,6 +459,9 @@ "CatalogDeclarativeNotificationChannel": "gooddata_sdk.catalog.organization.layout.notification_channel", "CatalogDeclarativeOrganizationPermission": "gooddata_sdk.catalog.permission.declarative_model.permission", "CatalogDeclarativeParameter": "gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model", + "CatalogDeclarativePublisherDocument": "gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model", + "CatalogDeclarativePublisherDocumentPageTemplate": "gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model", + "CatalogDeclarativePublisherDocumentTemplate": "gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model", "CatalogDeclarativeReference": "gooddata_sdk.catalog.workspace.declarative_model.workspace.logical_model.dataset.dataset", "CatalogDeclarativeSingleWorkspacePermission": "gooddata_sdk.catalog.permission.declarative_model.permission", "CatalogDeclarativeTable": "gooddata_sdk.catalog.data_source.declarative_model.physical_model.table", @@ -522,6 +532,8 @@ "CatalogPermissionsAssignment": "gooddata_sdk.catalog.user.management_model.management", "CatalogPermissionsForAssigneeIdentifier": "gooddata_sdk.catalog.permission.declarative_model.manage_dashboard_permissions", "CatalogPermissionsForAssigneeRule": "gooddata_sdk.catalog.permission.declarative_model.manage_dashboard_permissions", + "CatalogPublisherDocumentPeriod": "gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model", + "CatalogRelativePublisherDocumentPeriod": "gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model", "CatalogRsaSpecification": "gooddata_sdk.catalog.organization.entity_model.jwk", "CatalogRunningSection": "gooddata_sdk.catalog.organization.common.running_section", "CatalogScanModelRequest": "gooddata_sdk.catalog.data_source.action_model.requests.scan_model_request", @@ -656,6 +668,7 @@ "CatalogAILakeOperation", "CatalogAILakeOperationError", "CatalogAILakeService", + "CatalogAbsolutePublisherDocumentPeriod", "CatalogAppearanceService", "CatalogAssigneeIdentifier", "CatalogAssigneeRule", @@ -719,6 +732,9 @@ "CatalogDeclarativeNotificationChannel", "CatalogDeclarativeOrganizationPermission", "CatalogDeclarativeParameter", + "CatalogDeclarativePublisherDocument", + "CatalogDeclarativePublisherDocumentPageTemplate", + "CatalogDeclarativePublisherDocumentTemplate", "CatalogDeclarativeReference", "CatalogDeclarativeSingleWorkspacePermission", "CatalogDeclarativeTable", @@ -789,6 +805,8 @@ "CatalogPermissionsAssignment", "CatalogPermissionsForAssigneeIdentifier", "CatalogPermissionsForAssigneeRule", + "CatalogPublisherDocumentPeriod", + "CatalogRelativePublisherDocumentPeriod", "CatalogRsaSpecification", "CatalogRunningSection", "CatalogScanModelRequest", diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py index fb8d8a43b..29e049316 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py @@ -1,11 +1,13 @@ # (C) 2022 GoodData Corporation from __future__ import annotations +import builtins from pathlib import Path from typing import Any, Union from attrs import define, field from cattrs import global_converter, structure +from gooddata_api_client.model.absolute_publisher_document_period import AbsolutePublisherDocumentPeriod from gooddata_api_client.model.declarative_analytical_dashboard import DeclarativeAnalyticalDashboard from gooddata_api_client.model.declarative_analytical_dashboard_extension import DeclarativeAnalyticalDashboardExtension from gooddata_api_client.model.declarative_analytics import DeclarativeAnalytics @@ -16,7 +18,13 @@ from gooddata_api_client.model.declarative_memory_item import DeclarativeMemoryItem from gooddata_api_client.model.declarative_metric import DeclarativeMetric from gooddata_api_client.model.declarative_parameter import DeclarativeParameter +from gooddata_api_client.model.declarative_publisher_document import DeclarativePublisherDocument +from gooddata_api_client.model.declarative_publisher_document_page_template import ( + DeclarativePublisherDocumentPageTemplate, +) +from gooddata_api_client.model.declarative_publisher_document_template import DeclarativePublisherDocumentTemplate from gooddata_api_client.model.declarative_visualization_object import DeclarativeVisualizationObject +from gooddata_api_client.model.relative_publisher_document_period import RelativePublisherDocumentPeriod from gooddata_sdk.catalog.base import Base from gooddata_sdk.catalog.permission.declarative_model.permission import ( @@ -84,6 +92,9 @@ class CatalogDeclarativeAnalyticsLayer(Base): export_definitions: list[CatalogDeclarativeExportDefinition] = field(factory=list) memory_items: list[CatalogDeclarativeMemoryItem] = field(factory=list) parameters: list[CatalogDeclarativeParameter] = field(factory=list) + documents: list[CatalogDeclarativePublisherDocument] = field(factory=list) + document_templates: list[CatalogDeclarativePublisherDocumentTemplate] = field(factory=list) + page_templates: list[CatalogDeclarativePublisherDocumentPageTemplate] = field(factory=list) @staticmethod def client_class() -> type[DeclarativeAnalyticsLayer]: @@ -372,3 +383,94 @@ class CatalogDeclarativeParameter(CatalogAnalyticsBase): @staticmethod def client_class() -> type[DeclarativeParameter]: return DeclarativeParameter + + +@define(kw_only=True) +class CatalogAbsolutePublisherDocumentPeriod(Base): + """A document period between two calendar dates, both inclusive, given as ISO dates (``2026-01-31``).""" + + type: str = field(default="absolute", init=False) + from_: str + to: str + # Required by the API but single-valued; the generated client defaults it the same way, and the code form omits it. + granularity: str = "GDC.time.date" + + @staticmethod + def client_class() -> builtins.type[AbsolutePublisherDocumentPeriod]: + return AbsolutePublisherDocumentPeriod + + +@define(kw_only=True) +class CatalogRelativePublisherDocumentPeriod(Base): + """A document period in units of ``granularity`` relative to the current one (``from_=-1, to=0``).""" + + type: str = field(default="relative", init=False) + from_: int + to: int + granularity: str + + @staticmethod + def client_class() -> builtins.type[RelativePublisherDocumentPeriod]: + return RelativePublisherDocumentPeriod + + +CatalogPublisherDocumentPeriod = Union[CatalogAbsolutePublisherDocumentPeriod, CatalogRelativePublisherDocumentPeriod] + + +@define(kw_only=True) +class CatalogDeclarativePublisherDocument(CatalogAnalyticsBaseMeta): + title: str + content: dict[str, Any] + period: CatalogPublisherDocumentPeriod + version: str + description: str | None = None + tags: list[str] | None = None + + @staticmethod + def client_class() -> type[DeclarativePublisherDocument]: + return DeclarativePublisherDocument + + @staticmethod + def structure_period(v: dict[str, Any], _: Any) -> CatalogPublisherDocumentPeriod: + period = dict(v) + for key in ("_from", "from"): + if key in period: + period["from_"] = period.pop(key) + period_type = period.get("type") + if period_type == "absolute": + return structure(period, CatalogAbsolutePublisherDocumentPeriod) + if period_type == "relative": + return structure(period, CatalogRelativePublisherDocumentPeriod) + raise ValueError(f"Unknown publisher document period type {period_type!r}, expected 'absolute' or 'relative'.") + + +global_converter.register_structure_hook( + CatalogPublisherDocumentPeriod, + CatalogDeclarativePublisherDocument.structure_period, +) + + +@define(kw_only=True) +class CatalogDeclarativePublisherDocumentTemplate(CatalogAnalyticsObjectBase): + title: str + content: dict[str, Any] + version: str + description: str | None = None + tags: list[str] | None = None + + @staticmethod + def client_class() -> type[DeclarativePublisherDocumentTemplate]: + return DeclarativePublisherDocumentTemplate + + +@define(kw_only=True) +class CatalogDeclarativePublisherDocumentPageTemplate(CatalogAnalyticsObjectBase): + title: str + content: dict[str, Any] + version: str + description: str | None = None + tags: list[str] | None = None + + @staticmethod + def client_class() -> type[DeclarativePublisherDocumentPageTemplate]: + return DeclarativePublisherDocumentPageTemplate diff --git a/packages/gooddata-sdk/tests/catalog/unit_tests/test_declarative_analytics_documents.py b/packages/gooddata-sdk/tests/catalog/unit_tests/test_declarative_analytics_documents.py new file mode 100644 index 000000000..55377dad3 --- /dev/null +++ b/packages/gooddata-sdk/tests/catalog/unit_tests/test_declarative_analytics_documents.py @@ -0,0 +1,216 @@ +# (C) 2026 GoodData Corporation +"""Unit test: Publisher documents survive the declarative analytics round-trip. + +The analytics layer carries ``documents``, ``documentTemplates`` and +``pageTemplates``. Whatever goes in through ``from_dict`` must come back out of +``to_api()`` unchanged, including content keys the SDK does not model. +""" + +from __future__ import annotations + +from datetime import date +from typing import Any + +import pytest +from cattrs import structure +from gooddata_sdk import ( + CatalogAbsolutePublisherDocumentPeriod, + CatalogDeclarativeAnalytics, + CatalogDeclarativePublisherDocument, + CatalogDeclarativePublisherDocumentPageTemplate, + CatalogDeclarativePublisherDocumentTemplate, + CatalogPublisherDocumentPeriod, + CatalogRelativePublisherDocumentPeriod, + CatalogUserIdentifier, +) +from gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model import ( + CatalogDeclarativeAnalyticsLayer, +) + +_AUTHOR = { + "createdBy": {"id": "admin", "type": "user"}, + "createdAt": "2026-11-02 10:00", + "modifiedBy": {"id": "admin", "type": "user"}, + "modifiedAt": "2026-11-02 11:00", +} +_TEXT = {"type": "text", "id": "t1", "markdown": "Hello"} +_DOCUMENT = { + "id": "doc_1", + "title": "Doc 1", + "version": "1", + "period": {"type": "relative", "granularity": "GDC.time.month", "from": -1, "to": 0}, + "content": { + "locale": "en-US", + "pages": [{"id": "p1", "kind": "content", "layout": {"type": "row", "children": [_TEXT]}}], + "futureField": {"nested": [1, {"deep": True}]}, + }, + **_AUTHOR, +} +_DOCUMENT_TEMPLATE = {"id": "tpl_1", "title": "Tpl 1", "version": "1", "content": {"locale": "en-US"}} +_PAGE_TEMPLATE = {"id": "pt_1", "title": "Page 1", "version": "1", "content": {"layout": _TEXT}} +_LAYER = {"documents": [_DOCUMENT], "documentTemplates": [_DOCUMENT_TEMPLATE], "pageTemplates": [_PAGE_TEMPLATE]} +_ABSOLUTE_PERIOD = {"type": "absolute", "granularity": "GDC.time.date", "from": "2026-01-01", "to": "2026-01-31"} +_RELATIVE_PERIOD = {"type": "relative", "granularity": "GDC.time.month", "from": -1, "to": 0} +# The generated client holds an absolute period's dates as `datetime.date`, so its `to_dict` writes them so. +_PERIODS = pytest.mark.parametrize( + ("period", "typed_period", "client_period"), + [ + ( + _ABSOLUTE_PERIOD, + CatalogAbsolutePublisherDocumentPeriod(from_="2026-01-01", to="2026-01-31", granularity="GDC.time.date"), + {**_ABSOLUTE_PERIOD, "from": date(2026, 1, 1), "to": date(2026, 1, 31)}, + ), + ( + _RELATIVE_PERIOD, + CatalogRelativePublisherDocumentPeriod(from_=-1, to=0, granularity="GDC.time.month"), + _RELATIVE_PERIOD, + ), + ], + ids=["absolute", "relative"], +) + + +def _round_trip(layer: CatalogDeclarativeAnalyticsLayer) -> dict[str, Any]: + return layer.to_api().to_dict(camel_case=True) + + +def test_documents_survive_api_round_trip() -> None: + layer = CatalogDeclarativeAnalyticsLayer.from_dict(_LAYER) + + round_tripped = _round_trip(layer) + + assert {key: round_tripped[key] for key in _LAYER} == _LAYER + + +def test_document_author_fields_are_typed() -> None: + layer = CatalogDeclarativeAnalyticsLayer.from_dict(_LAYER) + + document = layer.documents[0] + + assert isinstance(document, CatalogDeclarativePublisherDocument) + assert document.created_by == CatalogUserIdentifier(id="admin", type="user") + assert document.created_at == "2026-11-02 10:00" + assert document.modified_by == CatalogUserIdentifier(id="admin", type="user") + assert document.modified_at == "2026-11-02 11:00" + + +@pytest.mark.parametrize( + ("layer_key", "attribute", "item_class", "item"), + [ + ("documentTemplates", "document_templates", CatalogDeclarativePublisherDocumentTemplate, _DOCUMENT_TEMPLATE), + ("pageTemplates", "page_templates", CatalogDeclarativePublisherDocumentPageTemplate, _PAGE_TEMPLATE), + ], + ids=["document_template", "page_template"], +) +def test_templates_have_no_author_attributes( + layer_key: str, attribute: str, item_class: type, item: dict[str, Any] +) -> None: + layer = CatalogDeclarativeAnalyticsLayer.from_dict({layer_key: [item]}) + + template = getattr(layer, attribute)[0] + + assert isinstance(template, item_class) + assert not hasattr(template, "created_by") + round_tripped = _round_trip(layer)[layer_key] + assert round_tripped == [item] + assert not set(_AUTHOR) & set(round_tripped[0]) + + +def test_document_without_author_fields() -> None: + document = {key: value for key, value in _DOCUMENT.items() if key not in _AUTHOR} + layer = CatalogDeclarativeAnalyticsLayer.from_dict({"documents": [document]}) + + loaded = layer.documents[0] + + assert loaded.created_by is None + assert loaded.created_at is None + assert loaded.modified_by is None + assert loaded.modified_at is None + round_tripped = _round_trip(layer)["documents"] + assert round_tripped == [document] + assert not set(_AUTHOR) & set(round_tripped[0]) + + +def test_empty_layer_has_empty_document_lists() -> None: + layer = CatalogDeclarativeAnalyticsLayer.from_dict({}) + + assert layer.documents == [] + assert layer.document_templates == [] + assert layer.page_templates == [] + round_tripped = _round_trip(layer) + assert round_tripped["documents"] == [] + assert round_tripped["documentTemplates"] == [] + assert round_tripped["pageTemplates"] == [] + + +def _document_with(period: dict[str, Any]) -> dict[str, Any]: + return {**{key: value for key, value in _DOCUMENT.items() if key not in _AUTHOR}, "period": period} + + +@_PERIODS +def test_period_read_is_typed( + period: dict[str, Any], typed_period: CatalogPublisherDocumentPeriod, client_period: dict[str, Any] +) -> None: + document = CatalogDeclarativePublisherDocument.from_dict(_document_with(period)) + + assert document.period == typed_period + + +@_PERIODS +def test_period_to_dict_writes_api_names( + period: dict[str, Any], typed_period: CatalogPublisherDocumentPeriod, client_period: dict[str, Any] +) -> None: + document = CatalogDeclarativePublisherDocument.from_dict(_document_with(period)) + + assert document.to_dict()["period"] == client_period + + +@_PERIODS +def test_hand_built_document_equals_read_document( + period: dict[str, Any], typed_period: CatalogPublisherDocumentPeriod, client_period: dict[str, Any] +) -> None: + hand_built = CatalogDeclarativePublisherDocument( + id=_DOCUMENT["id"], + title=_DOCUMENT["title"], + version=_DOCUMENT["version"], + content=_DOCUMENT["content"], + period=typed_period, + ) + + read_back = CatalogDeclarativePublisherDocument.from_dict(hand_built.to_dict()) + + assert read_back == hand_built + + +@_PERIODS +def test_nested_period_read_is_typed( + period: dict[str, Any], typed_period: CatalogPublisherDocumentPeriod, client_period: dict[str, Any] +) -> None: + analytics = CatalogDeclarativeAnalytics.from_dict({"analytics": {"documents": [_document_with(period)]}}) + + assert analytics.analytics is not None + assert analytics.analytics.documents[0].period == typed_period + + +@_PERIODS +def test_nested_period_write_uses_api_names( + period: dict[str, Any], typed_period: CatalogPublisherDocumentPeriod, client_period: dict[str, Any] +) -> None: + document = CatalogDeclarativePublisherDocument( + id=_DOCUMENT["id"], + title=_DOCUMENT["title"], + version=_DOCUMENT["version"], + content=_DOCUMENT["content"], + period=typed_period, + ) + analytics = CatalogDeclarativeAnalytics(analytics=CatalogDeclarativeAnalyticsLayer(documents=[document])) + + written = analytics.to_api().to_dict(camel_case=True)["analytics"]["documents"][0]["period"] + + assert "from_" not in written + assert written == client_period + + +def test_unknown_period_type_raises() -> None: + with pytest.raises(ValueError, match="rolling"): + structure({"type": "rolling", "from": -1, "to": 0}, CatalogPublisherDocumentPeriod) From 7fcfc25fa113d543232a784f509528e6b522be7d Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Tue, 3 Nov 2026 14:52:02 +0100 Subject: [PATCH 06/12] feat(gooddata-sdk): store and load publisher documents on disk The analytics layer carries publisher documents, document templates and page templates, but store_to_disk and load_from_disk ignored them, so a layout written to disk and read back lost all three. store_to_disk now writes them to three folders directly under analytics_model/: documents/, document_templates/ and page_templates/, one .yaml per object, the same way as metrics or parameters. load_from_disk reads them back. A folder stored before this change, without the three folders, still loads, with the three lists empty; a document YAML without the author fields loads with them unset. jira: LX-3447 risk: low Co-Authored-By: Claude Opus 5.5 --- .../analytics_model/analytics_model.py | 53 +++++++++++++++++++ .../test_declarative_analytics_documents.py | 48 +++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py index 29e049316..851b90d15 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py @@ -60,6 +60,9 @@ EXPORT_DEFINITION_DIR = "export_definitions" MEMORY_ITEMS_DIR = "memory_items" PARAMETERS_DIR = "parameters" +LAYOUT_DOCUMENTS_DIR = "documents" +LAYOUT_DOCUMENT_TEMPLATES_DIR = "document_templates" +LAYOUT_PAGE_TEMPLATES_DIR = "page_templates" @define(kw_only=True) @@ -166,6 +169,24 @@ def get_parameters_folder(analytics_model_folder: Path) -> Path: create_directory(folder) return folder + @staticmethod + def get_documents_folder(analytics_model_folder: Path) -> Path: + folder = analytics_model_folder / LAYOUT_DOCUMENTS_DIR + create_directory(folder) + return folder + + @staticmethod + def get_document_templates_folder(analytics_model_folder: Path) -> Path: + folder = analytics_model_folder / LAYOUT_DOCUMENT_TEMPLATES_DIR + create_directory(folder) + return folder + + @staticmethod + def get_page_templates_folder(analytics_model_folder: Path) -> Path: + folder = analytics_model_folder / LAYOUT_PAGE_TEMPLATES_DIR + create_directory(folder) + return folder + def store_to_disk(self, workspace_folder: Path, sort: bool = False) -> None: analytics_model_folder = self.get_analytics_model_folder(workspace_folder) @@ -179,6 +200,9 @@ def store_to_disk(self, workspace_folder: Path, sort: bool = False) -> None: export_definition_folder = self.get_export_definition_folder(analytical_dashboards_folder) memory_item_folder = self.get_memory_item_folder(analytics_model_folder) parameters_folder = self.get_parameters_folder(analytics_model_folder) + documents_folder = self.get_documents_folder(analytics_model_folder) + document_templates_folder = self.get_document_templates_folder(analytics_model_folder) + page_templates_folder = self.get_page_templates_folder(analytics_model_folder) for analytical_dashboard in self.analytical_dashboards: analytical_dashboard.store_to_disk(analytical_dashboards_folder, sort=sort) @@ -210,6 +234,15 @@ def store_to_disk(self, workspace_folder: Path, sort: bool = False) -> None: for parameter in self.parameters: parameter.store_to_disk(parameters_folder, sort=sort) + for document in self.documents: + document.store_to_disk(documents_folder, sort=sort) + + for document_template in self.document_templates: + document_template.store_to_disk(document_templates_folder, sort=sort) + + for page_template in self.page_templates: + page_template.store_to_disk(page_templates_folder, sort=sort) + @classmethod def load_from_disk(cls, workspace_folder: Path) -> CatalogDeclarativeAnalyticsLayer: analytics_model_folder = cls.get_analytics_model_folder(workspace_folder) @@ -223,6 +256,9 @@ def load_from_disk(cls, workspace_folder: Path) -> CatalogDeclarativeAnalyticsLa export_definition_folder = cls.get_export_definition_folder(analytical_dashboards_folder) memory_item_folder = cls.get_memory_item_folder(analytics_model_folder) parameters_folder = cls.get_parameters_folder(analytics_model_folder) + documents_folder = cls.get_documents_folder(analytics_model_folder) + document_templates_folder = cls.get_document_templates_folder(analytics_model_folder) + page_templates_folder = cls.get_page_templates_folder(analytics_model_folder) analytical_dashboard_files = get_sorted_yaml_files(analytical_dashboards_folder) analytical_dashboard_extension_files = get_sorted_yaml_files(analytical_dashboard_extensions_folder) @@ -234,6 +270,9 @@ def load_from_disk(cls, workspace_folder: Path) -> CatalogDeclarativeAnalyticsLa export_definition_files = get_sorted_yaml_files(export_definition_folder) memory_item_files = get_sorted_yaml_files(memory_item_folder) parameter_files = get_sorted_yaml_files(parameters_folder) + document_files = get_sorted_yaml_files(documents_folder) + document_template_files = get_sorted_yaml_files(document_templates_folder) + page_template_files = get_sorted_yaml_files(page_templates_folder) analytical_dashboards = [ CatalogDeclarativeAnalyticalDashboard.load_from_disk(analytical_dashboard_file) @@ -268,6 +307,17 @@ def load_from_disk(cls, workspace_folder: Path) -> CatalogDeclarativeAnalyticsLa CatalogDeclarativeMemoryItem.load_from_disk(memory_item_file) for memory_item_file in memory_item_files ] parameters = [CatalogDeclarativeParameter.load_from_disk(parameter_file) for parameter_file in parameter_files] + documents = [ + CatalogDeclarativePublisherDocument.load_from_disk(document_file) for document_file in document_files + ] + document_templates = [ + CatalogDeclarativePublisherDocumentTemplate.load_from_disk(document_template_file) + for document_template_file in document_template_files + ] + page_templates = [ + CatalogDeclarativePublisherDocumentPageTemplate.load_from_disk(page_template_file) + for page_template_file in page_template_files + ] return cls( analytical_dashboards=analytical_dashboards, analytical_dashboard_extensions=analytical_dashboard_extensions, @@ -279,6 +329,9 @@ def load_from_disk(cls, workspace_folder: Path) -> CatalogDeclarativeAnalyticsLa export_definitions=export_definitions, memory_items=memory_items, parameters=parameters, + documents=documents, + document_templates=document_templates, + page_templates=page_templates, ) diff --git a/packages/gooddata-sdk/tests/catalog/unit_tests/test_declarative_analytics_documents.py b/packages/gooddata-sdk/tests/catalog/unit_tests/test_declarative_analytics_documents.py index 55377dad3..948edeea7 100644 --- a/packages/gooddata-sdk/tests/catalog/unit_tests/test_declarative_analytics_documents.py +++ b/packages/gooddata-sdk/tests/catalog/unit_tests/test_declarative_analytics_documents.py @@ -8,7 +8,9 @@ from __future__ import annotations +import shutil from datetime import date +from pathlib import Path from typing import Any import pytest @@ -26,6 +28,7 @@ from gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model import ( CatalogDeclarativeAnalyticsLayer, ) +from gooddata_sdk.utils import write_layout_to_file _AUTHOR = { "createdBy": {"id": "admin", "type": "user"}, @@ -49,6 +52,8 @@ _DOCUMENT_TEMPLATE = {"id": "tpl_1", "title": "Tpl 1", "version": "1", "content": {"locale": "en-US"}} _PAGE_TEMPLATE = {"id": "pt_1", "title": "Page 1", "version": "1", "content": {"layout": _TEXT}} _LAYER = {"documents": [_DOCUMENT], "documentTemplates": [_DOCUMENT_TEMPLATE], "pageTemplates": [_PAGE_TEMPLATE]} +_METRIC = {"id": "bmk_w_fraud_charged_back", "title": "BMK", "content": {"format": "#,##0", "maql": "SELECT 1"}} +_DOCUMENT_FOLDERS = ("documents", "document_templates", "page_templates") _ABSOLUTE_PERIOD = {"type": "absolute", "granularity": "GDC.time.date", "from": "2026-01-01", "to": "2026-01-31"} _RELATIVE_PERIOD = {"type": "relative", "granularity": "GDC.time.month", "from": -1, "to": 0} # The generated client holds an absolute period's dates as `datetime.date`, so its `to_dict` writes them so. @@ -143,6 +148,33 @@ def test_empty_layer_has_empty_document_lists() -> None: assert round_tripped["pageTemplates"] == [] +@pytest.mark.parametrize("sort", [True, False], ids=["sorted", "unsorted"]) +def test_documents_survive_disk_round_trip(tmp_path: Path, sort: bool) -> None: + layer = CatalogDeclarativeAnalyticsLayer.from_dict(_LAYER) + + layer.store_to_disk(tmp_path, sort=sort) + + analytics_model_folder = tmp_path / "analytics_model" + assert (analytics_model_folder / "documents" / "doc_1.yaml").is_file() + assert (analytics_model_folder / "document_templates" / "tpl_1.yaml").is_file() + assert (analytics_model_folder / "page_templates" / "pt_1.yaml").is_file() + round_tripped = _round_trip(CatalogDeclarativeAnalyticsLayer.load_from_disk(tmp_path)) + assert {key: round_tripped[key] for key in _LAYER} == _LAYER + + +def test_load_without_document_folders(tmp_path: Path) -> None: + CatalogDeclarativeAnalyticsLayer.from_dict({"metrics": [_METRIC]}).store_to_disk(tmp_path) + for folder in _DOCUMENT_FOLDERS: + shutil.rmtree(tmp_path / "analytics_model" / folder, ignore_errors=True) + + reloaded = CatalogDeclarativeAnalyticsLayer.load_from_disk(tmp_path) + + assert reloaded.documents == [] + assert reloaded.document_templates == [] + assert reloaded.page_templates == [] + assert _round_trip(reloaded)["metrics"] == [_METRIC] + + def _document_with(period: dict[str, Any]) -> dict[str, Any]: return {**{key: value for key, value in _DOCUMENT.items() if key not in _AUTHOR}, "period": period} @@ -214,3 +246,19 @@ def test_nested_period_write_uses_api_names( def test_unknown_period_type_raises() -> None: with pytest.raises(ValueError, match="rolling"): structure({"type": "rolling", "from": -1, "to": 0}, CatalogPublisherDocumentPeriod) + + +def test_load_document_yaml_without_author_fields(tmp_path: Path) -> None: + document = {key: value for key, value in _DOCUMENT.items() if key not in _AUTHOR} + documents_folder = tmp_path / "analytics_model" / "documents" + documents_folder.mkdir(parents=True) + write_layout_to_file(documents_folder / "doc_1.yaml", document) + + reloaded = CatalogDeclarativeAnalyticsLayer.load_from_disk(tmp_path) + + assert len(reloaded.documents) == 1 + loaded = reloaded.documents[0] + assert loaded.created_by is None + assert loaded.created_at is None + assert loaded.modified_by is None + assert loaded.modified_at is None From 867b0b527f7b9633a66a022ea07e8aba7ac417dd Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Tue, 3 Nov 2026 16:13:36 +0100 Subject: [PATCH 07/12] build(gooddata-sdk): require gooddata-code-convertors 11.66.0 11.66.0 is the first stable release of gooddata-code-convertors with the v2 publisher convertors for documents, document templates and page templates, which Analytics-as-Code needs to clone and deploy them. uv lock moves only the convertor entry, from 11.57.0 to 11.66.0, with the same dependencies. On py314 in freshly built tox envs, the 27 existing AaC tests (-k aac) pass, and the gooddata-eval suite, the other consumer of the convertors, passes unchanged (2542 passed, 1 skipped by design). jira: LX-3447 risk: low Co-Authored-By: Claude Opus 5.5 --- packages/gooddata-sdk/pyproject.toml | 2 +- uv.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/gooddata-sdk/pyproject.toml b/packages/gooddata-sdk/pyproject.toml index b8d3b1094..9e9ab2050 100644 --- a/packages/gooddata-sdk/pyproject.toml +++ b/packages/gooddata-sdk/pyproject.toml @@ -34,7 +34,7 @@ dependencies = [ "brotli==1.2.1", "requests>=2.33.0,<3.0.0", "python-dotenv>=1.2.2,<2.0.0", - "gooddata-code-convertors>=11.57.0", + "gooddata-code-convertors>=11.66.0", ] classifiers = [ "Development Status :: 5 - Production/Stable", diff --git a/uv.lock b/uv.lock index 6e32ceeb6..5dee3f881 100644 --- a/uv.lock +++ b/uv.lock @@ -1041,7 +1041,7 @@ requires-dist = [ [[package]] name = "gooddata-code-convertors" -version = "11.57.0" +version = "11.66.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, @@ -1049,7 +1049,7 @@ dependencies = [ { name = "wasmtime" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/88/a8/4ca369e2de1be3f9c0d23dc5696c895cfdb5e529b69ded9862e5b250557d/gooddata_code_convertors-11.57.0-py3-none-any.whl", hash = "sha256:efc56ba78eec9d7fb7e93e00d1b321583d0ac1ae38240a373a287478ae49c70b", size = 1220956, upload-time = "2026-09-17T06:54:58.286Z" }, + { url = "https://files.pythonhosted.org/packages/99/45/1796b463eb183ff4f6dda3a25291f6323ef0edbcee10cf4221106fc6d768/gooddata_code_convertors-11.66.0-py3-none-any.whl", hash = "sha256:0cb7f74892596002fca4e2e63d753250eb1efa44658b80b0f58b11a8bc7c2aa7", size = 1385475, upload-time = "2026-11-02T10:36:52.904Z" }, ] [[package]] @@ -1507,7 +1507,7 @@ requires-dist = [ { name = "brotli", specifier = "==1.2.1" }, { name = "cattrs", specifier = ">=22.1.0,<=26.1.0" }, { name = "gooddata-api-client", editable = "gooddata-api-client" }, - { name = "gooddata-code-convertors", specifier = ">=11.57.0" }, + { name = "gooddata-code-convertors", specifier = ">=11.66.0" }, { name = "pyarrow", marker = "extra == 'arrow'", specifier = ">=23.0.1" }, { name = "python-dateutil", specifier = ">=2.5.3" }, { name = "python-dotenv", specifier = ">=1.2.2,<2.0.0" }, From 14822b438904a852d07c48ac054f15c3e9133ddf Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Tue, 3 Nov 2026 16:22:44 +0100 Subject: [PATCH 08/12] feat(gooddata-sdk): clone and deploy publisher documents as code gdc clone writes Publisher documents, document templates and page templates to documents/, documentTemplates/ and pageTemplates/, and gdc deploy sends them back, through the v2 publisher convertors of gooddata-code-convertors. The AaC form carries no author fields, so a clone then deploy re-stamps the creator to the deploying user. An object whose version is not "2" raises a ValueError naming its type, id and version, on store and on load; so does any other refusal by the convertor. Store converts all three types before it creates the target folder, so refusing one of them writes nothing. The folder names follow the layout keys until the gd CLI decides its own (LX-3096). jira: LX-3447 risk: low Co-Authored-By: Claude Opus 5.5 --- .../src/gooddata_sdk/catalog/workspace/aac.py | 161 +++++++++++++++- .../gooddata-sdk/tests/catalog/test_aac.py | 11 ++ .../aac_tests/documentTemplates/tpl_1.yaml | 23 +++ .../unit_tests/aac_tests/documents/doc_1.yaml | 31 ++++ .../aac_tests/pageTemplates/pt_1.yaml | 17 ++ .../catalog/unit_tests/test_aac_documents.py | 172 ++++++++++++++++++ 6 files changed, 411 insertions(+), 4 deletions(-) create mode 100644 packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/documentTemplates/tpl_1.yaml create mode 100644 packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/documents/doc_1.yaml create mode 100644 packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/pageTemplates/pt_1.yaml create mode 100644 packages/gooddata-sdk/tests/catalog/unit_tests/test_aac_documents.py diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/aac.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/aac.py index 0f59bbd06..2cc21cef1 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/aac.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/aac.py @@ -1,16 +1,21 @@ # (C) 2026 GoodData Corporation from __future__ import annotations +from collections.abc import Callable from pathlib import Path from typing import Any, Literal from gooddata_code_convertors import ( + ConversionError, declarative_attribute_hierarchy_to_yaml, declarative_dashboard_to_yaml, declarative_dataset_to_yaml, declarative_date_instance_to_yaml, declarative_metric_to_yaml, declarative_plugin_to_yaml, + declarative_publisher_document_template_to_yaml_v2, + declarative_publisher_document_to_yaml_v2, + declarative_publisher_page_template_to_yaml_v2, declarative_visualisation_to_yaml, yaml_attribute_hierarchy_to_declarative, yaml_dashboard_to_declarative, @@ -18,6 +23,9 @@ yaml_date_dataset_to_declarative, yaml_metric_to_declarative, yaml_plugin_to_declarative, + yaml_publisher_document_template_to_declarative_v2, + yaml_publisher_document_to_declarative_v2, + yaml_publisher_page_template_to_declarative_v2, yaml_visualisation_to_declarative, ) @@ -54,7 +62,20 @@ # All known AAC type values _ALL_AAC_TYPES = ( - frozenset({"dataset", "date", "metric", "dashboard", "plugin", "attribute_hierarchy"}) | _VISUALIZATION_TYPES + frozenset( + { + "dataset", + "date", + "metric", + "dashboard", + "plugin", + "attribute_hierarchy", + "document", + "document_template", + "page_template", + } + ) + | _VISUALIZATION_TYPES ) # Types that are "dataset-like" for the entities array @@ -83,6 +104,36 @@ def _build_entities(aac_objects: list[dict[str, Any]]) -> list[dict[str, Any]]: ] +# --------------------------------------------------------------------------- +# Convertor refusal errors (documents, document templates, page templates) +# --------------------------------------------------------------------------- + + +def _convert( + convert: Callable[[dict[str, Any]], dict[str, Any]], + aac_type: str, + obj: dict[str, Any], + direction: Literal["read", "write"], +) -> dict[str, Any]: + """Run a convertor on one object and name the object when the convertor refuses it. + + Args: + convert: The gooddata-code-convertors function to apply to obj. + aac_type: The AAC type of obj, used to name it in the error. + obj: The AAC dict when reading from code, the declarative dict when writing as code. + direction: "read" for AAC to declarative on load, "write" for declarative to AAC on store. + + Raises: + ValueError: The convertor refused obj. + """ + try: + return convert(obj) + except ConversionError as e: + name = f'{aac_type} "{obj.get("id")}" (version "{obj.get("version")}")' + action = f"read {name} from code" if direction == "read" else f"write {name} as code" + raise ValueError(f"Cannot {action}: {e}") from e + + # --------------------------------------------------------------------------- # Individual object conversions: AAC dict → Declarative dict # --------------------------------------------------------------------------- @@ -155,6 +206,33 @@ def aac_attribute_hierarchy_to_declarative(aac: dict[str, Any]) -> dict[str, Any return yaml_attribute_hierarchy_to_declarative(aac) +def aac_document_to_declarative(aac: dict[str, Any]) -> dict[str, Any]: + """Convert an AAC document dict to declarative format. + + Raises: + ValueError: The convertor refused the document, for example because its version is not "2". + """ + return _convert(yaml_publisher_document_to_declarative_v2, "document", aac, "read") + + +def aac_document_template_to_declarative(aac: dict[str, Any]) -> dict[str, Any]: + """Convert an AAC document template dict to declarative format. + + Raises: + ValueError: The convertor refused the document template, for example because its version is not "2". + """ + return _convert(yaml_publisher_document_template_to_declarative_v2, "document_template", aac, "read") + + +def aac_page_template_to_declarative(aac: dict[str, Any]) -> dict[str, Any]: + """Convert an AAC page template dict to declarative format. + + Raises: + ValueError: The convertor refused the page template, for example because its version is not "2". + """ + return _convert(yaml_publisher_page_template_to_declarative_v2, "page_template", aac, "read") + + # --------------------------------------------------------------------------- # Individual object conversions: Declarative dict → AAC dict # Returns {"json": dict, "content": str} @@ -226,6 +304,35 @@ def declarative_attribute_hierarchy_to_aac(declarative: dict[str, Any]) -> dict[ return declarative_attribute_hierarchy_to_yaml(declarative) +def declarative_document_to_aac(declarative: dict[str, Any]) -> dict[str, Any]: + """Convert a declarative document dict to AAC format. + + The AAC form carries no author fields (createdBy, createdAt, modifiedBy, modifiedAt). + + Raises: + ValueError: The convertor refused the document, for example because its version is not "2". + """ + return _convert(declarative_publisher_document_to_yaml_v2, "document", declarative, "write") + + +def declarative_document_template_to_aac(declarative: dict[str, Any]) -> dict[str, Any]: + """Convert a declarative document template dict to AAC format. + + Raises: + ValueError: The convertor refused the document template, for example because its version is not "2". + """ + return _convert(declarative_publisher_document_template_to_yaml_v2, "document_template", declarative, "write") + + +def declarative_page_template_to_aac(declarative: dict[str, Any]) -> dict[str, Any]: + """Convert a declarative page template dict to AAC format. + + Raises: + ValueError: The convertor refused the page template, for example because its version is not "2". + """ + return _convert(declarative_publisher_page_template_to_yaml_v2, "page_template", declarative, "write") + + # --------------------------------------------------------------------------- # Format detection # --------------------------------------------------------------------------- @@ -245,7 +352,17 @@ def detect_yaml_format(path: Path) -> Literal["aac", "declarative"]: return "declarative" # Check for AAC markers: typed subdirectories - aac_subdirs = {"datasets", "metrics", "visualisations", "dashboards", "plugins", "attributeHierarchies"} + aac_subdirs = { + "datasets", + "metrics", + "visualisations", + "dashboards", + "plugins", + "attributeHierarchies", + "documents", + "documentTemplates", + "pageTemplates", + } for subdir in aac_subdirs: if (path / subdir).is_dir(): return "aac" @@ -319,6 +436,9 @@ def load_aac_workspace_from_disk( analytical_dashboards: list[dict[str, Any]] = [] dashboard_plugins: list[dict[str, Any]] = [] attribute_hierarchies: list[dict[str, Any]] = [] + documents: list[dict[str, Any]] = [] + document_templates: list[dict[str, Any]] = [] + page_templates: list[dict[str, Any]] = [] for aac in aac_objects: aac_type = aac.get("type") @@ -341,6 +461,12 @@ def load_aac_workspace_from_disk( dashboard_plugins.append(aac_plugin_to_declarative(aac)) case "attribute_hierarchy": attribute_hierarchies.append(aac_attribute_hierarchy_to_declarative(aac)) + case "document": + documents.append(aac_document_to_declarative(aac)) + case "document_template": + document_templates.append(aac_document_template_to_declarative(aac)) + case "page_template": + page_templates.append(aac_page_template_to_declarative(aac)) case vis_type if vis_type in _VISUALIZATION_TYPES: visualization_objects.append(aac_visualization_to_declarative(aac, entities)) @@ -365,6 +491,12 @@ def load_aac_workspace_from_disk( analytics["dashboardPlugins"] = dashboard_plugins if attribute_hierarchies: analytics["attributeHierarchyObjects"] = attribute_hierarchies + if documents: + analytics["documents"] = documents + if document_templates: + analytics["documentTemplates"] = document_templates + if page_templates: + analytics["pageTemplates"] = page_templates if analytics: workspace_model_dict["analytics"] = analytics @@ -388,14 +520,26 @@ def store_aac_workspace_to_disk(model: CatalogDeclarativeWorkspaceModel, source_ """Convert a declarative workspace model to AAC YAML files and write to disk. Creates typed subdirectories (datasets/, metrics/, visualisations/, dashboards/, - plugins/, attributeHierarchies/) under source_dir. + plugins/, attributeHierarchies/, documents/, documentTemplates/, pageTemplates/) + under source_dir. + + Raises: + ValueError: The convertor refused a document, document template or page template. + Nothing is written in that case. """ - source_dir.mkdir(parents=True, exist_ok=True) model_dict = model.to_dict(camel_case=True) ldm = model_dict.get("ldm", {}) analytics = model_dict.get("analytics", {}) + documents = [(d["id"], declarative_document_to_aac(d)) for d in analytics.get("documents", [])] + document_templates = [ + (t["id"], declarative_document_template_to_aac(t)) for t in analytics.get("documentTemplates", []) + ] + page_templates = [(p["id"], declarative_page_template_to_aac(p)) for p in analytics.get("pageTemplates", [])] + + source_dir.mkdir(parents=True, exist_ok=True) + for dataset in ldm.get("datasets", []): result = declarative_dataset_to_aac(dataset) _write_aac_file(source_dir, "datasets", dataset["id"], result["content"]) @@ -423,3 +567,12 @@ def store_aac_workspace_to_disk(model: CatalogDeclarativeWorkspaceModel, source_ for hierarchy in analytics.get("attributeHierarchyObjects", []): result = declarative_attribute_hierarchy_to_aac(hierarchy) _write_aac_file(source_dir, "attributeHierarchies", hierarchy["id"], result["content"]) + + for document_id, result in documents: + _write_aac_file(source_dir, "documents", document_id, result["content"]) + + for template_id, result in document_templates: + _write_aac_file(source_dir, "documentTemplates", template_id, result["content"]) + + for page_template_id, result in page_templates: + _write_aac_file(source_dir, "pageTemplates", page_template_id, result["content"]) diff --git a/packages/gooddata-sdk/tests/catalog/test_aac.py b/packages/gooddata-sdk/tests/catalog/test_aac.py index 69fe7a75e..d12a9fe9e 100644 --- a/packages/gooddata-sdk/tests/catalog/test_aac.py +++ b/packages/gooddata-sdk/tests/catalog/test_aac.py @@ -5,6 +5,7 @@ import tempfile from pathlib import Path +import pytest import yaml from gooddata_sdk.catalog.workspace.aac import ( aac_dataset_to_declarative, @@ -230,6 +231,16 @@ def test_detect_aac_with_flat_files(self, tmp_path: Path) -> None: (tmp_path / "orders.yaml").write_text("type: dataset\nid: orders\n") assert detect_yaml_format(tmp_path) == "aac" + @pytest.mark.parametrize("subdir", ["documents", "documentTemplates", "pageTemplates"]) + def test_detect_aac_with_publisher_subdirs(self, tmp_path: Path, subdir: str) -> None: + (tmp_path / subdir).mkdir() + (tmp_path / subdir / "x.yaml").write_text("type: document\nid: x\n") + assert detect_yaml_format(tmp_path) == "aac" + + def test_detect_aac_with_flat_document_file(self, tmp_path: Path) -> None: + (tmp_path / "doc_1.yaml").write_text("type: document\nid: doc_1\n") + assert detect_yaml_format(tmp_path) == "aac" + def test_detect_declarative_with_workspaces_dir(self, tmp_path: Path) -> None: (tmp_path / "workspaces").mkdir() assert detect_yaml_format(tmp_path) == "declarative" diff --git a/packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/documentTemplates/tpl_1.yaml b/packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/documentTemplates/tpl_1.yaml new file mode 100644 index 000000000..21079de43 --- /dev/null +++ b/packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/documentTemplates/tpl_1.yaml @@ -0,0 +1,23 @@ +# (C) 2026 GoodData Corporation +# A document template is the pages a document starts from. +# A document made from it copies them and keeps no reference back, +# so the document stays as it was made while the template moves on. + +type: document_template +id: tpl_1 +version: "2" +title: Tpl 1 +description: Base +tags: + - finance +content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + type: row + children: + - type: text + id: t1 + markdown: Hello diff --git a/packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/documents/doc_1.yaml b/packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/documents/doc_1.yaml new file mode 100644 index 000000000..f6ac3ed0d --- /dev/null +++ b/packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/documents/doc_1.yaml @@ -0,0 +1,31 @@ +# (C) 2026 GoodData Corporation +# A document presents a finished period as pages of visualizations and text. +# Its period becomes a date filter on every visualization that does not opt out, +# and a page places what it draws in a tree of rows and columns. + +type: document +id: doc_1 +version: "2" +title: Doc 1 +description: Monthly +tags: + - finance +period: + granularity: MONTH + from: -1 + to: 0 +content: + locale: en-US + future_field: + nested: + - 1 + - deep: true + pages: + - id: p1 + kind: content + layout: + type: row + children: + - type: text + id: t1 + markdown: Hello diff --git a/packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/pageTemplates/pt_1.yaml b/packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/pageTemplates/pt_1.yaml new file mode 100644 index 000000000..f3db999e5 --- /dev/null +++ b/packages/gooddata-sdk/tests/catalog/unit_tests/aac_tests/pageTemplates/pt_1.yaml @@ -0,0 +1,17 @@ +# (C) 2026 GoodData Corporation +# A page template is one page a document or a document template can copy. +# It places widgets in a tree of rows and columns, and a widget left empty +# here is one the document is expected to fill. + +type: page_template +id: pt_1 +version: "2" +title: Page 1 +description: Cover +tags: + - finance +content: + layout: + type: text + id: t1 + markdown: Hello diff --git a/packages/gooddata-sdk/tests/catalog/unit_tests/test_aac_documents.py b/packages/gooddata-sdk/tests/catalog/unit_tests/test_aac_documents.py new file mode 100644 index 000000000..fc558a222 --- /dev/null +++ b/packages/gooddata-sdk/tests/catalog/unit_tests/test_aac_documents.py @@ -0,0 +1,172 @@ +# (C) 2026 GoodData Corporation +from __future__ import annotations + +import shutil +from datetime import date +from pathlib import Path +from typing import Any + +import pytest +from gooddata_sdk.catalog.workspace.aac import load_aac_workspace_from_disk, store_aac_workspace_to_disk +from gooddata_sdk.catalog.workspace.declarative_model.workspace.workspace import CatalogDeclarativeWorkspaceModel +from gooddata_sdk.utils import read_layout_from_file + +_FIXTURES_DIR = Path(__file__).parent / "aac_tests" + +_AUTHOR = { + "createdBy": {"id": "admin", "type": "user"}, + "createdAt": "2026-11-02 10:00", + "modifiedBy": {"id": "admin", "type": "user"}, + "modifiedAt": "2026-11-02 11:00", +} +_TEXT = {"type": "text", "id": "t1", "markdown": "Hello"} +_PAGES = [{"id": "p1", "kind": "content", "layout": {"type": "row", "children": [_TEXT]}}] +_DOCUMENT = { + "id": "doc_1", + "title": "Doc 1", + "description": "Monthly", + "tags": ["finance"], + "version": "2", + "period": {"type": "relative", "granularity": "GDC.time.month", "from": -1, "to": 0}, + "content": {"locale": "en-US", "pages": _PAGES, "futureField": {"nested": [1, {"deep": True}]}}, + **_AUTHOR, +} +_DOCUMENT_TEMPLATE = { + "id": "tpl_1", + "title": "Tpl 1", + "description": "Base", + "tags": ["finance"], + "version": "2", + "content": {"locale": "en-US", "pages": _PAGES}, +} +_PAGE_TEMPLATE = { + "id": "pt_1", + "title": "Page 1", + "description": "Cover", + "tags": ["finance"], + "version": "2", + "content": {"layout": _TEXT}, +} +_METRIC = {"id": "m1", "title": "Metric 1", "content": {"format": "#,##0", "maql": "SELECT 1"}} +_LAYOUT_KEYS = ("documents", "documentTemplates", "pageTemplates") + + +def _model(analytics: dict[str, Any]) -> CatalogDeclarativeWorkspaceModel: + return CatalogDeclarativeWorkspaceModel.from_dict({"analytics": analytics}) + + +def _publisher_model() -> CatalogDeclarativeWorkspaceModel: + return _model( + {"documents": [_DOCUMENT], "documentTemplates": [_DOCUMENT_TEMPLATE], "pageTemplates": [_PAGE_TEMPLATE]} + ) + + +def _reloaded_analytics(tmp_path: Path) -> dict[str, Any]: + return load_aac_workspace_from_disk(tmp_path).to_dict(camel_case=True).get("analytics", {}) + + +def test_store_writes_one_file_per_object(tmp_path: Path) -> None: + store_aac_workspace_to_disk(_publisher_model(), tmp_path) + common_keys = {"type", "id", "version", "title", "description", "tags", "content"} + + for path, aac_type, keys in ( + (tmp_path / "documents" / "doc_1.yaml", "document", common_keys | {"period"}), + (tmp_path / "documentTemplates" / "tpl_1.yaml", "document_template", common_keys), + (tmp_path / "pageTemplates" / "pt_1.yaml", "page_template", common_keys), + ): + assert path.is_file() + aac = read_layout_from_file(path) + assert aac["type"] == aac_type + assert aac["version"] == "2" + assert set(aac) == keys + + +def test_objects_round_trip_through_aac(tmp_path: Path) -> None: + store_aac_workspace_to_disk(_publisher_model(), tmp_path) + + analytics = _reloaded_analytics(tmp_path) + + document_without_author = {key: value for key, value in _DOCUMENT.items() if key not in _AUTHOR} + assert {key: analytics.get(key) for key in _LAYOUT_KEYS} == { + "documents": [document_without_author], + "documentTemplates": [_DOCUMENT_TEMPLATE], + "pageTemplates": [_PAGE_TEMPLATE], + } + + +def test_absolute_period_round_trips(tmp_path: Path) -> None: + document = {**_DOCUMENT, "period": {"type": "absolute", "from": "2026-01-01", "to": "2026-01-31"}} + store_aac_workspace_to_disk(_model({"documents": [document]}), tmp_path) + + period = _reloaded_analytics(tmp_path)["documents"][0]["period"] + + assert {key: period[key] for key in ("type", "from", "to")} == { + "type": "absolute", + "from": date(2026, 1, 1), + "to": date(2026, 1, 31), + } + + +def test_load_fixture_folders_beside_visualisations(tmp_path: Path) -> None: + for subdir in ("datasets", "metrics", "visualisations", "documents", "documentTemplates", "pageTemplates"): + shutil.copytree(_FIXTURES_DIR / subdir, tmp_path / subdir) + + model_dict = load_aac_workspace_from_disk(tmp_path).to_dict(camel_case=True) + ldm = model_dict.get("ldm", {}) + analytics = model_dict.get("analytics", {}) + + assert [obj["id"] for obj in analytics.get("documents", [])] == ["doc_1"] + assert [obj["id"] for obj in analytics.get("documentTemplates", [])] == ["tpl_1"] + assert [obj["id"] for obj in analytics.get("pageTemplates", [])] == ["pt_1"] + assert len(ldm.get("datasets", [])) == 2 + assert len(analytics.get("metrics", [])) == 1 + assert len(analytics.get("visualizationObjects", [])) == 2 + + +def test_workspace_without_documents_stores_as_today(tmp_path: Path) -> None: + store_aac_workspace_to_disk(_model({"metrics": [_METRIC]}), tmp_path) + + for subdir in _LAYOUT_KEYS: + assert not (tmp_path / subdir).exists() + assert (tmp_path / "metrics" / "m1.yaml").is_file() + + analytics = _reloaded_analytics(tmp_path) + for key in _LAYOUT_KEYS: + assert not analytics.get(key) + assert [metric["id"] for metric in analytics["metrics"]] == ["m1"] + + +@pytest.mark.parametrize( + ("layout_key", "obj", "aac_type"), + [ + ("documents", _DOCUMENT, "document"), + ("documentTemplates", _DOCUMENT_TEMPLATE, "document_template"), + ("pageTemplates", _PAGE_TEMPLATE, "page_template"), + ], +) +def test_store_refuses_non_v2_object(tmp_path: Path, layout_key: str, obj: dict[str, Any], aac_type: str) -> None: + model = _model({"metrics": [_METRIC], layout_key: [{**obj, "version": "1"}]}) + obj_id = obj["id"] + + with pytest.raises(ValueError, match=rf'{aac_type} "{obj_id}" \(version "1"\)'): + store_aac_workspace_to_disk(model, tmp_path) + + assert list(tmp_path.rglob("*.yaml")) == [] + + +def test_store_names_refused_template(tmp_path: Path) -> None: + model = _model({"documentTemplates": [{**_DOCUMENT_TEMPLATE, "content": {"locale": "en-US"}}]}) + + with pytest.raises(ValueError, match=r'document_template "tpl_1" \(version "2"\)'): + store_aac_workspace_to_disk(model, tmp_path) + + +def test_load_refuses_non_v2_file(tmp_path: Path) -> None: + fixture = (_FIXTURES_DIR / "documents" / "doc_1.yaml").read_text(encoding="utf-8") + (tmp_path / "documents").mkdir() + (tmp_path / "documents" / "doc_1.yaml").write_text( + fixture.replace('version: "2"', 'version: "1"'), encoding="utf-8" + ) + + with pytest.raises(ValueError, match=r'document "doc_1" \(version "1"\)'): + load_aac_workspace_from_disk(tmp_path) From fe58c73e02b542fa6ea6a3f99319de3b8fc0f186 Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Thu, 5 Nov 2026 15:46:32 +0100 Subject: [PATCH 09/12] fix(gooddata-eval): write dates in the generate snapshot An absolute-period Publisher document puts datetime.date values into the declarative layer the snapshot is taken from, and json.dumps refused them, so --snapshot-out failed on any workspace holding such a document. The write now turns date and datetime values into ISO strings and raises TypeError on any other value JSON cannot hold, so a replayed snapshot never carries a silently stringified value. Snapshots saved from now on carry documents. jira: LX-3447 risk: low Co-Authored-By: Claude Opus 5.5 Co-Authored-By: Claude Sonnet 5.5 --- .../core/dataset/from_insights.py | 11 +++- .../gooddata-eval/tests/test_from_insights.py | 50 +++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/packages/gooddata-eval/src/gooddata_eval/core/dataset/from_insights.py b/packages/gooddata-eval/src/gooddata_eval/core/dataset/from_insights.py index 029dd1373..7e30f2164 100644 --- a/packages/gooddata-eval/src/gooddata_eval/core/dataset/from_insights.py +++ b/packages/gooddata-eval/src/gooddata_eval/core/dataset/from_insights.py @@ -20,7 +20,7 @@ import re import sys import unicodedata -from datetime import datetime, timezone +from datetime import date, datetime, timezone from pathlib import Path from gooddata_sdk.catalog.workspace.aac import declarative_visualization_to_aac @@ -729,6 +729,13 @@ def _validation_errors(envelope: dict) -> str | None: return None +def _snapshot_json_default(value: object) -> str: + """JSON hook for the snapshot: dates and datetimes become ISO strings, anything else is refused.""" + if isinstance(value, date): + return value.isoformat() + raise TypeError(f"Object of type {type(value).__name__} is not JSON serializable") + + def generate(args, sdk_factory=None) -> int: """Run the whole generation pipeline. Returns a process exit code.""" if args.snapshot_in: @@ -738,7 +745,7 @@ def generate(args, sdk_factory=None) -> int: raise ValueError("a live run needs an SDK; pass --snapshot-in to replay a saved model instead") snapshot = fetch_snapshot(sdk_factory(), args.workspace) if args.snapshot_out: - Path(args.snapshot_out).write_text(json.dumps(snapshot, indent=2)) + Path(args.snapshot_out).write_text(json.dumps(snapshot, indent=2, default=_snapshot_json_default)) analytics = snapshot["analytics"] display_names = snapshot.get("display_names") or {} diff --git a/packages/gooddata-eval/tests/test_from_insights.py b/packages/gooddata-eval/tests/test_from_insights.py index 72bd0435e..dae62ecc6 100644 --- a/packages/gooddata-eval/tests/test_from_insights.py +++ b/packages/gooddata-eval/tests/test_from_insights.py @@ -1,5 +1,7 @@ # (C) 2026 GoodData Corporation import json +from datetime import date, datetime +from pathlib import Path from types import SimpleNamespace from unittest.mock import patch @@ -1000,6 +1002,54 @@ def fake_fetch(sdk, workspace_id): assert json.loads((tmp_path / "snap-out.json").read_text())["workspace_id"] == "ws" +def test_generate_saves_a_snapshot_with_an_absolute_period_document(tmp_path: Path) -> None: + # The declarative layer parses an absolute document period into dates, which plain JSON cannot hold. + class _Sdk: + pass + + snapshot = _snapshot(_bar("spend", "merchant.NAME")) + snapshot["analytics"]["documents"] = [ + { + "id": "doc_1", + "period": { + "type": "absolute", + "granularity": "GDC.time.date", + "from": date(2026, 1, 1), + "to": date(2026, 1, 31), + }, + "modifiedAt": datetime(2026, 1, 15, 9, 30), + } + ] + + args = _args(tmp_path, snapshot_out=str(tmp_path / "snap-out.json")) + with patch.object(from_insights_mod, "fetch_snapshot", lambda sdk, workspace_id: snapshot): + assert generate(args, sdk_factory=_Sdk) == 0 + + saved = json.loads((tmp_path / "snap-out.json").read_text()) + assert isinstance(saved, dict) + document = saved["analytics"]["documents"][0] + assert (document["period"]["from"], document["period"]["to"]) == ("2026-01-01", "2026-01-31") + assert document["modifiedAt"] == "2026-01-15T09:30:00" + + +def test_generate_refuses_to_save_a_snapshot_value_json_cannot_hold(tmp_path: Path) -> None: + class _Sdk: + pass + + snapshot = _snapshot(_bar("spend", "merchant.NAME")) + snapshot["analytics"]["documents"] = [{"id": "doc_1", "tags": {"a", "b"}}] + + out = tmp_path / "snap-out.json" + args = _args(tmp_path, snapshot_out=str(out)) + with ( + patch.object(from_insights_mod, "fetch_snapshot", lambda sdk, workspace_id: snapshot), + pytest.raises(TypeError, match="set"), + ): + generate(args, sdk_factory=_Sdk) + + assert not out.exists() + + def test_generate_without_a_snapshot_or_an_sdk_says_which_is_missing(tmp_path): with pytest.raises(ValueError, match="snapshot-in"): generate(_args(tmp_path)) From 1e28403c06a9e1e778a30cf9238e3e2c445fcc7a Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Thu, 5 Nov 2026 15:46:45 +0100 Subject: [PATCH 10/12] test(gooddata-sdk): cover documents in the analytics layout round trip The new service test seeds a workspace with one document, carrying an absolute period and author fields, one document template and one page template. It then reads, stores, loads and puts the analytics model and checks that all three survive, the document with its four author fields unchanged. The same scenario run against the SDK before the document models leaves the workspace with no documents. The backend omits documents, documentTemplates and pageTemplates from layout responses when they are empty, while the SDK always emits them. The two tests comparing the SDK dictionary with the raw layout fill those keys on the raw side through one helper, and stay exact on every other key. The expected layouts gain the three lists. upload_demo_layout.py, which make load-staging runs, now treats a 201 from user creation as success, the status the backend returns for it now; before, the layout load crashed on it. jira: LX-3447 risk: nonprod Co-Authored-By: Claude Opus 5.5 --- .../expected/declarative_analytics_model.json | 5 +- .../declarative_analytics_model_child.json | 5 +- ...declarative_analytics_model_documents.json | 57 +++++++++++++++++++ .../expected/declarative_workspaces.json | 9 +++ .../declarative_workspaces_snake_case.json | 15 ++++- .../refresh/declarative_workspaces.json | 15 ++++- .../tests/catalog/test_catalog_workspace.py | 28 +++++++-- .../catalog/test_catalog_workspace_content.py | 41 +++++++++++++ packages/tests-support/upload_demo_layout.py | 2 +- 9 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model_documents.json diff --git a/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model.json b/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model.json index 1c29509de..46be3b508 100644 --- a/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model.json +++ b/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model.json @@ -2252,6 +2252,9 @@ ], "exportDefinitions": [], "memoryItems": [], - "parameters": [] + "parameters": [], + "documents": [], + "documentTemplates": [], + "pageTemplates": [] } } diff --git a/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model_child.json b/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model_child.json index 15d9f3fd2..a6b8565da 100644 --- a/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model_child.json +++ b/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model_child.json @@ -21,6 +21,9 @@ "visualizationObjects": [], "exportDefinitions": [], "memoryItems": [], - "parameters": [] + "parameters": [], + "documents": [], + "documentTemplates": [], + "pageTemplates": [] } } diff --git a/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model_documents.json b/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model_documents.json new file mode 100644 index 000000000..ad31b77d8 --- /dev/null +++ b/packages/gooddata-sdk/tests/catalog/expected/declarative_analytics_model_documents.json @@ -0,0 +1,57 @@ +{ + "analytics": { + "documents": [ + { + "id": "doc_1", + "title": "Doc 1", + "description": "Monthly", + "tags": ["finance"], + "version": "2", + "period": {"type": "absolute", "granularity": "GDC.time.date", "from": "2026-01-01", "to": "2026-01-31"}, + "content": { + "locale": "en-US", + "pages": [ + { + "id": "p1", + "kind": "content", + "layout": {"type": "row", "children": [{"type": "text", "id": "t1", "markdown": "Hello"}]} + } + ] + }, + "createdBy": {"id": "admin", "type": "user"}, + "createdAt": "2000-01-01 00:00", + "modifiedBy": {"id": "admin", "type": "user"}, + "modifiedAt": "2026-11-02 11:00" + } + ], + "documentTemplates": [ + { + "id": "tpl_1", + "title": "Tpl 1", + "description": "Brand review", + "tags": ["brand"], + "version": "2", + "content": { + "locale": "en-US", + "pages": [ + { + "id": "p1", + "kind": "content", + "layout": {"type": "row", "children": [{"type": "text", "id": "t1", "markdown": "Hello"}]} + } + ] + } + } + ], + "pageTemplates": [ + { + "id": "pt_1", + "title": "Page 1", + "description": "Cover", + "tags": ["brand"], + "version": "2", + "content": {"layout": {"type": "text", "id": "t1", "markdown": "Hello"}} + } + ] + } +} diff --git a/packages/gooddata-sdk/tests/catalog/expected/declarative_workspaces.json b/packages/gooddata-sdk/tests/catalog/expected/declarative_workspaces.json index 63307cf61..3d99ffa8d 100644 --- a/packages/gooddata-sdk/tests/catalog/expected/declarative_workspaces.json +++ b/packages/gooddata-sdk/tests/catalog/expected/declarative_workspaces.json @@ -469,6 +469,9 @@ "title": "dashboard_plugin_2" } ], + "documentTemplates": [], + "documents": [], + "pageTemplates": [], "exportDefinitions": [], "filterContexts": [ { @@ -2944,6 +2947,9 @@ "analyticalDashboards": [], "attributeHierarchies": [], "dashboardPlugins": [], + "documentTemplates": [], + "documents": [], + "pageTemplates": [], "exportDefinitions": [], "filterContexts": [], "metrics": [], @@ -2991,6 +2997,9 @@ "analyticalDashboards": [], "attributeHierarchies": [], "dashboardPlugins": [], + "documentTemplates": [], + "documents": [], + "pageTemplates": [], "exportDefinitions": [], "filterContexts": [], "metrics": [], diff --git a/packages/gooddata-sdk/tests/catalog/expected/declarative_workspaces_snake_case.json b/packages/gooddata-sdk/tests/catalog/expected/declarative_workspaces_snake_case.json index 18ed0ff0e..f5ea2bdc2 100644 --- a/packages/gooddata-sdk/tests/catalog/expected/declarative_workspaces_snake_case.json +++ b/packages/gooddata-sdk/tests/catalog/expected/declarative_workspaces_snake_case.json @@ -2815,7 +2815,10 @@ ], "export_definitions": [], "memory_items": [], - "parameters": [] + "parameters": [], + "documents": [], + "document_templates": [], + "page_templates": [] } }, "permissions": [ @@ -2900,7 +2903,10 @@ "visualization_objects": [], "export_definitions": [], "memory_items": [], - "parameters": [] + "parameters": [], + "documents": [], + "document_templates": [], + "page_templates": [] } }, "parent": { @@ -2932,7 +2938,10 @@ "visualization_objects": [], "export_definitions": [], "memory_items": [], - "parameters": [] + "parameters": [], + "documents": [], + "document_templates": [], + "page_templates": [] } }, "parent": { diff --git a/packages/gooddata-sdk/tests/catalog/refresh/declarative_workspaces.json b/packages/gooddata-sdk/tests/catalog/refresh/declarative_workspaces.json index bce96638c..67557a010 100644 --- a/packages/gooddata-sdk/tests/catalog/refresh/declarative_workspaces.json +++ b/packages/gooddata-sdk/tests/catalog/refresh/declarative_workspaces.json @@ -2873,7 +2873,10 @@ ], "exportDefinitions": [], "memoryItems": [], - "parameters": [] + "parameters": [], + "documents": [], + "documentTemplates": [], + "pageTemplates": [] } }, "permissions": [ @@ -2959,7 +2962,10 @@ "visualizationObjects": [], "exportDefinitions": [], "memoryItems": [], - "parameters": [] + "parameters": [], + "documents": [], + "documentTemplates": [], + "pageTemplates": [] } }, "parent": { @@ -2992,7 +2998,10 @@ "visualizationObjects": [], "exportDefinitions": [], "memoryItems": [], - "parameters": [] + "parameters": [], + "documents": [], + "documentTemplates": [], + "pageTemplates": [] } }, "parent": { diff --git a/packages/gooddata-sdk/tests/catalog/test_catalog_workspace.py b/packages/gooddata-sdk/tests/catalog/test_catalog_workspace.py index c82163af0..91de1448b 100644 --- a/packages/gooddata-sdk/tests/catalog/test_catalog_workspace.py +++ b/packages/gooddata-sdk/tests/catalog/test_catalog_workspace.py @@ -3,6 +3,7 @@ import json from pathlib import Path +from typing import Any from xml.etree import ElementTree as ET import yaml @@ -47,6 +48,18 @@ _current_dir = Path(__file__).parent.absolute() _fixtures_dir = _current_dir / "fixtures" / "workspaces" +# The backend omits these analytics lists from a layout response when they are empty, while the SDK model +# always emits them. +_ANALYTICS_LISTS_OMITTED_WHEN_EMPTY = ("documents", "documentTemplates", "pageTemplates") + + +def _fill_lists_omitted_when_empty(workspace_model: dict[str, Any]) -> dict[str, Any]: + analytics = workspace_model.get("analytics") + if analytics is not None: + for key in _ANALYTICS_LISTS_OMITTED_WHEN_EMPTY: + analytics.setdefault(key, []) + return workspace_model + def _empty_workspaces(sdk: GoodDataSdk) -> None: empty_workspaces_e = CatalogDeclarativeWorkspaces.from_api({"workspaces": [], "workspace_data_filters": []}) @@ -186,9 +199,10 @@ def test_declarative_workspaces(test_config): assert len(workspaces_o.workspaces) == 3 assert len(workspaces_o.workspace_data_filters) == 2 assert [workspace.id for workspace in workspaces_o.workspaces] == ["demo", "demo_west", "demo_west_california"] - assert workspaces_o.to_dict(camel_case=True) == layout_api.get_workspaces_layout(exclude=["ACTIVITY_INFO"]).to_dict( - camel_case=True - ) + workspaces_raw = layout_api.get_workspaces_layout(exclude=["ACTIVITY_INFO"]).to_dict(camel_case=True) + for workspace_raw in workspaces_raw["workspaces"]: + _fill_lists_omitted_when_empty(workspace_raw["model"]) + assert workspaces_o.to_dict(camel_case=True) == workspaces_raw @gd_vcr.use_cassette(str(_fixtures_dir / "demo_update_workspace_invalid.yaml")) @@ -593,9 +607,11 @@ def test_get_declarative_workspace(test_config): assert len(workspace.analytics.filter_contexts) == 2 assert len(workspace.analytics.metrics) == 24 assert len(workspace.analytics.visualization_objects) == 15 - assert workspace.to_dict(camel_case=True) == layout_api.get_workspace_layout( - workspace_id=test_config["workspace"], exclude=["ACTIVITY_INFO"] - ).to_dict(camel_case=True) + assert workspace.to_dict(camel_case=True) == _fill_lists_omitted_when_empty( + layout_api.get_workspace_layout(workspace_id=test_config["workspace"], exclude=["ACTIVITY_INFO"]).to_dict( + camel_case=True + ) + ) @gd_vcr.use_cassette(str(_fixtures_dir / "demo_put_declarative_workspace.yaml")) diff --git a/packages/gooddata-sdk/tests/catalog/test_catalog_workspace_content.py b/packages/gooddata-sdk/tests/catalog/test_catalog_workspace_content.py index 312088e9f..5e214c2fd 100644 --- a/packages/gooddata-sdk/tests/catalog/test_catalog_workspace_content.py +++ b/packages/gooddata-sdk/tests/catalog/test_catalog_workspace_content.py @@ -7,6 +7,7 @@ from unittest.mock import MagicMock import attrs +from gooddata_api_client.model.declarative_analytics import DeclarativeAnalytics from gooddata_sdk import ( CatalogDatasetWorkspaceDataFilterIdentifier, CatalogDeclarativeAnalytics, @@ -21,6 +22,7 @@ CatalogValidateByItem, CatalogWorkspace, DataSourceValidator, + GoodDataApiClient, GoodDataSdk, ObjId, ) @@ -239,6 +241,45 @@ def test_put_declarative_analytics_model(test_config): safe_delete(_refresh_workspaces, sdk) +@gd_vcr.use_cassette(str(_fixtures_dir / "demo_documents_store_load_and_put.yaml")) +def test_documents_survive_store_load_and_put(test_config): + sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"]) + layout_api = GoodDataApiClient(host=test_config["host"], token=test_config["token"]).layout_api + identifier = test_documents_survive_store_load_and_put.__name__ + path = _current_dir / "store" / "documents" + recreate_directory(path) + # The seed's createdAt is the cassette normalizer's canonical value, so a replayed read returns + # the same author fields a recording run sees. + with open(_current_dir / "expected" / "declarative_analytics_model_documents.json") as f: + seed = json.load(f) + seed_document = seed["analytics"]["documents"][0] + + try: + _set_up_workspace_ldm(sdk, test_config["workspace"], identifier) + layout_api.set_analytics_model(identifier, DeclarativeAnalytics.from_dict(seed, camel_case=True)) + analytics_model_e = sdk.catalog_workspace_content.get_declarative_analytics_model(identifier) + + sdk.catalog_workspace_content.store_declarative_analytics_model(identifier, path) + loaded = sdk.catalog_workspace_content.load_declarative_analytics_model(identifier, path) + sdk.catalog_workspace_content.put_declarative_analytics_model(identifier, loaded) + + analytics_raw = layout_api.get_analytics_model(identifier).analytics + assert len(analytics_raw.get("documents", [])) == 1 + assert len(analytics_raw.get("document_templates", [])) == 1 + assert len(analytics_raw.get("page_templates", [])) == 1 + + analytics_model_o = sdk.catalog_workspace_content.get_declarative_analytics_model(identifier) + assert deep_eq(analytics_model_e, analytics_model_o) + assert deep_eq(analytics_model_e.to_api().to_dict(), analytics_model_o.to_api().to_dict()) + document = analytics_model_o.analytics.documents[0] + assert document.created_by.id == seed_document["createdBy"]["id"] + assert document.created_at == seed_document["createdAt"] + assert document.modified_by.id == seed_document["modifiedBy"]["id"] + assert document.modified_at == seed_document["modifiedAt"] + finally: + safe_delete(_refresh_workspaces, sdk) + + @gd_vcr.use_cassette(str(_fixtures_dir / "demo_put_declarative_ldm.yaml")) def test_put_declarative_ldm(test_config): sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"]) diff --git a/packages/tests-support/upload_demo_layout.py b/packages/tests-support/upload_demo_layout.py index cfcd06efa..d7ff6b074 100644 --- a/packages/tests-support/upload_demo_layout.py +++ b/packages/tests-support/upload_demo_layout.py @@ -65,7 +65,7 @@ def rest_op(op, url_path, data=None, raise_ex=True): else: return None - if response.status_code == 200: + if response.status_code in (200, 201): return response.json() else: return None From ed3f50cf5b9b110797e0da370352dd1b06655a9d Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Thu, 5 Nov 2026 16:57:18 +0100 Subject: [PATCH 11/12] chore(gooddata-sdk): record layout cassettes with publisher documents The SDK now sends documents, documentTemplates and pageTemplates in every analytics layout it puts, and the backend returns them, so the 15 cassettes that replay a layout read or put no longer matched. They are re-recorded, and the document round-trip test gets its own cassette. All 16 were recorded on the python-sdk-dex staging environment with ENABLE_METRIC_PERMISSIONS and ENABLE_VISUALIZATION_PERMISSIONS off, and are committed as recorded, unedited. With those flags on, the backend adds grants on metrics and visualization objects and the metricExtensions and visualizationObjectExtensions lists, which the SDK does not model yet (PSDK-236), and the raw-layout tests fail on them. Dashboard grants are recorded as returned. A separate recording on a local stack agrees with these on every interaction and on everything the tests assert. It differs only in values no test reads: the organization's region, dataCenter and allowedOrigins fields, the content type and type field of not-found errors, and the content-length header. jira: LX-3447 risk: nonprod Co-Authored-By: Claude Opus 5.5 --- .../demo_documents_store_load_and_put.yaml | 3555 +++++++++++++++++ .../demo_get_declarative_analytics_model.yaml | 2 + ...d_and_put_declarative_analytics_model.yaml | 23 + .../demo_put_declarative_analytics_model.yaml | 21 +- .../export_definition_analytics_layout.yaml | 16 + .../workspaces/demo_clone_workspace.yaml | 62 +- .../demo_declarative_workspaces.yaml | 4 + .../demo_get_declarative_workspace.yaml | 4 + .../demo_get_declarative_workspaces.yaml | 2 + ...get_declarative_workspaces_snake_case.yaml | 2 + ...mo_load_and_put_declarative_workspace.yaml | 16 + ...o_load_and_put_declarative_workspaces.yaml | 20 + .../demo_put_declarative_workspace.yaml | 23 +- .../demo_put_declarative_workspaces.yaml | 22 + .../workspaces/demo_translate_workspace.yaml | 25 +- 15 files changed, 3783 insertions(+), 14 deletions(-) create mode 100644 packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_documents_store_load_and_put.yaml diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_documents_store_load_and_put.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_documents_store_load_and_put.yaml new file mode 100644 index 000000000..1640263be --- /dev/null +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_documents_store_load_and_put.yaml @@ -0,0 +1,3555 @@ +# (C) 2026 GoodData Corporation +interactions: + - request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: GET + uri: http://localhost:3000/api/v1/entities/workspaces/test_documents_survive_store_load_and_put?include=workspaces + response: + body: + string: + detail: The requested endpoint does not exist or you do not have permission + to access it. + status: 404 + title: Not Found + traceId: NORMALIZED_TRACE_ID_000000000000 + headers: + Content-Type: + - application/json + DATE: &id001 + - PLACEHOLDER + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + status: + code: 404 + message: Not Found + - request: + body: + data: + attributes: + name: test_documents_survive_store_load_and_put + id: test_documents_survive_store_load_and_put + type: workspace + headers: + Accept: + - application/json + Accept-Encoding: + - br, gzip, deflate + Content-Type: + - application/json + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: POST + uri: http://localhost:3000/api/v1/entities/workspaces + response: + body: + string: + data: + attributes: + name: test_documents_survive_store_load_and_put + id: test_documents_survive_store_load_and_put + type: workspace + links: + self: http://localhost:3000/api/v1/entities/workspaces/test_documents_survive_store_load_and_put + headers: + Content-Type: + - application/json + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 201 + message: Created + - request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: GET + uri: http://localhost:3000/api/v1/layout/workspaces/demo/logicalModel + response: + body: + string: + ldm: + datasets: + - aggregatedFacts: [] + attributes: + - description: Campaign channel id + id: campaign_channel_id + isNullable: false + labels: [] + sourceColumn: campaign_channel_id + sourceColumnDataType: STRING + tags: + - Campaign channels + title: Campaign channel id + - description: Category + id: campaign_channels.category + isNullable: true + labels: [] + sourceColumn: category + sourceColumnDataType: STRING + tags: + - Campaign channels + title: Category + - description: Type + id: type + isNullable: true + labels: [] + sourceColumn: type + sourceColumnDataType: STRING + tags: + - Campaign channels + title: Type + dataSourceTableId: + dataSourceId: demo-test-ds + id: campaign_channels + path: + - demo + - campaign_channels + type: dataSource + description: Campaign channels + facts: + - description: Budget + id: budget + isNullable: true + sourceColumn: budget + sourceColumnDataType: NUMERIC + tags: + - Campaign channels + title: Budget + - description: Spend + id: spend + isNullable: true + sourceColumn: spend + sourceColumnDataType: NUMERIC + tags: + - Campaign channels + title: Spend + grain: + - id: campaign_channel_id + type: attribute + id: campaign_channels + references: + - identifier: + id: campaigns + type: dataset + multivalue: false + sources: + - column: campaign_id + dataType: INT + isNullable: true + target: + id: campaign_id + type: attribute + tags: + - Campaign channels + title: Campaign channels + - aggregatedFacts: + - description: Budget Agg + id: budget_agg + sourceColumn: budget + sourceColumnDataType: INT + sourceFactReference: + operation: SUM + reference: + id: budget + type: fact + tags: + - Campaign channels per category + attributes: [] + description: Campaign channels per categories + facts: [] + grain: [] + id: campaign_channels_per_category + precedence: 1 + references: + - identifier: + id: campaign_channels + type: dataset + multivalue: false + sources: + - column: campaign_channel_id + dataType: STRING + isNullable: true + target: + id: campaign_channel_id + type: attribute + sql: + dataSourceId: demo-test-ds + statement: SELECT category, SUM(budget) FROM campaign_channels GROUP + BY category + tags: + - Campaign channels per category + title: Campaign channels per category + - aggregatedFacts: [] + attributes: + - description: Campaign id + id: campaign_id + isNullable: false + labels: [] + sourceColumn: campaign_id + sourceColumnDataType: INT + tags: + - Campaigns + title: Campaign id + - description: Campaign name + id: campaign_name + isNullable: true + labels: [] + sourceColumn: campaign_name + sourceColumnDataType: STRING + tags: + - Campaigns + title: Campaign name + dataSourceTableId: + dataSourceId: demo-test-ds + id: campaigns + path: + - demo + - campaigns + type: dataSource + description: Campaigns + facts: [] + grain: + - id: campaign_id + type: attribute + id: campaigns + references: [] + tags: + - Campaigns + title: Campaigns + - aggregatedFacts: [] + attributes: + - description: Customer id + id: customer_id + isNullable: false + labels: [] + sourceColumn: customer_id + sourceColumnDataType: INT + tags: + - Customers + title: Customer id + - description: Customer name + id: customer_name + isNullable: true + labels: [] + sourceColumn: customer_name + sourceColumnDataType: STRING + tags: + - Customers + title: Customer name + - description: Region + id: region + isNullable: true + labels: [] + sourceColumn: region + sourceColumnDataType: STRING + tags: + - Customers + title: Region + - description: State + id: state + isNullable: true + labels: + - description: Location + id: geo__state__location + isNullable: true + sourceColumn: geo__state__location + sourceColumnDataType: STRING + tags: + - Customers + title: Location + valueType: GEO + sourceColumn: state + sourceColumnDataType: STRING + tags: + - Customers + title: State + dataSourceTableId: + dataSourceId: demo-test-ds + id: customers + path: + - demo + - customers + type: dataSource + description: Customers + facts: [] + grain: + - id: customer_id + type: attribute + id: customers + references: [] + tags: + - Customers + title: Customers + - aggregatedFacts: [] + attributes: + - description: Order id + id: order_id + isNullable: true + labels: [] + sourceColumn: order_id + sourceColumnDataType: STRING + tags: + - Order lines + title: Order id + - description: Order line id + id: order_line_id + isNullable: false + labels: [] + sourceColumn: order_line_id + sourceColumnDataType: STRING + tags: + - Order lines + title: Order line id + - description: Order status + id: order_status + isNullable: true + labels: [] + sourceColumn: order_status + sourceColumnDataType: STRING + tags: + - Order lines + title: Order status + dataSourceTableId: + dataSourceId: demo-test-ds + id: order_lines + path: + - demo + - order_lines + type: dataSource + description: Order lines + facts: + - description: Price + id: price + isNullable: true + sourceColumn: price + sourceColumnDataType: NUMERIC + tags: + - Order lines + title: Price + - description: Quantity + id: quantity + isNullable: true + sourceColumn: quantity + sourceColumnDataType: NUMERIC + tags: + - Order lines + title: Quantity + grain: + - id: order_line_id + type: attribute + id: order_lines + references: + - identifier: + id: campaigns + type: dataset + multivalue: false + sources: + - column: campaign_id + dataType: INT + isNullable: true + target: + id: campaign_id + type: attribute + - identifier: + id: customers + type: dataset + multivalue: false + sources: + - column: customer_id + dataType: INT + isNullable: true + target: + id: customer_id + type: attribute + - identifier: + id: date + type: dataset + multivalue: false + sources: + - column: date + dataType: DATE + isNullable: true + target: + id: date + type: date + - identifier: + id: products + type: dataset + multivalue: false + sources: + - column: product_id + dataType: INT + isNullable: true + target: + id: product_id + type: attribute + tags: + - Order lines + title: Order lines + workspaceDataFilterColumns: + - dataType: STRING + name: wdf__region + - dataType: STRING + name: wdf__state + workspaceDataFilterReferences: + - filterColumn: wdf__region + filterColumnDataType: STRING + filterId: + id: wdf__region + type: workspaceDataFilter + - aggregatedFacts: [] + attributes: + - description: Product id + id: product_id + isNullable: false + labels: [] + sourceColumn: product_id + sourceColumnDataType: INT + tags: + - Products + title: Product id + - description: Product name + id: product_name + isNullable: true + labels: [] + sourceColumn: product_name + sourceColumnDataType: STRING + tags: + - Products + title: Product name + - description: Category + id: products.category + isNullable: true + labels: [] + sourceColumn: category + sourceColumnDataType: STRING + tags: + - Products + title: Category + dataSourceTableId: + dataSourceId: demo-test-ds + id: products + path: + - demo + - products + type: dataSource + description: Products + facts: [] + grain: + - id: product_id + type: attribute + id: products + references: [] + tags: + - Products + title: Products + dateInstances: + - description: '' + granularities: + - DAY + - WEEK + - MONTH + - QUARTER + - YEAR + granularitiesFormatting: + titleBase: '' + titlePattern: '%titleBase - %granularityTitle' + id: date + tags: + - Date + title: Date + headers: + Content-Type: + - application/json + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + content-length: + - '7492' + status: + code: 200 + message: OK + - request: + body: + ldm: + datasets: + - aggregatedFacts: [] + attributes: + - description: Campaign channel id + id: campaign_channel_id + isNullable: false + labels: [] + sourceColumn: campaign_channel_id + sourceColumnDataType: STRING + tags: + - Campaign channels + title: Campaign channel id + - description: Category + id: campaign_channels.category + isNullable: true + labels: [] + sourceColumn: category + sourceColumnDataType: STRING + tags: + - Campaign channels + title: Category + - description: Type + id: type + isNullable: true + labels: [] + sourceColumn: type + sourceColumnDataType: STRING + tags: + - Campaign channels + title: Type + dataSourceTableId: + dataSourceId: demo-test-ds + id: campaign_channels + path: + - demo + - campaign_channels + type: dataSource + description: Campaign channels + facts: + - description: Budget + id: budget + isNullable: true + sourceColumn: budget + sourceColumnDataType: NUMERIC + tags: + - Campaign channels + title: Budget + - description: Spend + id: spend + isNullable: true + sourceColumn: spend + sourceColumnDataType: NUMERIC + tags: + - Campaign channels + title: Spend + grain: + - id: campaign_channel_id + type: attribute + id: campaign_channels + references: + - identifier: + id: campaigns + type: dataset + multivalue: false + sources: + - column: campaign_id + dataType: INT + isNullable: true + target: + id: campaign_id + type: attribute + tags: + - Campaign channels + title: Campaign channels + - aggregatedFacts: + - description: Budget Agg + id: budget_agg + sourceColumn: budget + sourceColumnDataType: INT + sourceFactReference: + operation: SUM + reference: + id: budget + type: fact + tags: + - Campaign channels per category + attributes: [] + description: Campaign channels per categories + facts: [] + grain: [] + id: campaign_channels_per_category + precedence: 1 + references: + - identifier: + id: campaign_channels + type: dataset + multivalue: false + sources: + - column: campaign_channel_id + dataType: STRING + isNullable: true + target: + id: campaign_channel_id + type: attribute + sql: + dataSourceId: demo-test-ds + statement: SELECT category, SUM(budget) FROM campaign_channels GROUP + BY category + tags: + - Campaign channels per category + title: Campaign channels per category + - aggregatedFacts: [] + attributes: + - description: Campaign id + id: campaign_id + isNullable: false + labels: [] + sourceColumn: campaign_id + sourceColumnDataType: INT + tags: + - Campaigns + title: Campaign id + - description: Campaign name + id: campaign_name + isNullable: true + labels: [] + sourceColumn: campaign_name + sourceColumnDataType: STRING + tags: + - Campaigns + title: Campaign name + dataSourceTableId: + dataSourceId: demo-test-ds + id: campaigns + path: + - demo + - campaigns + type: dataSource + description: Campaigns + facts: [] + grain: + - id: campaign_id + type: attribute + id: campaigns + references: [] + tags: + - Campaigns + title: Campaigns + - aggregatedFacts: [] + attributes: + - description: Customer id + id: customer_id + isNullable: false + labels: [] + sourceColumn: customer_id + sourceColumnDataType: INT + tags: + - Customers + title: Customer id + - description: Customer name + id: customer_name + isNullable: true + labels: [] + sourceColumn: customer_name + sourceColumnDataType: STRING + tags: + - Customers + title: Customer name + - description: Region + id: region + isNullable: true + labels: [] + sourceColumn: region + sourceColumnDataType: STRING + tags: + - Customers + title: Region + - description: State + id: state + isNullable: true + labels: + - description: Location + id: geo__state__location + isNullable: true + sourceColumn: geo__state__location + sourceColumnDataType: STRING + tags: + - Customers + title: Location + valueType: GEO + sourceColumn: state + sourceColumnDataType: STRING + tags: + - Customers + title: State + dataSourceTableId: + dataSourceId: demo-test-ds + id: customers + path: + - demo + - customers + type: dataSource + description: Customers + facts: [] + grain: + - id: customer_id + type: attribute + id: customers + references: [] + tags: + - Customers + title: Customers + - aggregatedFacts: [] + attributes: + - description: Order id + id: order_id + isNullable: true + labels: [] + sourceColumn: order_id + sourceColumnDataType: STRING + tags: + - Order lines + title: Order id + - description: Order line id + id: order_line_id + isNullable: false + labels: [] + sourceColumn: order_line_id + sourceColumnDataType: STRING + tags: + - Order lines + title: Order line id + - description: Order status + id: order_status + isNullable: true + labels: [] + sourceColumn: order_status + sourceColumnDataType: STRING + tags: + - Order lines + title: Order status + dataSourceTableId: + dataSourceId: demo-test-ds + id: order_lines + path: + - demo + - order_lines + type: dataSource + description: Order lines + facts: + - description: Price + id: price + isNullable: true + sourceColumn: price + sourceColumnDataType: NUMERIC + tags: + - Order lines + title: Price + - description: Quantity + id: quantity + isNullable: true + sourceColumn: quantity + sourceColumnDataType: NUMERIC + tags: + - Order lines + title: Quantity + grain: + - id: order_line_id + type: attribute + id: order_lines + references: + - identifier: + id: campaigns + type: dataset + multivalue: false + sources: + - column: campaign_id + dataType: INT + isNullable: true + target: + id: campaign_id + type: attribute + - identifier: + id: customers + type: dataset + multivalue: false + sources: + - column: customer_id + dataType: INT + isNullable: true + target: + id: customer_id + type: attribute + - identifier: + id: date + type: dataset + multivalue: false + sources: + - column: date + dataType: DATE + isNullable: true + target: + id: date + type: date + - identifier: + id: products + type: dataset + multivalue: false + sources: + - column: product_id + dataType: INT + isNullable: true + target: + id: product_id + type: attribute + tags: + - Order lines + title: Order lines + workspaceDataFilterColumns: + - dataType: STRING + name: wdf__region + - dataType: STRING + name: wdf__state + - aggregatedFacts: [] + attributes: + - description: Product id + id: product_id + isNullable: false + labels: [] + sourceColumn: product_id + sourceColumnDataType: INT + tags: + - Products + title: Product id + - description: Product name + id: product_name + isNullable: true + labels: [] + sourceColumn: product_name + sourceColumnDataType: STRING + tags: + - Products + title: Product name + - description: Category + id: products.category + isNullable: true + labels: [] + sourceColumn: category + sourceColumnDataType: STRING + tags: + - Products + title: Category + dataSourceTableId: + dataSourceId: demo-test-ds + id: products + path: + - demo + - products + type: dataSource + description: Products + facts: [] + grain: + - id: product_id + type: attribute + id: products + references: [] + tags: + - Products + title: Products + dateInstances: + - description: '' + granularities: + - DAY + - WEEK + - MONTH + - QUARTER + - YEAR + granularitiesFormatting: + titleBase: '' + titlePattern: '%titleBase - %granularityTitle' + id: date + tags: + - Date + title: Date + headers: + Accept-Encoding: + - br, gzip, deflate + Content-Type: + - application/json + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: PUT + uri: http://localhost:3000/api/v1/layout/workspaces/test_documents_survive_store_load_and_put/logicalModel + response: + body: + string: '' + headers: + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 204 + message: No Content + - request: + body: + analytics: + documentTemplates: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + description: Brand review + id: tpl_1 + tags: + - brand + title: Tpl 1 + version: '2' + documents: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + createdAt: 2000-01-01 00:00 + createdBy: + id: admin + type: user + description: Monthly + id: doc_1 + modifiedAt: 2026-11-02 11:00 + modifiedBy: + id: admin + type: user + period: + from: '2026-01-01' + granularity: GDC.time.date + to: '2026-01-31' + type: absolute + tags: + - finance + title: Doc 1 + version: '2' + pageTemplates: + - content: + layout: + id: t1 + markdown: Hello + type: text + description: Cover + id: pt_1 + tags: + - brand + title: Page 1 + version: '2' + headers: + Accept-Encoding: + - br, gzip, deflate + Content-Type: + - application/json + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: PUT + uri: http://localhost:3000/api/v1/layout/workspaces/test_documents_survive_store_load_and_put/analyticsModel + response: + body: + string: '' + headers: + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 204 + message: No Content + - request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: GET + uri: http://localhost:3000/api/v1/layout/workspaces/test_documents_survive_store_load_and_put/analyticsModel + response: + body: + string: + analytics: + analyticalDashboardExtensions: [] + analyticalDashboards: [] + attributeHierarchies: [] + dashboardPlugins: [] + documentTemplates: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + description: Brand review + id: tpl_1 + tags: + - brand + title: Tpl 1 + version: '2' + documents: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + createdAt: 2000-01-01 00:00 + createdBy: + id: admin + type: user + description: Monthly + id: doc_1 + modifiedAt: 2026-11-02 11:00 + modifiedBy: + id: admin + type: user + period: + from: '2026-01-01' + granularity: GDC.time.date + to: '2026-01-31' + type: absolute + tags: + - finance + title: Doc 1 + version: '2' + exportDefinitions: [] + filterContexts: [] + memoryItems: [] + metrics: [] + pageTemplates: + - content: + layout: + id: t1 + markdown: Hello + type: text + description: Cover + id: pt_1 + tags: + - brand + title: Page 1 + version: '2' + parameters: [] + visualizationObjects: [] + headers: + Content-Type: + - application/json + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + content-length: + - '1165' + status: + code: 200 + message: OK + - request: + body: null + headers: + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: GET + uri: http://localhost:3000/api/v1/entities/organization + response: + body: + string: '' + headers: + Content-Type: + - application/vnd.gooddata.api+json + DATE: *id001 + Expires: + - '0' + Location: + - /api/v1/entities/admin/organizations/default + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 302 + message: Found + - request: + body: null + headers: + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: GET + uri: http://localhost:3000/api/v1/entities/admin/organizations/default + response: + body: + string: + data: + attributes: + allowedOrigins: [] + dataCenter: '' + earlyAccess: enableAlerting + earlyAccessValues: + - enableAlerting + - enableSmtp + - enablePreAggregationDatasets + - enableScheduling + - enableCompositeGrain + - enableUserManagement + - enableRawExports + - enableFlexibleDashboardLayout + hostname: localhost + name: Default Organization + region: '' + id: default + type: organization + links: + self: http://localhost:3000/api/v1/entities/admin/organizations/default + headers: + Content-Type: + - application/vnd.gooddata.api+json + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 200 + message: OK + - request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: GET + uri: http://localhost:3000/api/v1/layout/workspaces/test_documents_survive_store_load_and_put/analyticsModel + response: + body: + string: + analytics: + analyticalDashboardExtensions: [] + analyticalDashboards: [] + attributeHierarchies: [] + dashboardPlugins: [] + documentTemplates: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + description: Brand review + id: tpl_1 + tags: + - brand + title: Tpl 1 + version: '2' + documents: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + createdAt: 2000-01-01 00:00 + createdBy: + id: admin + type: user + description: Monthly + id: doc_1 + modifiedAt: 2026-11-02 11:00 + modifiedBy: + id: admin + type: user + period: + from: '2026-01-01' + granularity: GDC.time.date + to: '2026-01-31' + type: absolute + tags: + - finance + title: Doc 1 + version: '2' + exportDefinitions: [] + filterContexts: [] + memoryItems: [] + metrics: [] + pageTemplates: + - content: + layout: + id: t1 + markdown: Hello + type: text + description: Cover + id: pt_1 + tags: + - brand + title: Page 1 + version: '2' + parameters: [] + visualizationObjects: [] + headers: + Content-Type: + - application/json + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + content-length: + - '1165' + status: + code: 200 + message: OK + - request: + body: null + headers: + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: GET + uri: http://localhost:3000/api/v1/entities/organization + response: + body: + string: '' + headers: + Content-Type: + - application/vnd.gooddata.api+json + DATE: *id001 + Expires: + - '0' + Location: + - /api/v1/entities/admin/organizations/default + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 302 + message: Found + - request: + body: null + headers: + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: GET + uri: http://localhost:3000/api/v1/entities/admin/organizations/default + response: + body: + string: + data: + attributes: + allowedOrigins: [] + dataCenter: '' + earlyAccess: enableAlerting + earlyAccessValues: + - enableAlerting + - enableSmtp + - enablePreAggregationDatasets + - enableScheduling + - enableCompositeGrain + - enableUserManagement + - enableRawExports + - enableFlexibleDashboardLayout + hostname: localhost + name: Default Organization + region: '' + id: default + type: organization + links: + self: http://localhost:3000/api/v1/entities/admin/organizations/default + headers: + Content-Type: + - application/vnd.gooddata.api+json + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 200 + message: OK + - request: + body: + analytics: + analyticalDashboardExtensions: [] + analyticalDashboards: [] + attributeHierarchies: [] + dashboardPlugins: [] + documentTemplates: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + description: Brand review + id: tpl_1 + tags: + - brand + title: Tpl 1 + version: '2' + documents: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + createdAt: 2000-01-01 00:00 + createdBy: + id: admin + type: user + description: Monthly + id: doc_1 + modifiedAt: 2026-11-02 11:00 + modifiedBy: + id: admin + type: user + period: + from: '2026-01-01' + granularity: GDC.time.date + to: '2026-01-31' + type: absolute + tags: + - finance + title: Doc 1 + version: '2' + exportDefinitions: [] + filterContexts: [] + memoryItems: [] + metrics: [] + pageTemplates: + - content: + layout: + id: t1 + markdown: Hello + type: text + description: Cover + id: pt_1 + tags: + - brand + title: Page 1 + version: '2' + parameters: [] + visualizationObjects: [] + headers: + Accept-Encoding: + - br, gzip, deflate + Content-Type: + - application/json + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: PUT + uri: http://localhost:3000/api/v1/layout/workspaces/test_documents_survive_store_load_and_put/analyticsModel + response: + body: + string: '' + headers: + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 204 + message: No Content + - request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: GET + uri: http://localhost:3000/api/v1/layout/workspaces/test_documents_survive_store_load_and_put/analyticsModel + response: + body: + string: + analytics: + analyticalDashboardExtensions: [] + analyticalDashboards: [] + attributeHierarchies: [] + dashboardPlugins: [] + documentTemplates: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + description: Brand review + id: tpl_1 + tags: + - brand + title: Tpl 1 + version: '2' + documents: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + createdAt: 2000-01-01 00:00 + createdBy: + id: admin + type: user + description: Monthly + id: doc_1 + modifiedAt: 2026-11-02 11:00 + modifiedBy: + id: admin + type: user + period: + from: '2026-01-01' + granularity: GDC.time.date + to: '2026-01-31' + type: absolute + tags: + - finance + title: Doc 1 + version: '2' + exportDefinitions: [] + filterContexts: [] + memoryItems: [] + metrics: [] + pageTemplates: + - content: + layout: + id: t1 + markdown: Hello + type: text + description: Cover + id: pt_1 + tags: + - brand + title: Page 1 + version: '2' + parameters: [] + visualizationObjects: [] + headers: + Content-Type: + - application/json + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + content-length: + - '1165' + status: + code: 200 + message: OK + - request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: GET + uri: http://localhost:3000/api/v1/layout/workspaces/test_documents_survive_store_load_and_put/analyticsModel + response: + body: + string: + analytics: + analyticalDashboardExtensions: [] + analyticalDashboards: [] + attributeHierarchies: [] + dashboardPlugins: [] + documentTemplates: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + description: Brand review + id: tpl_1 + tags: + - brand + title: Tpl 1 + version: '2' + documents: + - content: + locale: en-US + pages: + - id: p1 + kind: content + layout: + children: + - id: t1 + markdown: Hello + type: text + type: row + createdAt: 2000-01-01 00:00 + createdBy: + id: admin + type: user + description: Monthly + id: doc_1 + modifiedAt: 2026-11-02 11:00 + modifiedBy: + id: admin + type: user + period: + from: '2026-01-01' + granularity: GDC.time.date + to: '2026-01-31' + type: absolute + tags: + - finance + title: Doc 1 + version: '2' + exportDefinitions: [] + filterContexts: [] + memoryItems: [] + metrics: [] + pageTemplates: + - content: + layout: + id: t1 + markdown: Hello + type: text + description: Cover + id: pt_1 + tags: + - brand + title: Page 1 + version: '2' + parameters: [] + visualizationObjects: [] + headers: + Content-Type: + - application/json + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + content-length: + - '1165' + status: + code: 200 + message: OK + - request: + body: + workspaceDataFilters: + - columnName: wdf__region + id: wdf__region + title: Customer region + workspace: + id: demo + type: workspace + workspaceDataFilterSettings: + - filterValues: + - West + id: region_west + title: Region West + workspace: + id: demo_west + type: workspace + - columnName: wdf__state + id: wdf__state + title: Customer state + workspace: + id: demo_west + type: workspace + workspaceDataFilterSettings: + - filterValues: + - California + id: region_west_california + title: Region West California + workspace: + id: demo_west_california + type: workspace + workspaces: + - automations: [] + customApplicationSettings: [] + filterViews: [] + hierarchyPermissions: + - assignee: + id: demo2 + type: user + name: MANAGE + - assignee: + id: demoGroup + type: userGroup + name: ANALYZE + id: demo + model: + analytics: + analyticalDashboardExtensions: [] + analyticalDashboards: + - content: + filterContextRef: + identifier: + id: campaign_name_filter + type: filterContext + layout: + sections: + - header: + description: The first insight shows a breakdown of + spend by category and campaign. The second shows revenue + per $ spend, for each campaign, to demonstrate, how + campaigns are successful. + title: Spend breakdown and Revenue + items: + - size: + xl: + gridWidth: 6 + type: IDashboardLayoutItem + widget: + description: '' + drills: [] + ignoreDashboardFilters: [] + insight: + identifier: + id: campaign_spend + type: visualizationObject + properties: {} + title: Campaign Spend + type: insight + - size: + xl: + gridWidth: 6 + type: IDashboardLayoutItem + widget: + description: '' + drills: [] + ignoreDashboardFilters: [] + insight: + identifier: + id: revenue_per_usd_vs_spend_by_campaign + type: visualizationObject + properties: {} + title: Revenue per $ vs Spend by Campaign + type: insight + type: IDashboardLayoutSection + type: IDashboardLayout + version: '2' + description: '' + id: campaign + permissions: + - assigneeRule: + type: allWorkspaceUsers + name: VIEW + title: Campaign + - content: + filterContextRef: + identifier: + id: campaign_name_filter + type: filterContext + layout: + sections: + - items: + - size: + xl: + gridWidth: 12 + type: IDashboardLayoutItem + widget: + description: '' + drills: [] + ignoreDashboardFilters: [] + insight: + identifier: + id: top_10_products + type: visualizationObject + properties: {} + title: DHO simple + type: insight + type: IDashboardLayoutSection + type: IDashboardLayout + plugins: + - plugin: + identifier: + id: dashboard_plugin_1 + type: dashboardPlugin + version: '2' + version: '2' + id: dashboard_plugin + title: Dashboard plugin + - content: + filterContextRef: + identifier: + id: region_filter + type: filterContext + layout: + sections: + - items: + - size: + xl: + gridWidth: 6 + type: IDashboardLayoutItem + widget: + dateDataSet: + identifier: + id: date + type: dataset + description: '' + drills: [] + ignoreDashboardFilters: [] + insight: + identifier: + id: top_10_products + type: visualizationObject + properties: {} + title: Top 10 Products + type: insight + - size: + xl: + gridWidth: 6 + type: IDashboardLayoutItem + widget: + dateDataSet: + identifier: + id: date + type: dataset + description: '' + drills: [] + ignoreDashboardFilters: [] + insight: + identifier: + id: revenue_trend + type: visualizationObject + properties: {} + title: Revenue Trend + type: insight + - size: + xl: + gridWidth: 6 + type: IDashboardLayoutItem + widget: + dateDataSet: + identifier: + id: date + type: dataset + description: '' + drills: [] + ignoreDashboardFilters: [] + insight: + identifier: + id: customers_trend + type: visualizationObject + properties: {} + title: Customers Trend + type: insight + - size: + xl: + gridWidth: 6 + type: IDashboardLayoutItem + widget: + dateDataSet: + identifier: + id: date + type: dataset + description: '' + drills: [] + ignoreDashboardFilters: [] + insight: + identifier: + id: product_categories_pie_chart + type: visualizationObject + properties: {} + title: Product Categories Pie Chart + type: insight + - size: + xl: + gridWidth: 6 + type: IDashboardLayoutItem + widget: + dateDataSet: + identifier: + id: date + type: dataset + description: '' + drills: [] + ignoreDashboardFilters: [] + insight: + identifier: + id: product_breakdown + type: visualizationObject + properties: {} + title: Product Breakdown + type: insight + - size: + xl: + gridWidth: 6 + type: IDashboardLayoutItem + widget: + dateDataSet: + identifier: + id: date + type: dataset + description: '' + drills: [] + ignoreDashboardFilters: [] + insight: + identifier: + id: product_saleability + type: visualizationObject + properties: {} + title: Product Saleability + type: insight + - size: + xl: + gridWidth: 12 + type: IDashboardLayoutItem + widget: + dateDataSet: + identifier: + id: date + type: dataset + description: '' + drills: [] + ignoreDashboardFilters: [] + insight: + identifier: + id: percent_revenue_per_product_by_customer_and_category + type: visualizationObject + properties: {} + title: '% Revenue per Product by Customer and Category' + type: insight + type: IDashboardLayoutSection + type: IDashboardLayout + version: '2' + description: '' + id: product_and_category + title: Product & Category + attributeHierarchies: [] + dashboardPlugins: + - content: + url: https://www.example.com + version: '2' + description: Testing record dashboard_plugin_1 + id: dashboard_plugin_1 + title: dashboard_plugin_1 + - content: + url: https://www.example.com + version: '2' + description: Testing record dashboard_plugin_2 + id: dashboard_plugin_2 + title: dashboard_plugin_2 + documentTemplates: [] + documents: [] + exportDefinitions: [] + filterContexts: + - content: + filters: + - dateFilter: + from: '0' + granularity: GDC.time.month + to: '0' + type: relative + - attributeFilter: + attributeElements: + uris: [] + displayForm: + identifier: + id: campaign_name + type: label + filterElementsBy: [] + localIdentifier: 14b0807447ef4bc28f43e4fc5c337d1d + negativeSelection: true + version: '2' + description: '' + id: campaign_name_filter + title: filterContext + - content: + filters: + - attributeFilter: + attributeElements: + uris: [] + displayForm: + identifier: + id: region + type: label + filterElementsBy: [] + localIdentifier: 2d5ef8df82444f6ba27b45f0990ee6af + negativeSelection: true + version: '2' + description: '' + id: region_filter + title: filterContext + memoryItems: [] + metrics: + - content: + format: '#,##0' + maql: SELECT COUNT({attribute/customer_id},{attribute/order_line_id}) + id: amount_of_active_customers + title: '# of Active Customers' + - content: + format: '#,##0' + maql: SELECT COUNT({attribute/order_id}) + id: amount_of_orders + title: '# of Orders' + - content: + format: '#,##0' + maql: 'SELECT {metric/amount_of_active_customers} WHERE (SELECT + {metric/revenue} BY {attribute/customer_id}) > 10000 ' + id: amount_of_top_customers + title: '# of Top Customers' + - content: + format: '#,##0.00' + maql: SELECT {metric/amount_of_orders} WHERE NOT ({label/order_status} + IN ("Returned", "Canceled")) + description: '' + id: amount_of_valid_orders + title: '# of Valid Orders' + - content: + format: $#,##0 + maql: SELECT SUM({fact/spend}) + id: campaign_spend + title: Campaign Spend + - content: + format: $#,##0 + maql: SELECT SUM({fact/price}*{fact/quantity}) + id: order_amount + title: Order Amount + - content: + format: '#,##0.0%' + maql: SELECT {metric/revenue} / {metric/total_revenue} + id: percent_revenue + title: '% Revenue' + - content: + format: '#,##0.0%' + maql: "SELECT\n (SELECT {metric/revenue} WHERE (SELECT {metric/revenue_top_10}\ + \ BY {attribute/customer_id}) > 0)\n /\n {metric/revenue}" + id: percent_revenue_from_top_10_customers + title: '% Revenue from Top 10 Customers' + - content: + format: '#,##0.0%' + maql: "SELECT\n (SELECT {metric/revenue} WHERE (SELECT {metric/revenue_top_10_percent}\ + \ BY {attribute/customer_id}) > 0)\n /\n {metric/revenue}" + id: percent_revenue_from_top_10_percent_customers + title: '% Revenue from Top 10% Customers' + - content: + format: '#,##0.0%' + maql: "SELECT\n (SELECT {metric/revenue} WHERE (SELECT {metric/revenue_top_10_percent}\ + \ BY {attribute/product_id}) > 0)\n /\n {metric/revenue}" + id: percent_revenue_from_top_10_percent_products + title: '% Revenue from Top 10% Products' + - content: + format: '#,##0.0%' + maql: "SELECT\n (SELECT {metric/revenue} WHERE (SELECT {metric/revenue_top_10}\ + \ BY {attribute/product_id}) > 0)\n /\n {metric/revenue}" + id: percent_revenue_from_top_10_products + title: '% Revenue from Top 10 Products' + - content: + format: '#,##0.0%' + maql: SELECT {metric/revenue} / (SELECT {metric/revenue} BY + {attribute/products.category}, ALL OTHER) + id: percent_revenue_in_category + title: '% Revenue in Category' + - content: + format: '#,##0.0%' + maql: SELECT {metric/revenue} / (SELECT {metric/revenue} BY + ALL {attribute/product_id}) + id: percent_revenue_per_product + title: '% Revenue per Product' + - content: + format: $#,##0 + maql: SELECT {metric/order_amount} WHERE NOT ({label/order_status} + IN ("Returned", "Canceled")) + description: '' + id: revenue + title: Revenue + - content: + format: $#,##0 + maql: SELECT {metric/revenue} WHERE {label/products.category} + IN ("Clothing") + id: revenue-clothing + title: Revenue (Clothing) + - content: + format: $#,##0 + maql: SELECT {metric/revenue} WHERE {label/products.category} + IN ( "Electronics") + id: revenue-electronic + title: Revenue (Electronic) + - content: + format: $#,##0 + maql: SELECT {metric/revenue} WHERE {label/products.category} + IN ("Home") + id: revenue-home + title: Revenue (Home) + - content: + format: $#,##0 + maql: SELECT {metric/revenue} WHERE {label/products.category} + IN ("Outdoor") + id: revenue-outdoor + title: Revenue (Outdoor) + - content: + format: $#,##0.0 + maql: SELECT AVG(SELECT {metric/revenue} BY {attribute/customer_id}) + id: revenue_per_customer + title: Revenue per Customer + - content: + format: $#,##0.0 + maql: SELECT {metric/revenue} / {metric/campaign_spend} + id: revenue_per_dollar_spent + title: Revenue per Dollar Spent + - content: + format: $#,##0 + maql: SELECT {metric/revenue} WHERE TOP(10) OF ({metric/revenue}) + id: revenue_top_10 + title: Revenue / Top 10 + - content: + format: $#,##0 + maql: SELECT {metric/revenue} WHERE TOP(10%) OF ({metric/revenue}) + id: revenue_top_10_percent + title: Revenue / Top 10% + - content: + format: $#,##0 + maql: SELECT {metric/revenue} BY ALL OTHER + id: total_revenue + title: Total Revenue + - content: + format: $#,##0 + maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER + id: total_revenue-no_filters + title: Total Revenue (No Filters) + pageTemplates: [] + parameters: [] + visualizationObjects: + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: campaign_spend + type: metric + localIdentifier: d319bcb2d8c04442a684e3b3cd063381 + title: Campaign Spend + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: campaign_channels.category + type: label + localIdentifier: 291c085e7df8420db84117ca49f59c49 + localIdentifier: view + - items: + - attribute: + displayForm: + identifier: + id: campaign_name + type: label + localIdentifier: d9dd143d647d4d148405a60ec2cf59bc + localIdentifier: segment + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: type + type: label + notIn: + values: [] + - negativeAttributeFilter: + displayForm: + identifier: + id: campaign_channels.category + type: label + notIn: + values: [] + - negativeAttributeFilter: + displayForm: + identifier: + id: campaign_name + type: label + notIn: + values: [] + properties: + controls: + legend: + position: bottom + version: '2' + visualizationUrl: local:treemap + id: campaign_spend + title: Campaign Spend + - content: + buckets: + - items: + - measure: + alias: Active Customers + definition: + measureDefinition: + computeRatio: false + filters: [] + item: + identifier: + id: amount_of_active_customers + type: metric + localIdentifier: 2ba0b87b59ca41a4b1530e81a5c1d081 + title: '# of Active Customers' + localIdentifier: measures + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue_per_customer + type: metric + localIdentifier: ec0606894b9f4897b7beaf1550608928 + title: Revenue per Customer + localIdentifier: secondary_measures + - items: + - attribute: + displayForm: + identifier: + id: date.month + type: label + localIdentifier: 0de7d7f08af7480aa636857a26be72b6 + localIdentifier: view + filters: + - relativeDateFilter: + dataSet: + identifier: + id: date + type: dataset + from: -12 + granularity: GDC.time.month + to: -1 + properties: + controls: + colorMapping: + - color: + type: guid + value: '20' + id: 2ba0b87b59ca41a4b1530e81a5c1d081 + - color: + type: guid + value: '4' + id: ec0606894b9f4897b7beaf1550608928 + dualAxis: true + legend: + position: bottom + primaryChartType: column + secondaryChartType: line + secondary_yaxis: + measures: + - ec0606894b9f4897b7beaf1550608928 + xaxis: + name: + visible: false + rotation: auto + version: '2' + visualizationUrl: local:combo2 + id: customers_trend + title: Customers Trend + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: percent_revenue_per_product + type: metric + localIdentifier: 08d8346c1ce7438994b251991c0fbf65 + title: '% Revenue per Product' + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue + type: metric + localIdentifier: b2350c06688b4da9b3833ebcce65527f + title: Revenue + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: customer_name + type: label + localIdentifier: 7a4045fd00ac44579f52406df679435f + - attribute: + displayForm: + identifier: + id: products.category + type: label + localIdentifier: 6a003ffd14994237ba64c4a02c488429 + - attribute: + displayForm: + identifier: + id: product_name + type: label + localIdentifier: 75ea396d0c8b48098e31dccf8b5801d3 + localIdentifier: attribute + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: customer_name + type: label + notIn: + values: [] + - negativeAttributeFilter: + displayForm: + identifier: + id: products.category + type: label + notIn: + values: [] + - negativeAttributeFilter: + displayForm: + identifier: + id: product_name + type: label + notIn: + values: [] + properties: {} + sorts: + - attributeSortItem: + attributeIdentifier: 7a4045fd00ac44579f52406df679435f + direction: asc + version: '2' + visualizationUrl: local:table + id: percent_revenue_per_product_by_customer_and_category + title: '% Revenue per Product by Customer and Category' + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: amount_of_active_customers + type: metric + localIdentifier: 1a14cdc1293c46e89a2e25d3e741d235 + title: '# of Active Customers' + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: date.month + type: label + localIdentifier: c1feca1864244ec2ace7a9b9d7fda231 + localIdentifier: view + - items: + - attribute: + displayForm: + identifier: + id: region + type: label + localIdentifier: 530cddbd7ca04d039e73462d81ed44d5 + localIdentifier: stack + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: region + type: label + notIn: + values: [] + - relativeDateFilter: + dataSet: + identifier: + id: date + type: dataset + from: -11 + granularity: GDC.time.month + to: 0 + properties: + controls: + legend: + position: bottom + stackMeasuresToPercent: true + version: '2' + visualizationUrl: local:area + id: percentage_of_customers_by_region + title: Percentage of Customers by Region + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue + type: metric + localIdentifier: 590d332ef686468b8878ae41b23341c6 + title: Revenue + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: products.category + type: label + localIdentifier: b166c71091864312a14c7ae8ff886ffe + localIdentifier: view + - items: + - attribute: + displayForm: + identifier: + id: product_name + type: label + localIdentifier: e920a50e0bbb49788df0aac53634c1cd + localIdentifier: segment + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: products.category + type: label + notIn: + values: [] + - negativeAttributeFilter: + displayForm: + identifier: + id: product_name + type: label + notIn: + values: [] + properties: + controls: + legend: + position: bottom + version: '2' + visualizationUrl: local:treemap + id: product_breakdown + title: Product Breakdown + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + computeRatio: true + filters: [] + item: + identifier: + id: revenue + type: metric + format: '#,##0.00%' + localIdentifier: 162b857af49d45769bc12604a5c192b9 + title: '% Revenue' + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: products.category + type: label + localIdentifier: fe513cef1c6244a5ac21c5f49c56b108 + localIdentifier: view + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: product_name + type: label + notIn: + values: [] + - negativeAttributeFilter: + displayForm: + identifier: + id: products.category + type: label + notIn: + values: [] + properties: + controls: + dataLabels: + visible: auto + legend: + position: bottom + version: '2' + visualizationUrl: local:donut + id: product_categories_pie_chart + title: Product Categories Pie Chart + - content: + buckets: + - items: + - measure: + alias: Previous Period + definition: + popMeasureDefinition: + measureIdentifier: c82e025fa2db4afea9a600a424591dbe + popAttribute: + identifier: + id: date.year + type: attribute + localIdentifier: c82e025fa2db4afea9a600a424591dbe_pop + - measure: + alias: This Period + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue + type: metric + localIdentifier: c82e025fa2db4afea9a600a424591dbe + title: Revenue + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: products.category + type: label + localIdentifier: c804ef5ba7944a5a9f360c86a9e95e9a + localIdentifier: view + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: product_name + type: label + notIn: + values: [] + - relativeDateFilter: + dataSet: + identifier: + id: date + type: dataset + from: -11 + granularity: GDC.time.month + to: 0 + - negativeAttributeFilter: + displayForm: + identifier: + id: products.category + type: label + notIn: + values: [] + properties: + controls: + legend: + position: bottom + stackMeasures: false + xaxis: + name: + visible: false + yaxis: + name: + visible: false + version: '2' + visualizationUrl: local:column + id: product_revenue_comparison-over_previous_period + title: Product Revenue Comparison (over previous period) + - content: + buckets: + - items: + - measure: + alias: Number of Orders + definition: + measureDefinition: + filters: [] + item: + identifier: + id: amount_of_orders + type: metric + localIdentifier: aeb5d51a162d4b59aba3bd6ddebcc780 + title: '# of Orders' + localIdentifier: measures + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue + type: metric + localIdentifier: 94b3edd3a73c4a48a4d13bbe9442cc98 + title: Revenue + localIdentifier: secondary_measures + - items: + - attribute: + displayForm: + identifier: + id: product_name + type: label + localIdentifier: d2a991bdd123448eb2be73d79f1180c4 + localIdentifier: attribute + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: product_name + type: label + notIn: + values: [] + properties: + controls: + dataLabels: + visible: auto + grid: + enabled: true + version: '2' + visualizationUrl: local:scatter + id: product_saleability + title: Product Saleability + - content: + buckets: + - items: + - measure: + alias: Items Sold + definition: + measureDefinition: + aggregation: sum + filters: [] + item: + identifier: + id: quantity + type: fact + format: '#,##0.00' + localIdentifier: 29486504dd0e4a36a18b0b2f792d3a46 + title: Sum of Quantity + - measure: + definition: + measureDefinition: + aggregation: avg + filters: [] + item: + identifier: + id: price + type: fact + format: '#,##0.00' + localIdentifier: aa6391acccf1452f8011201aef9af492 + title: Avg Price + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: percent_revenue_in_category + type: metric + localIdentifier: 2cd39539d8da46c9883e63caa3ba7cc0 + title: '% Revenue in Category' + - measure: + alias: Total Revenue + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue + type: metric + localIdentifier: 9a0f08331c094c7facf2a0b4f418de0a + title: Revenue + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: products.category + type: label + localIdentifier: 06bc6b3b9949466494e4f594c11f1bff + - attribute: + displayForm: + identifier: + id: product_name + type: label + localIdentifier: 192668bfb6a74e9ab7b5d1ce7cb68ea3 + localIdentifier: attribute + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: customer_name + type: label + notIn: + values: [] + - negativeAttributeFilter: + displayForm: + identifier: + id: product_name + type: label + notIn: + values: [] + - negativeAttributeFilter: + displayForm: + identifier: + id: products.category + type: label + notIn: + values: [] + properties: {} + sorts: + - attributeSortItem: + attributeIdentifier: 06bc6b3b9949466494e4f594c11f1bff + direction: asc + version: '2' + visualizationUrl: local:table + id: revenue_and_quantity_by_product_and_category + title: Revenue and Quantity by Product and Category + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue + type: metric + localIdentifier: 7df6c34387744d69b23ec92e1a5cf543 + title: Revenue + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: date.month + type: label + localIdentifier: 4bb4fc1986c546de9ad976e6ec23fed4 + localIdentifier: trend + - items: + - attribute: + displayForm: + identifier: + id: products.category + type: label + localIdentifier: 34bddcb1cd024902a82396216b0fa9d8 + localIdentifier: segment + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: products.category + type: label + notIn: + values: [] + - relativeDateFilter: + dataSet: + identifier: + id: date + type: dataset + granularity: GDC.time.year + properties: + controls: + legend: + position: bottom + version: '2' + visualizationUrl: local:line + id: revenue_by_category_trend + title: Revenue by Category Trend + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue + type: metric + localIdentifier: 4ae3401bdbba4938afe983df4ba04e1c + title: Revenue + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: product_name + type: label + localIdentifier: 1c8ba72dbfc84ddd913bf81dc355c427 + localIdentifier: view + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: product_name + type: label + notIn: + values: [] + properties: {} + version: '2' + visualizationUrl: local:bar + id: revenue_by_product + title: Revenue by Product + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: campaign_spend + type: metric + localIdentifier: 13a50d811e474ac6808d8da7f4673b35 + title: Campaign Spend + localIdentifier: measures + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue_per_dollar_spent + type: metric + localIdentifier: a0f15e82e6334280a44dbedc7d086e7c + title: Revenue per Dollar Spent + localIdentifier: secondary_measures + - items: + - attribute: + displayForm: + identifier: + id: campaign_name + type: label + localIdentifier: 1d9fa968bafb423eb29c938dfb1207ff + localIdentifier: attribute + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: campaign_name + type: label + notIn: + values: [] + properties: + controls: + xaxis: + min: '0' + yaxis: + min: '0' + version: '2' + visualizationUrl: local:scatter + id: revenue_per_usd_vs_spend_by_campaign + title: Revenue per $ vs Spend by Campaign + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + computeRatio: false + filters: [] + item: + identifier: + id: revenue + type: metric + localIdentifier: 60c854969a9c4c278ab596d99c222e92 + title: Revenue + localIdentifier: measures + - items: + - measure: + alias: Number of Orders + definition: + measureDefinition: + computeRatio: false + filters: [] + item: + identifier: + id: amount_of_orders + type: metric + localIdentifier: c2fa7ef48cc54af99f8c280eb451e051 + title: '# of Orders' + localIdentifier: secondary_measures + - items: + - attribute: + displayForm: + identifier: + id: date.month + type: label + localIdentifier: 413ac374b65648fa96826ca01d47bdda + localIdentifier: view + filters: + - relativeDateFilter: + dataSet: + identifier: + id: date + type: dataset + from: -3 + granularity: GDC.time.quarter + to: 0 + properties: + controls: + dualAxis: true + legend: + position: bottom + primaryChartType: column + secondaryChartType: line + secondary_yaxis: + measures: + - c2fa7ef48cc54af99f8c280eb451e051 + xaxis: + name: + visible: false + rotation: auto + version: '2' + visualizationUrl: local:combo2 + id: revenue_trend + title: Revenue Trend + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue_top_10 + type: metric + localIdentifier: 3f127ccfe57a40399e23f9ae2a4ad810 + title: Revenue / Top 10 + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: customer_name + type: label + localIdentifier: f4e39e24f11e4827a191c30d65c89d2c + localIdentifier: view + - items: + - attribute: + displayForm: + identifier: + id: state + type: label + localIdentifier: bbccd430176d428caed54c99afc9589e + localIdentifier: stack + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: customer_name + type: label + notIn: + values: [] + - negativeAttributeFilter: + displayForm: + identifier: + id: state + type: label + notIn: + values: [] + properties: + controls: + legend: + position: bottom + version: '2' + visualizationUrl: local:bar + id: top_10_customers + title: Top 10 Customers + - content: + buckets: + - items: + - measure: + definition: + measureDefinition: + filters: [] + item: + identifier: + id: revenue_top_10 + type: metric + localIdentifier: 77dc71bbac92412bac5f94284a5919df + title: Revenue / Top 10 + localIdentifier: measures + - items: + - attribute: + displayForm: + identifier: + id: product_name + type: label + localIdentifier: 781952e728204dcf923142910cc22ae2 + localIdentifier: view + - items: + - attribute: + displayForm: + identifier: + id: products.category + type: label + localIdentifier: fe513cef1c6244a5ac21c5f49c56b108 + localIdentifier: stack + filters: + - negativeAttributeFilter: + displayForm: + identifier: + id: product_name + type: label + notIn: + values: [] + - negativeAttributeFilter: + displayForm: + identifier: + id: products.category + type: label + notIn: + values: [] + properties: + controls: + legend: + position: bottom + version: '2' + visualizationUrl: local:bar + id: top_10_products + title: Top 10 Products + ldm: + datasets: + - aggregatedFacts: [] + attributes: + - description: Campaign channel id + id: campaign_channel_id + isNullable: false + labels: [] + sourceColumn: campaign_channel_id + sourceColumnDataType: STRING + tags: + - Campaign channels + title: Campaign channel id + - description: Category + id: campaign_channels.category + isNullable: true + labels: [] + sourceColumn: category + sourceColumnDataType: STRING + tags: + - Campaign channels + title: Category + - description: Type + id: type + isNullable: true + labels: [] + sourceColumn: type + sourceColumnDataType: STRING + tags: + - Campaign channels + title: Type + dataSourceTableId: + dataSourceId: demo-test-ds + id: campaign_channels + path: + - demo + - campaign_channels + type: dataSource + description: Campaign channels + facts: + - description: Budget + id: budget + isNullable: true + sourceColumn: budget + sourceColumnDataType: NUMERIC + tags: + - Campaign channels + title: Budget + - description: Spend + id: spend + isNullable: true + sourceColumn: spend + sourceColumnDataType: NUMERIC + tags: + - Campaign channels + title: Spend + grain: + - id: campaign_channel_id + type: attribute + id: campaign_channels + references: + - identifier: + id: campaigns + type: dataset + multivalue: false + sources: + - column: campaign_id + dataType: INT + isNullable: true + target: + id: campaign_id + type: attribute + tags: + - Campaign channels + title: Campaign channels + - aggregatedFacts: + - description: Budget Agg + id: budget_agg + sourceColumn: budget + sourceColumnDataType: INT + sourceFactReference: + operation: SUM + reference: + id: budget + type: fact + tags: + - Campaign channels per category + attributes: [] + description: Campaign channels per categories + facts: [] + grain: [] + id: campaign_channels_per_category + precedence: 1 + references: + - identifier: + id: campaign_channels + type: dataset + multivalue: false + sources: + - column: campaign_channel_id + dataType: STRING + isNullable: true + target: + id: campaign_channel_id + type: attribute + sql: + dataSourceId: demo-test-ds + statement: SELECT category, SUM(budget) FROM campaign_channels + GROUP BY category + tags: + - Campaign channels per category + title: Campaign channels per category + - aggregatedFacts: [] + attributes: + - description: Campaign id + id: campaign_id + isNullable: false + labels: [] + sourceColumn: campaign_id + sourceColumnDataType: INT + tags: + - Campaigns + title: Campaign id + - description: Campaign name + id: campaign_name + isNullable: true + labels: [] + sourceColumn: campaign_name + sourceColumnDataType: STRING + tags: + - Campaigns + title: Campaign name + dataSourceTableId: + dataSourceId: demo-test-ds + id: campaigns + path: + - demo + - campaigns + type: dataSource + description: Campaigns + facts: [] + grain: + - id: campaign_id + type: attribute + id: campaigns + references: [] + tags: + - Campaigns + title: Campaigns + - aggregatedFacts: [] + attributes: + - description: Customer id + id: customer_id + isNullable: false + labels: [] + sourceColumn: customer_id + sourceColumnDataType: INT + tags: + - Customers + title: Customer id + - description: Customer name + id: customer_name + isNullable: true + labels: [] + sourceColumn: customer_name + sourceColumnDataType: STRING + tags: + - Customers + title: Customer name + - description: Region + id: region + isNullable: true + labels: [] + sourceColumn: region + sourceColumnDataType: STRING + tags: + - Customers + title: Region + - description: State + id: state + isNullable: true + labels: + - description: Location + id: geo__state__location + isNullable: true + sourceColumn: geo__state__location + sourceColumnDataType: STRING + tags: + - Customers + title: Location + valueType: GEO + sourceColumn: state + sourceColumnDataType: STRING + tags: + - Customers + title: State + dataSourceTableId: + dataSourceId: demo-test-ds + id: customers + path: + - demo + - customers + type: dataSource + description: Customers + facts: [] + grain: + - id: customer_id + type: attribute + id: customers + references: [] + tags: + - Customers + title: Customers + - aggregatedFacts: [] + attributes: + - description: Order id + id: order_id + isNullable: true + labels: [] + sourceColumn: order_id + sourceColumnDataType: STRING + tags: + - Order lines + title: Order id + - description: Order line id + id: order_line_id + isNullable: false + labels: [] + sourceColumn: order_line_id + sourceColumnDataType: STRING + tags: + - Order lines + title: Order line id + - description: Order status + id: order_status + isNullable: true + labels: [] + sourceColumn: order_status + sourceColumnDataType: STRING + tags: + - Order lines + title: Order status + dataSourceTableId: + dataSourceId: demo-test-ds + id: order_lines + path: + - demo + - order_lines + type: dataSource + description: Order lines + facts: + - description: Price + id: price + isNullable: true + sourceColumn: price + sourceColumnDataType: NUMERIC + tags: + - Order lines + title: Price + - description: Quantity + id: quantity + isNullable: true + sourceColumn: quantity + sourceColumnDataType: NUMERIC + tags: + - Order lines + title: Quantity + grain: + - id: order_line_id + type: attribute + id: order_lines + references: + - identifier: + id: campaigns + type: dataset + multivalue: false + sources: + - column: campaign_id + dataType: INT + isNullable: true + target: + id: campaign_id + type: attribute + - identifier: + id: customers + type: dataset + multivalue: false + sources: + - column: customer_id + dataType: INT + isNullable: true + target: + id: customer_id + type: attribute + - identifier: + id: date + type: dataset + multivalue: false + sources: + - column: date + dataType: DATE + isNullable: true + target: + id: date + type: date + - identifier: + id: products + type: dataset + multivalue: false + sources: + - column: product_id + dataType: INT + isNullable: true + target: + id: product_id + type: attribute + tags: + - Order lines + title: Order lines + workspaceDataFilterColumns: + - dataType: STRING + name: wdf__region + - dataType: STRING + name: wdf__state + workspaceDataFilterReferences: + - filterColumn: wdf__region + filterColumnDataType: STRING + filterId: + id: wdf__region + type: workspaceDataFilter + - aggregatedFacts: [] + attributes: + - description: Product id + id: product_id + isNullable: false + labels: [] + sourceColumn: product_id + sourceColumnDataType: INT + tags: + - Products + title: Product id + - description: Product name + id: product_name + isNullable: true + labels: [] + sourceColumn: product_name + sourceColumnDataType: STRING + tags: + - Products + title: Product name + - description: Category + id: products.category + isNullable: true + labels: [] + sourceColumn: category + sourceColumnDataType: STRING + tags: + - Products + title: Category + dataSourceTableId: + dataSourceId: demo-test-ds + id: products + path: + - demo + - products + type: dataSource + description: Products + facts: [] + grain: + - id: product_id + type: attribute + id: products + references: [] + tags: + - Products + title: Products + dateInstances: + - description: '' + granularities: + - DAY + - WEEK + - MONTH + - QUARTER + - YEAR + granularitiesFormatting: + titleBase: '' + titlePattern: '%titleBase - %granularityTitle' + id: date + tags: + - Date + title: Date + name: Demo + permissions: + - assignee: + id: demo2 + type: user + name: ANALYZE + - assignee: + id: demoGroup + type: userGroup + name: VIEW + settings: [] + userDataFilters: [] + - automations: [] + customApplicationSettings: [] + filterViews: [] + hierarchyPermissions: [] + id: demo_west + model: + analytics: + analyticalDashboardExtensions: + - id: campaign + permissions: + - assigneeRule: + type: allWorkspaceUsers + name: VIEW + analyticalDashboards: [] + attributeHierarchies: [] + dashboardPlugins: [] + documentTemplates: [] + documents: [] + exportDefinitions: [] + filterContexts: [] + memoryItems: [] + metrics: [] + pageTemplates: [] + parameters: [] + visualizationObjects: [] + ldm: + datasetExtensions: + - id: order_lines + workspaceDataFilterReferences: + - filterColumn: wdf__state + filterColumnDataType: STRING + filterId: + id: wdf__state + type: workspaceDataFilter + datasets: [] + dateInstances: [] + name: Demo West + parent: + id: demo + type: workspace + permissions: [] + settings: [] + userDataFilters: [] + - automations: [] + customApplicationSettings: [] + filterViews: [] + hierarchyPermissions: [] + id: demo_west_california + model: + analytics: + analyticalDashboardExtensions: [] + analyticalDashboards: [] + attributeHierarchies: [] + dashboardPlugins: [] + documentTemplates: [] + documents: [] + exportDefinitions: [] + filterContexts: [] + memoryItems: [] + metrics: [] + pageTemplates: [] + parameters: [] + visualizationObjects: [] + ldm: + datasets: [] + dateInstances: [] + name: Demo West California + parent: + id: demo_west + type: workspace + permissions: [] + settings: [] + userDataFilters: [] + headers: + Accept-Encoding: + - br, gzip, deflate + Content-Type: + - application/json + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + method: PUT + uri: http://localhost:3000/api/v1/layout/workspaces + response: + body: + string: '' + headers: + DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + status: + code: 204 + message: No Content +version: 1 diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_get_declarative_analytics_model.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_get_declarative_analytics_model.yaml index 27b41e962..b6b839e17 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_get_declarative_analytics_model.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_get_declarative_analytics_model.yaml @@ -1350,6 +1350,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '27788' status: code: 200 message: OK diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_load_and_put_declarative_analytics_model.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_load_and_put_declarative_analytics_model.yaml index e17cf0d86..578c0a640 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_load_and_put_declarative_analytics_model.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_load_and_put_declarative_analytics_model.yaml @@ -21,11 +21,16 @@ interactions: status: 404 title: Not Found traceId: NORMALIZED_TRACE_ID_000000000000 + type: about:blank headers: Content-Type: - application/problem+json DATE: &id001 - PLACEHOLDER + Expires: + - '0' + Pragma: + - no-cache X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 @@ -494,6 +499,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '7492' status: code: 200 message: OK @@ -2259,6 +2266,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '27788' status: code: 200 message: OK @@ -2615,6 +2624,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -2883,6 +2894,7 @@ interactions: type: user id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -5212,6 +5224,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '27788' status: code: 200 message: OK @@ -5513,6 +5527,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -5689,6 +5705,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -7002,10 +7019,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -7037,10 +7057,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_put_declarative_analytics_model.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_put_declarative_analytics_model.yaml index 65e329dac..8f1390f80 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_put_declarative_analytics_model.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/demo_put_declarative_analytics_model.yaml @@ -23,12 +23,15 @@ interactions: traceId: NORMALIZED_TRACE_ID_000000000000 headers: Content-Type: - - application/problem+json + - application/json DATE: &id001 - PLACEHOLDER + Expires: + - '0' + Pragma: + - no-cache X-Content-Type-Options: - nosniff - X-GDC-TRACE-ID: *id001 status: code: 404 message: Not Found @@ -494,6 +497,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '7492' status: code: 200 message: OK @@ -958,10 +963,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] headers: @@ -1329,6 +1337,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -1505,6 +1515,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -2818,10 +2829,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -2853,10 +2867,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/export_definition_analytics_layout.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/export_definition_analytics_layout.yaml index 343973380..00f13484c 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/export_definition_analytics_layout.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspace_content/export_definition_analytics_layout.yaml @@ -1350,6 +1350,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '27788' status: code: 200 message: OK @@ -1607,6 +1609,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: - id: export_definition_id requestPayload: @@ -1784,6 +1788,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -4058,6 +4063,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '27902' status: code: 200 message: OK @@ -4359,6 +4366,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -4535,6 +4544,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -5848,10 +5858,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -5883,10 +5896,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_clone_workspace.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_clone_workspace.yaml index ad533a463..c2112fda6 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_clone_workspace.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_clone_workspace.yaml @@ -21,6 +21,7 @@ interactions: status: 404 title: Not Found traceId: NORMALIZED_TRACE_ID_000000000000 + type: about:blank headers: Content-Type: - application/problem+json @@ -2006,6 +2007,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '38447' status: code: 200 message: OK @@ -2065,11 +2068,14 @@ interactions: traceId: NORMALIZED_TRACE_ID_000000000000 headers: Content-Type: - - application/problem+json + - application/json DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache X-Content-Type-Options: - nosniff - X-GDC-TRACE-ID: *id001 status: code: 404 message: Not Found @@ -2096,11 +2102,14 @@ interactions: traceId: NORMALIZED_TRACE_ID_000000000000 headers: Content-Type: - - application/problem+json + - application/json DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache X-Content-Type-Options: - nosniff - X-GDC-TRACE-ID: *id001 status: code: 404 message: Not Found @@ -2545,6 +2554,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -2813,6 +2824,7 @@ interactions: type: user id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -6227,6 +6239,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '38482' status: code: 200 message: OK @@ -8146,6 +8160,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '38447' status: code: 200 message: OK @@ -8205,11 +8221,14 @@ interactions: traceId: NORMALIZED_TRACE_ID_000000000000 headers: Content-Type: - - application/problem+json + - application/json DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache X-Content-Type-Options: - nosniff - X-GDC-TRACE-ID: *id001 status: code: 404 message: Not Found @@ -8236,11 +8255,14 @@ interactions: traceId: NORMALIZED_TRACE_ID_000000000000 headers: Content-Type: - - application/problem+json + - application/json DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache X-Content-Type-Options: - nosniff - X-GDC-TRACE-ID: *id001 status: code: 404 message: Not Found @@ -8699,6 +8721,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -8967,6 +8991,7 @@ interactions: type: user id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -12477,6 +12502,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '38447' status: code: 200 message: OK @@ -12630,6 +12657,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '1756' status: code: 200 message: OK @@ -12682,10 +12711,15 @@ interactions: status: 404 title: Not Found traceId: NORMALIZED_TRACE_ID_000000000000 + type: about:blank headers: Content-Type: - application/problem+json DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 @@ -13147,6 +13181,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -13415,6 +13451,7 @@ interactions: type: user id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -15178,6 +15215,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -15354,6 +15393,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -16667,10 +16707,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -16702,10 +16745,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_declarative_workspaces.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_declarative_workspaces.yaml index f90923eed..c3416ac33 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_declarative_workspaces.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_declarative_workspaces.yaml @@ -1865,6 +1865,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '37668' status: code: 200 message: OK @@ -3732,6 +3734,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '37668' status: code: 200 message: OK diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspace.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspace.yaml index d66181715..b645dfe1f 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspace.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspace.yaml @@ -1741,6 +1741,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '35279' status: code: 200 message: OK @@ -3484,6 +3486,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '35279' status: code: 200 message: OK diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspaces.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspaces.yaml index f2aaac8e3..6d8599e5a 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspaces.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspaces.yaml @@ -1865,6 +1865,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '37668' status: code: 200 message: OK diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspaces_snake_case.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspaces_snake_case.yaml index f2aaac8e3..6d8599e5a 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspaces_snake_case.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_get_declarative_workspaces_snake_case.yaml @@ -1865,6 +1865,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '37668' status: code: 200 message: OK diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_load_and_put_declarative_workspace.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_load_and_put_declarative_workspace.yaml index e2afa3868..387b277c9 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_load_and_put_declarative_workspace.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_load_and_put_declarative_workspace.yaml @@ -1741,6 +1741,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '35279' status: code: 200 message: OK @@ -2169,6 +2171,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -2437,6 +2441,7 @@ interactions: type: user id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -5548,6 +5553,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '35279' status: code: 200 message: OK @@ -5849,6 +5856,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -6025,6 +6034,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -7338,10 +7348,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -7373,10 +7386,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_load_and_put_declarative_workspaces.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_load_and_put_declarative_workspaces.yaml index e4e36dc2c..c5dddfdb9 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_load_and_put_declarative_workspaces.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_load_and_put_declarative_workspaces.yaml @@ -440,6 +440,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -616,6 +618,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -1907,10 +1910,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -1942,10 +1948,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -3826,6 +3835,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '37288' status: code: 200 message: OK @@ -4127,6 +4138,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -4303,6 +4316,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -5616,10 +5630,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -5651,10 +5668,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_put_declarative_workspace.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_put_declarative_workspace.yaml index 371f857d5..65d25dae9 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_put_declarative_workspace.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_put_declarative_workspace.yaml @@ -23,12 +23,15 @@ interactions: traceId: NORMALIZED_TRACE_ID_000000000000 headers: Content-Type: - - application/problem+json + - application/json DATE: &id001 - PLACEHOLDER + Expires: + - '0' + Pragma: + - no-cache X-Content-Type-Options: - nosniff - X-GDC-TRACE-ID: *id001 status: code: 404 message: Not Found @@ -1816,6 +1819,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '35279' status: code: 200 message: OK @@ -2073,6 +2078,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -2245,6 +2252,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -5284,6 +5292,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '35121' status: code: 200 message: OK @@ -5585,6 +5595,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -5761,6 +5773,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -7074,10 +7087,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -7109,10 +7125,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_put_declarative_workspaces.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_put_declarative_workspaces.yaml index 2264518c8..67b7121aa 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_put_declarative_workspaces.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_put_declarative_workspaces.yaml @@ -1865,6 +1865,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '37668' status: code: 200 message: OK @@ -2228,6 +2230,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -2404,6 +2408,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -3717,10 +3722,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -3752,10 +3760,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -5658,6 +5669,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '37668' status: code: 200 message: OK @@ -5959,6 +5972,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -6135,6 +6150,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -7448,10 +7464,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -7483,10 +7502,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: diff --git a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_translate_workspace.yaml b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_translate_workspace.yaml index b8ae3b839..5a0de4324 100644 --- a/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_translate_workspace.yaml +++ b/packages/gooddata-sdk/tests/catalog/fixtures/workspaces/demo_translate_workspace.yaml @@ -1950,6 +1950,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '38447' status: code: 200 message: OK @@ -3981,6 +3983,8 @@ interactions: X-Content-Type-Options: - nosniff X-GDC-TRACE-ID: *id001 + content-length: + - '38447' status: code: 200 message: OK @@ -4007,11 +4011,14 @@ interactions: traceId: NORMALIZED_TRACE_ID_000000000000 headers: Content-Type: - - application/problem+json + - application/json DATE: *id001 + Expires: + - '0' + Pragma: + - no-cache X-Content-Type-Options: - nosniff - X-GDC-TRACE-ID: *id001 status: code: 404 message: Not Found @@ -4456,6 +4463,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -4724,6 +4733,7 @@ interactions: type: user id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -6172,6 +6182,7 @@ interactions: status: 404 title: Not Found traceId: NORMALIZED_TRACE_ID_000000000000 + type: about:blank headers: Content-Type: - application/problem+json @@ -6259,6 +6270,7 @@ interactions: status: 404 title: Not Found traceId: NORMALIZED_TRACE_ID_000000000000 + type: about:blank headers: Content-Type: - application/problem+json @@ -6623,6 +6635,8 @@ interactions: description: Testing record dashboard_plugin_2 id: dashboard_plugin_2 title: dashboard_plugin_2 + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: - content: @@ -6799,6 +6813,7 @@ interactions: maql: SELECT {metric/total_revenue} WITHOUT PARENT FILTER id: total_revenue-no_filters title: Total Revenue (No Filters) + pageTemplates: [] parameters: [] visualizationObjects: - content: @@ -8112,10 +8127,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: @@ -8147,10 +8165,13 @@ interactions: analyticalDashboards: [] attributeHierarchies: [] dashboardPlugins: [] + documentTemplates: [] + documents: [] exportDefinitions: [] filterContexts: [] memoryItems: [] metrics: [] + pageTemplates: [] parameters: [] visualizationObjects: [] ldm: From 2d51c7be78f7b0876932811d1b27711194736886 Mon Sep 17 00:00:00 2001 From: AdamPenaz Date: Fri, 6 Nov 2026 13:46:18 +0100 Subject: [PATCH 12/12] docs(gooddata-sdk): type client model fields as Catalog classes Record for the next contributor the rule the publisher document period settled: a field the generated client types as a model gets its own Catalog class, because a plain dict read through the client comes back with the client's Python names and value types. The entry names the pattern (a Union behind a global_converter structure hook, a keyword field spelled from_), the one exception by convention (an analytics object's content stays an opaque dict), and the check to run after regenerating the client, since a regeneration once typed Automation.metadata without anyone noticing. jira: LX-3447 risk: nonprod Co-Authored-By: Claude Opus 5.5 --- packages/gooddata-sdk/AGENTS.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/gooddata-sdk/AGENTS.md b/packages/gooddata-sdk/AGENTS.md index 2bc58d718..9e430a6ab 100644 --- a/packages/gooddata-sdk/AGENTS.md +++ b/packages/gooddata-sdk/AGENTS.md @@ -112,6 +112,18 @@ then every parent, so an invocation deep in a tree can pick up a `gooddata.yaml` not expect. Note the spelling: this CLI uses `gooddata.yaml`, while `gooddata-dbt` uses `gooddata.yml`. +**A field the generated client types as a model gets its own Catalog class, never +`dict[str, Any]`.** `Base.from_dict` reads through the client class, so such a dict comes +back with the client's Python names (`_from`, `default_value`) and value types +(`datetime.date`), while `to_dict` still writes the API's names. Model a oneOf as a `Union` +of classes behind a `global_converter` structure hook, as dashboard `permissions` and the +publisher document `period` do. Name a keyword field `from_`; `Base` writes it back as the +client's `_from`. One exception, by convention: an analytics object's `content` is its body +and stays an opaque `dict` whatever the client types it as, so its keys follow the client in +memory. After regenerating the client, check the fields that were free-form `JsonNode`: a +regeneration can type one unnoticed, as it typed `Automation.metadata` +(`AutomationMetadata`, 2025-04). + ## Testing Cassette-heavy — `tests/catalog/fixtures/` is the single largest churn point in the repo.