gooddata-sdk 1.15.1.dev2__tar.gz → 1.15.1.dev3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gooddata-sdk-1.15.1.dev2/gooddata_sdk.egg-info → gooddata-sdk-1.15.1.dev3}/PKG-INFO +4 -4
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/README.md +1 -1
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/__init__.py +6 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/catalog_service_base.py +1 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/declarative_model/data_source.py +1 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/entity_model/data_source.py +11 -1
- gooddata-sdk-1.15.1.dev3/gooddata_sdk/catalog/user/management_model/__init__.py +1 -0
- gooddata-sdk-1.15.1.dev3/gooddata_sdk/catalog/user/management_model/management.py +60 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/user/service.py +28 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/client.py +5 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3/gooddata_sdk.egg-info}/PKG-INFO +4 -4
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk.egg-info/SOURCES.txt +2 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk.egg-info/requires.txt +1 -1
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/setup.py +3 -3
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/LICENSE.txt +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/MANIFEST.in +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/_version.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/base.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/action_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/action_model/requests/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/action_model/requests/ldm_request.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/action_model/requests/scan_model_request.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/action_model/requests/scan_sql_request.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/action_model/responses/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/action_model/responses/scan_sql_response.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/action_model/sql_column.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/declarative_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/declarative_model/physical_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/declarative_model/physical_model/column.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/declarative_model/physical_model/pdm.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/declarative_model/physical_model/table.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/entity_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/entity_model/content_objects/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/entity_model/content_objects/table.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/service.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/validation/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/validation/data_source.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/depends_on.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/entity.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/export/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/export/request.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/export/service.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/identifier.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/organization/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/organization/entity_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/organization/entity_model/directive.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/organization/entity_model/jwk.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/organization/entity_model/organization.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/organization/entity_model/setting.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/organization/service.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/parameter.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/permission/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/permission/declarative_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/permission/declarative_model/dashboard_assignees.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/permission/declarative_model/dashboard_permissions.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/permission/declarative_model/manage_dashboard_permissions.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/permission/declarative_model/permission.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/permission/service.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/rule.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/setting.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/types.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/user/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/user/declarative_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/user/declarative_model/user.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/user/declarative_model/user_and_user_groups.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/user/declarative_model/user_group.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/user/entity_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/user/entity_model/user.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/user/entity_model/user_group.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/validate_by_item.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/content_service.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/analytics_model/analytics_model.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/data_filter_references.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/dataset/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/dataset/dataset.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/dataset_extensions/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/dataset_extensions/dataset_extension.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/date_dataset/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/date_dataset/date_dataset.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/logical_model/ldm.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/declarative_model/workspace/workspace.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/entity_model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/entity_model/content_objects/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/entity_model/content_objects/dataset.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/entity_model/content_objects/metric.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/entity_model/content_objects/workspace_setting.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/entity_model/graph_objects/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/entity_model/graph_objects/graph.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/entity_model/user_data_filter.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/entity_model/workspace.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/model_container.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/service.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/model/__init__.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/model/attribute.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/model/base.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/model/execution.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/model/filter.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/model/metric.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/service.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/py.typed +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/sdk.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/support.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/table.py +140 -140
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/type_converter.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/utils.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/visualization.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk.egg-info/dependency_links.txt +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk.egg-info/top_level.txt +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/setup.cfg +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/tests/test_client.py +0 -0
- {gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/tests/test_type_converter.py +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: gooddata-sdk
|
|
3
|
-
Version: 1.15.1.
|
|
3
|
+
Version: 1.15.1.dev3
|
|
4
4
|
Summary: GoodData Cloud Python SDK
|
|
5
5
|
Author: GoodData
|
|
6
6
|
Author-email: support@gooddata.com
|
|
7
7
|
License: MIT
|
|
8
|
-
Project-URL: Documentation, https://www.gooddata.com/docs/python-sdk/1.15.1.
|
|
8
|
+
Project-URL: Documentation, https://www.gooddata.com/docs/python-sdk/1.15.1.dev3
|
|
9
9
|
Project-URL: Source, https://github.com/gooddata/gooddata-python-sdk
|
|
10
10
|
Keywords: gooddata,sdk,api,analytics,headless,business,intelligence,headless-bi,cloud,native,semantic,layer,sql,metrics
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -22,7 +22,7 @@ Classifier: Typing :: Typed
|
|
|
22
22
|
Requires-Python: >=3.8.0
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
License-File: LICENSE.txt
|
|
25
|
-
Requires-Dist: gooddata-api-client~=1.15.1.
|
|
25
|
+
Requires-Dist: gooddata-api-client~=1.15.1.dev3
|
|
26
26
|
Requires-Dist: python-dateutil>=2.5.3
|
|
27
27
|
Requires-Dist: pyyaml>=5.1
|
|
28
28
|
Requires-Dist: attrs<=23.2.0,>=21.4.0
|
|
@@ -44,7 +44,7 @@ At the moment the SDK provides services to inspect and interact with the Semanti
|
|
|
44
44
|
* Compute Service
|
|
45
45
|
* Table Service
|
|
46
46
|
|
|
47
|
-
See [DOCUMENTATION](https://www.gooddata.com/docs/python-sdk/1.15.1.
|
|
47
|
+
See [DOCUMENTATION](https://www.gooddata.com/docs/python-sdk/1.15.1.dev3) for more details.
|
|
48
48
|
|
|
49
49
|
## Requirements
|
|
50
50
|
|
|
@@ -13,7 +13,7 @@ At the moment the SDK provides services to inspect and interact with the Semanti
|
|
|
13
13
|
* Compute Service
|
|
14
14
|
* Table Service
|
|
15
15
|
|
|
16
|
-
See [DOCUMENTATION](https://www.gooddata.com/docs/python-sdk/1.15.1.
|
|
16
|
+
See [DOCUMENTATION](https://www.gooddata.com/docs/python-sdk/1.15.1.dev3) for more details.
|
|
17
17
|
|
|
18
18
|
## Requirements
|
|
19
19
|
|
|
@@ -114,6 +114,12 @@ from gooddata_sdk.catalog.user.declarative_model.user_group import (
|
|
|
114
114
|
)
|
|
115
115
|
from gooddata_sdk.catalog.user.entity_model.user import CatalogUser
|
|
116
116
|
from gooddata_sdk.catalog.user.entity_model.user_group import CatalogUserGroup
|
|
117
|
+
from gooddata_sdk.catalog.user.management_model.management import (
|
|
118
|
+
CatalogDataSourcePermissionAssignment,
|
|
119
|
+
CatalogPermissionAssignments,
|
|
120
|
+
CatalogPermissionsAssignment,
|
|
121
|
+
CatalogWorkspacePermissionAssignment,
|
|
122
|
+
)
|
|
117
123
|
from gooddata_sdk.catalog.validate_by_item import CatalogValidateByItem
|
|
118
124
|
from gooddata_sdk.catalog.workspace.content_service import CatalogWorkspaceContent, CatalogWorkspaceContentService
|
|
119
125
|
from gooddata_sdk.catalog.workspace.declarative_model.workspace.analytics_model.analytics_model import (
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/catalog_service_base.py
RENAMED
|
@@ -17,6 +17,7 @@ class CatalogServiceBase:
|
|
|
17
17
|
self._entities_api: apis.EntitiesApi = api_client.entities_api
|
|
18
18
|
self._layout_api: apis.LayoutApi = api_client.layout_api
|
|
19
19
|
self._actions_api: apis.ActionsApi = api_client.actions_api
|
|
20
|
+
self._user_management_api: apis.UserManagementApi = api_client.user_management_api
|
|
20
21
|
|
|
21
22
|
def get_organization(self) -> CatalogOrganization:
|
|
22
23
|
# The generated client does work properly with redirecting APIs
|
|
@@ -71,6 +71,7 @@ class CatalogDeclarativeDataSource(Base):
|
|
|
71
71
|
schema: str
|
|
72
72
|
enable_caching: Optional[bool] = None
|
|
73
73
|
cache_path: Optional[List[str]] = None
|
|
74
|
+
cache_strategy: Optional[str] = None
|
|
74
75
|
username: Optional[str] = None
|
|
75
76
|
parameters: Optional[List[CatalogParameter]] = None
|
|
76
77
|
decoded_parameters: Optional[List[CatalogParameter]] = None
|
|
@@ -31,7 +31,16 @@ class CatalogDataSourceBase(Base):
|
|
|
31
31
|
TokenCredentialsFromFile,
|
|
32
32
|
]
|
|
33
33
|
_DELIMITER: ClassVar[str] = "&"
|
|
34
|
-
_ATTRIBUTES: ClassVar[List[str]] = [
|
|
34
|
+
_ATTRIBUTES: ClassVar[List[str]] = [
|
|
35
|
+
"enable_caching",
|
|
36
|
+
"cache_path",
|
|
37
|
+
"cache_strategy",
|
|
38
|
+
"url",
|
|
39
|
+
"parameters",
|
|
40
|
+
"name",
|
|
41
|
+
"type",
|
|
42
|
+
"schema",
|
|
43
|
+
]
|
|
35
44
|
|
|
36
45
|
id: str
|
|
37
46
|
name: str
|
|
@@ -40,6 +49,7 @@ class CatalogDataSourceBase(Base):
|
|
|
40
49
|
url: Optional[str] = None
|
|
41
50
|
enable_caching: Optional[bool] = None
|
|
42
51
|
cache_path: Optional[List[str]] = None
|
|
52
|
+
cache_strategy: Optional[str] = None
|
|
43
53
|
parameters: Optional[List[Dict[str, str]]] = None
|
|
44
54
|
decoded_parameters: Optional[List[Dict[str, str]]] = None
|
|
45
55
|
credentials: Credentials = attr.field(repr=False)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# (C) 2024 GoodData Corporation
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# (C) 2024 GoodData Corporation
|
|
2
|
+
|
|
3
|
+
from typing import List, Optional, Type
|
|
4
|
+
|
|
5
|
+
import attrs
|
|
6
|
+
|
|
7
|
+
from gooddata_api_client.model.permissions_assignment import PermissionsAssignment
|
|
8
|
+
from gooddata_api_client.model.user_management_data_source_permission_assignment import (
|
|
9
|
+
UserManagementDataSourcePermissionAssignment,
|
|
10
|
+
)
|
|
11
|
+
from gooddata_api_client.model.user_management_permission_assignments import UserManagementPermissionAssignments
|
|
12
|
+
from gooddata_api_client.model.user_management_workspace_permission_assignment import (
|
|
13
|
+
UserManagementWorkspacePermissionAssignment,
|
|
14
|
+
)
|
|
15
|
+
from gooddata_sdk import CatalogAssigneeIdentifier
|
|
16
|
+
from gooddata_sdk.catalog.base import Base
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@attrs.define(auto_attribs=True, kw_only=True)
|
|
20
|
+
class CatalogDataSourcePermissionAssignment(Base):
|
|
21
|
+
id: str
|
|
22
|
+
permissions: List[str] = attrs.field(factory=list)
|
|
23
|
+
name: Optional[str] = None
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def client_class() -> Type[UserManagementDataSourcePermissionAssignment]:
|
|
27
|
+
return UserManagementDataSourcePermissionAssignment
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@attrs.define(auto_attribs=True, kw_only=True)
|
|
31
|
+
class CatalogWorkspacePermissionAssignment(Base):
|
|
32
|
+
id: str
|
|
33
|
+
permissions: List[str] = attrs.field(factory=list)
|
|
34
|
+
hierarchy_permissions: List[str] = attrs.field(factory=list)
|
|
35
|
+
name: Optional[str] = None
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def client_class() -> Type[UserManagementWorkspacePermissionAssignment]:
|
|
39
|
+
return UserManagementWorkspacePermissionAssignment
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@attrs.define(auto_attribs=True, kw_only=True)
|
|
43
|
+
class CatalogPermissionAssignments(Base):
|
|
44
|
+
workspaces: List[CatalogWorkspacePermissionAssignment] = attrs.field(factory=list)
|
|
45
|
+
data_sources: List[CatalogDataSourcePermissionAssignment] = attrs.field(factory=list)
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def client_class() -> Type[UserManagementPermissionAssignments]:
|
|
49
|
+
return UserManagementPermissionAssignments
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@attrs.define(auto_attribs=True, kw_only=True)
|
|
53
|
+
class CatalogPermissionsAssignment(Base):
|
|
54
|
+
assignees: List[CatalogAssigneeIdentifier]
|
|
55
|
+
workspaces: List[CatalogWorkspacePermissionAssignment] = attrs.field(factory=list)
|
|
56
|
+
data_sources: List[CatalogDataSourcePermissionAssignment] = attrs.field(factory=list)
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def client_class() -> Type[PermissionsAssignment]:
|
|
60
|
+
return PermissionsAssignment
|
|
@@ -12,6 +12,10 @@ from gooddata_sdk.catalog.user.declarative_model.user_and_user_groups import Cat
|
|
|
12
12
|
from gooddata_sdk.catalog.user.declarative_model.user_group import CatalogDeclarativeUserGroups
|
|
13
13
|
from gooddata_sdk.catalog.user.entity_model.user import CatalogUser, CatalogUserDocument
|
|
14
14
|
from gooddata_sdk.catalog.user.entity_model.user_group import CatalogUserGroup, CatalogUserGroupDocument
|
|
15
|
+
from gooddata_sdk.catalog.user.management_model.management import (
|
|
16
|
+
CatalogPermissionAssignments,
|
|
17
|
+
CatalogPermissionsAssignment,
|
|
18
|
+
)
|
|
15
19
|
from gooddata_sdk.utils import load_all_entities, load_all_entities_dict
|
|
16
20
|
|
|
17
21
|
|
|
@@ -363,3 +367,27 @@ class CatalogUserService(CatalogServiceBase):
|
|
|
363
367
|
"""
|
|
364
368
|
declarative_users_user_groups = self.load_declarative_users_user_groups(layout_root_path)
|
|
365
369
|
self.put_declarative_users_user_groups(declarative_users_user_groups)
|
|
370
|
+
|
|
371
|
+
# User management use case APIs
|
|
372
|
+
|
|
373
|
+
def get_user_permissions(self, user_id: str) -> CatalogPermissionAssignments:
|
|
374
|
+
return CatalogPermissionAssignments.from_api(self._user_management_api.list_permissions_for_user(user_id))
|
|
375
|
+
|
|
376
|
+
def manage_user_permissions(self, user_id: str, permission_assignments: CatalogPermissionAssignments) -> None:
|
|
377
|
+
self._user_management_api.manage_permissions_for_user(user_id, permission_assignments.to_api())
|
|
378
|
+
|
|
379
|
+
def get_user_group_permissions(self, user_group_id: str) -> CatalogPermissionAssignments:
|
|
380
|
+
return CatalogPermissionAssignments.from_api(
|
|
381
|
+
self._user_management_api.list_permissions_for_user_group(user_group_id)
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
def manage_user_group_permissions(
|
|
385
|
+
self, user_group_id: str, permission_assignments: CatalogPermissionAssignments
|
|
386
|
+
) -> None:
|
|
387
|
+
self._user_management_api.manage_permissions_for_user_group(user_group_id, permission_assignments.to_api())
|
|
388
|
+
|
|
389
|
+
def assign_permissions_bulk(self, permissions_assignment: CatalogPermissionsAssignment) -> None:
|
|
390
|
+
self._user_management_api.assign_permissions(permissions_assignment.to_api())
|
|
391
|
+
|
|
392
|
+
def revoke_permissions_bulk(self, permissions_assignment: CatalogPermissionsAssignment) -> None:
|
|
393
|
+
self._user_management_api.revoke_permissions(permissions_assignment.to_api())
|
|
@@ -54,6 +54,7 @@ class GoodDataApiClient:
|
|
|
54
54
|
self._entities_api = apis.EntitiesApi(self._api_client)
|
|
55
55
|
self._layout_api = apis.LayoutApi(self._api_client)
|
|
56
56
|
self._actions_api = apis.ActionsApi(self._api_client)
|
|
57
|
+
self._user_management_api = apis.UserManagementApi(self._api_client)
|
|
57
58
|
|
|
58
59
|
@staticmethod
|
|
59
60
|
def _set_default_headers(headers: dict) -> None:
|
|
@@ -75,3 +76,7 @@ class GoodDataApiClient:
|
|
|
75
76
|
@property
|
|
76
77
|
def actions_api(self) -> apis.ActionsApi:
|
|
77
78
|
return self._actions_api
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def user_management_api(self) -> apis.UserManagementApi:
|
|
82
|
+
return self._user_management_api
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: gooddata-sdk
|
|
3
|
-
Version: 1.15.1.
|
|
3
|
+
Version: 1.15.1.dev3
|
|
4
4
|
Summary: GoodData Cloud Python SDK
|
|
5
5
|
Author: GoodData
|
|
6
6
|
Author-email: support@gooddata.com
|
|
7
7
|
License: MIT
|
|
8
|
-
Project-URL: Documentation, https://www.gooddata.com/docs/python-sdk/1.15.1.
|
|
8
|
+
Project-URL: Documentation, https://www.gooddata.com/docs/python-sdk/1.15.1.dev3
|
|
9
9
|
Project-URL: Source, https://github.com/gooddata/gooddata-python-sdk
|
|
10
10
|
Keywords: gooddata,sdk,api,analytics,headless,business,intelligence,headless-bi,cloud,native,semantic,layer,sql,metrics
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -22,7 +22,7 @@ Classifier: Typing :: Typed
|
|
|
22
22
|
Requires-Python: >=3.8.0
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
License-File: LICENSE.txt
|
|
25
|
-
Requires-Dist: gooddata-api-client~=1.15.1.
|
|
25
|
+
Requires-Dist: gooddata-api-client~=1.15.1.dev3
|
|
26
26
|
Requires-Dist: python-dateutil>=2.5.3
|
|
27
27
|
Requires-Dist: pyyaml>=5.1
|
|
28
28
|
Requires-Dist: attrs<=23.2.0,>=21.4.0
|
|
@@ -44,7 +44,7 @@ At the moment the SDK provides services to inspect and interact with the Semanti
|
|
|
44
44
|
* Compute Service
|
|
45
45
|
* Table Service
|
|
46
46
|
|
|
47
|
-
See [DOCUMENTATION](https://www.gooddata.com/docs/python-sdk/1.15.1.
|
|
47
|
+
See [DOCUMENTATION](https://www.gooddata.com/docs/python-sdk/1.15.1.dev3) for more details.
|
|
48
48
|
|
|
49
49
|
## Requirements
|
|
50
50
|
|
|
@@ -76,6 +76,8 @@ gooddata_sdk/catalog/user/declarative_model/user_group.py
|
|
|
76
76
|
gooddata_sdk/catalog/user/entity_model/__init__.py
|
|
77
77
|
gooddata_sdk/catalog/user/entity_model/user.py
|
|
78
78
|
gooddata_sdk/catalog/user/entity_model/user_group.py
|
|
79
|
+
gooddata_sdk/catalog/user/management_model/__init__.py
|
|
80
|
+
gooddata_sdk/catalog/user/management_model/management.py
|
|
79
81
|
gooddata_sdk/catalog/workspace/__init__.py
|
|
80
82
|
gooddata_sdk/catalog/workspace/content_service.py
|
|
81
83
|
gooddata_sdk/catalog/workspace/model_container.py
|
|
@@ -7,7 +7,7 @@ this_directory = Path(__file__).parent
|
|
|
7
7
|
long_description = (this_directory / "README.md").read_text(encoding="utf-8")
|
|
8
8
|
|
|
9
9
|
REQUIRES = [
|
|
10
|
-
"gooddata-api-client~=1.15.1.
|
|
10
|
+
"gooddata-api-client~=1.15.1.dev3",
|
|
11
11
|
"python-dateutil>=2.5.3",
|
|
12
12
|
"pyyaml>=5.1",
|
|
13
13
|
"attrs>=21.4.0,<=23.2.0",
|
|
@@ -20,7 +20,7 @@ setup(
|
|
|
20
20
|
description="GoodData Cloud Python SDK",
|
|
21
21
|
long_description=long_description,
|
|
22
22
|
long_description_content_type="text/markdown",
|
|
23
|
-
version="1.15.1.
|
|
23
|
+
version="1.15.1.dev3",
|
|
24
24
|
author="GoodData",
|
|
25
25
|
author_email="support@gooddata.com",
|
|
26
26
|
license="MIT",
|
|
@@ -30,7 +30,7 @@ setup(
|
|
|
30
30
|
packages=find_packages(exclude=["tests*"]),
|
|
31
31
|
python_requires=">=3.8.0",
|
|
32
32
|
project_urls={
|
|
33
|
-
"Documentation": "https://www.gooddata.com/docs/python-sdk/1.15.1.
|
|
33
|
+
"Documentation": "https://www.gooddata.com/docs/python-sdk/1.15.1.dev3",
|
|
34
34
|
"Source": "https://github.com/gooddata/gooddata-python-sdk",
|
|
35
35
|
},
|
|
36
36
|
classifiers=[
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/data_source/service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/export/__init__.py
RENAMED
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/export/request.py
RENAMED
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/export/service.py
RENAMED
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/organization/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/organization/service.py
RENAMED
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/permission/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/permission/service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/user/entity_model/user.py
RENAMED
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/validate_by_item.py
RENAMED
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/catalog/workspace/service.py
RENAMED
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/model/__init__.py
RENAMED
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/model/attribute.py
RENAMED
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk/compute/model/execution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -272,25 +272,6 @@ class TotalDefinitionOrdering:
|
|
|
272
272
|
)
|
|
273
273
|
|
|
274
274
|
|
|
275
|
-
def _create_dimension(bucket: VisualizationBucket, measures_item_identifier: Optional[str] = None) -> TableDimension:
|
|
276
|
-
item_ids = [a.local_id for a in bucket.attributes]
|
|
277
|
-
if measures_item_identifier is not None:
|
|
278
|
-
item_ids.append(measures_item_identifier)
|
|
279
|
-
return TableDimension(
|
|
280
|
-
item_ids=item_ids,
|
|
281
|
-
idx=_GET_DIM_INDEX_OF_BUCKET_TYPE[bucket.type],
|
|
282
|
-
)
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
def _get_dim_idx_for_predicate(
|
|
286
|
-
dims: list[TableDimension], predicate: Callable[[TableDimension], bool]
|
|
287
|
-
) -> Optional[int]:
|
|
288
|
-
for dim_idx, dim in enumerate(dims):
|
|
289
|
-
if predicate(dim):
|
|
290
|
-
return dim_idx
|
|
291
|
-
return None
|
|
292
|
-
|
|
293
|
-
|
|
294
275
|
@frozen
|
|
295
276
|
class AttributeLocator:
|
|
296
277
|
attribute_identifier: str
|
|
@@ -367,6 +348,73 @@ def _create_data_col_locators(locators: list[VisualizationSortLocator]) -> list[
|
|
|
367
348
|
return converted_locators
|
|
368
349
|
|
|
369
350
|
|
|
351
|
+
def _get_dim_idx_for_predicate(
|
|
352
|
+
dims: list[TableDimension], predicate: Callable[[TableDimension], bool]
|
|
353
|
+
) -> Optional[int]:
|
|
354
|
+
for dim_idx, dim in enumerate(dims):
|
|
355
|
+
if predicate(dim):
|
|
356
|
+
return dim_idx
|
|
357
|
+
return None
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def _append_attribute_sort_key(
|
|
361
|
+
dims: list[TableDimension], sort_item: VisualizationSort, sorting: list[list[SortKey]]
|
|
362
|
+
) -> None:
|
|
363
|
+
dim_idx = _get_dim_idx_for_predicate(dims, lambda x: sort_item.attribute_identifier in x.item_ids)
|
|
364
|
+
if dim_idx is None:
|
|
365
|
+
log_msg = (
|
|
366
|
+
f'attempting to sort by attribute with localId "{sort_item.attribute_identifier}" '
|
|
367
|
+
"but this attribute is not in any dimension."
|
|
368
|
+
)
|
|
369
|
+
logger.warning(log_msg)
|
|
370
|
+
return
|
|
371
|
+
|
|
372
|
+
sorting[dim_idx].append(
|
|
373
|
+
SortKeyAttribute(
|
|
374
|
+
sort_type=sort_item.type,
|
|
375
|
+
direction=sort_item.direction,
|
|
376
|
+
attribute_identifier=sort_item.attribute_identifier,
|
|
377
|
+
attribute_sort_type=sort_item.attribute_sort_type,
|
|
378
|
+
)
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def _append_measure_sort_key(
|
|
383
|
+
measure_dim: Optional[TableDimension],
|
|
384
|
+
non_measure_dim_idx: Optional[int],
|
|
385
|
+
sort_item: VisualizationSort,
|
|
386
|
+
sorting: list[list[SortKey]],
|
|
387
|
+
) -> None:
|
|
388
|
+
if non_measure_dim_idx is None:
|
|
389
|
+
logger.warning(
|
|
390
|
+
"Trying to use measure sort in an execution that only contains dimension with MeasureGroup. "
|
|
391
|
+
"This is not valid sort. Measure sort is used to sort the non-measure dimension by values "
|
|
392
|
+
"from measure dimension. Skipping."
|
|
393
|
+
)
|
|
394
|
+
return
|
|
395
|
+
|
|
396
|
+
if not measure_dim:
|
|
397
|
+
logger.warning("Trying to use measure sort in an execution that does not contain MeasureGroup. Skipping.")
|
|
398
|
+
return
|
|
399
|
+
|
|
400
|
+
sorting[non_measure_dim_idx].append(
|
|
401
|
+
SortKeyValue(
|
|
402
|
+
sort_type=sort_item.type,
|
|
403
|
+
direction=sort_item.direction,
|
|
404
|
+
measure_dim_identifier=f"dim_{measure_dim.idx}",
|
|
405
|
+
data_column_locators=_create_data_col_locators(sort_item.locators),
|
|
406
|
+
)
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
def _merge_dims_with_sorting(dims: list[TableDimension], sorting: list[list[SortKey]]) -> list[TableDimension]:
|
|
411
|
+
for dim in dims:
|
|
412
|
+
dim_sorting = sorting[dim.idx]
|
|
413
|
+
if dim_sorting:
|
|
414
|
+
dim.sorting = [ds.to_dict() for ds in dim_sorting]
|
|
415
|
+
return dims
|
|
416
|
+
|
|
417
|
+
|
|
370
418
|
def _create_dims_with_sorts(dims: list[TableDimension], sorts: list[VisualizationSort]) -> list[TableDimension]:
|
|
371
419
|
"""
|
|
372
420
|
Places sorting into dimensions. Returns the same dimensions objects but with modified sorting.
|
|
@@ -406,64 +454,6 @@ def _create_dims_with_sorts(dims: list[TableDimension], sorts: list[Visualizatio
|
|
|
406
454
|
return _merge_dims_with_sorting(dims, sorting)
|
|
407
455
|
|
|
408
456
|
|
|
409
|
-
def _merge_dims_with_sorting(dims: list[TableDimension], sorting: list[list[SortKey]]) -> list[TableDimension]:
|
|
410
|
-
for dim in dims:
|
|
411
|
-
dim_sorting = sorting[dim.idx]
|
|
412
|
-
if dim_sorting:
|
|
413
|
-
dim.sorting = [ds.to_dict() for ds in dim_sorting]
|
|
414
|
-
return dims
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
def _append_measure_sort_key(
|
|
418
|
-
measure_dim: Optional[TableDimension],
|
|
419
|
-
non_measure_dim_idx: Optional[int],
|
|
420
|
-
sort_item: VisualizationSort,
|
|
421
|
-
sorting: list[list[SortKey]],
|
|
422
|
-
) -> None:
|
|
423
|
-
if non_measure_dim_idx is None:
|
|
424
|
-
logger.warning(
|
|
425
|
-
"Trying to use measure sort in an execution that only contains dimension with MeasureGroup. "
|
|
426
|
-
"This is not valid sort. Measure sort is used to sort the non-measure dimension by values "
|
|
427
|
-
"from measure dimension. Skipping."
|
|
428
|
-
)
|
|
429
|
-
return
|
|
430
|
-
|
|
431
|
-
if not measure_dim:
|
|
432
|
-
logger.warning("Trying to use measure sort in an execution that does not contain MeasureGroup. Skipping.")
|
|
433
|
-
return
|
|
434
|
-
|
|
435
|
-
sorting[non_measure_dim_idx].append(
|
|
436
|
-
SortKeyValue(
|
|
437
|
-
sort_type=sort_item.type,
|
|
438
|
-
direction=sort_item.direction,
|
|
439
|
-
measure_dim_identifier=f"dim_{measure_dim.idx}",
|
|
440
|
-
data_column_locators=_create_data_col_locators(sort_item.locators),
|
|
441
|
-
)
|
|
442
|
-
)
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
def _append_attribute_sort_key(
|
|
446
|
-
dims: list[TableDimension], sort_item: VisualizationSort, sorting: list[list[SortKey]]
|
|
447
|
-
) -> None:
|
|
448
|
-
dim_idx = _get_dim_idx_for_predicate(dims, lambda x: sort_item.attribute_identifier in x.item_ids)
|
|
449
|
-
if dim_idx is None:
|
|
450
|
-
log_msg = (
|
|
451
|
-
f'attempting to sort by attribute with localId "{sort_item.attribute_identifier}" '
|
|
452
|
-
"but this attribute is not in any dimension."
|
|
453
|
-
)
|
|
454
|
-
logger.warning(log_msg)
|
|
455
|
-
return
|
|
456
|
-
|
|
457
|
-
sorting[dim_idx].append(
|
|
458
|
-
SortKeyAttribute(
|
|
459
|
-
sort_type=sort_item.type,
|
|
460
|
-
direction=sort_item.direction,
|
|
461
|
-
attribute_identifier=sort_item.attribute_identifier,
|
|
462
|
-
attribute_sort_type=sort_item.attribute_sort_type,
|
|
463
|
-
)
|
|
464
|
-
)
|
|
465
|
-
|
|
466
|
-
|
|
467
457
|
def _vis_is_transposed(visualization: Visualization) -> bool:
|
|
468
458
|
controls = visualization.properties.get("controls")
|
|
469
459
|
if not controls:
|
|
@@ -471,6 +461,16 @@ def _vis_is_transposed(visualization: Visualization) -> bool:
|
|
|
471
461
|
return controls.get("measureGroupDimension") == "rows"
|
|
472
462
|
|
|
473
463
|
|
|
464
|
+
def _create_dimension(bucket: VisualizationBucket, measures_item_identifier: Optional[str] = None) -> TableDimension:
|
|
465
|
+
item_ids = [a.local_id for a in bucket.attributes]
|
|
466
|
+
if measures_item_identifier is not None:
|
|
467
|
+
item_ids.append(measures_item_identifier)
|
|
468
|
+
return TableDimension(
|
|
469
|
+
item_ids=item_ids,
|
|
470
|
+
idx=_GET_DIM_INDEX_OF_BUCKET_TYPE[bucket.type],
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
|
|
474
474
|
def _create_dimensions(visualization: Visualization) -> list[TableDimension]:
|
|
475
475
|
measures_item_identifier = _MEASURE_GROUP_IDENTIFIER if visualization.metrics else None
|
|
476
476
|
row_bucket = visualization.get_bucket_of_type(BucketType.ROWS)
|
|
@@ -567,59 +567,22 @@ class TotalsComputeInfo:
|
|
|
567
567
|
self.column_subtotal_dimension_index = self.col_attr_ids.index(col_total_attr_id)
|
|
568
568
|
|
|
569
569
|
|
|
570
|
-
def
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
These special cases are -
|
|
574
|
-
1. Grand totals - is the value obtained from row and column totals.
|
|
575
|
-
2. Marginal totals - is the value obtained within the subgroups from row and column subtotals.
|
|
576
|
-
|
|
577
|
-
For `Grand Totals`, in Tiger AFM, you specify that you want total of totals with total that have only
|
|
578
|
-
"measureGroup" present.
|
|
579
|
-
For `Marginal Total`, in Tiger AFM, would need to iterate through both dimensions and obtain the missing
|
|
580
|
-
totalDimensions items based on the attribute and column identifiers order in buckets.
|
|
581
|
-
"""
|
|
582
|
-
totals: list[TotalDefinition] = []
|
|
583
|
-
row_bucket = visualization.get_bucket_of_type(BucketType.ROWS)
|
|
584
|
-
col_bucket = visualization.get_bucket_of_type(BucketType.COLS)
|
|
585
|
-
|
|
586
|
-
tci = TotalsComputeInfo(
|
|
587
|
-
row_attr_ids=[a.local_id for a in row_bucket.attributes],
|
|
588
|
-
col_attr_ids=[a.local_id for a in col_bucket.attributes],
|
|
589
|
-
measure_group_rows=[_MEASURE_GROUP_IDENTIFIER] if _MEASURE_GROUP_IDENTIFIER in dimensions[0].item_ids else [],
|
|
590
|
-
measure_group_cols=[_MEASURE_GROUP_IDENTIFIER] if _MEASURE_GROUP_IDENTIFIER in dimensions[1].item_ids else [],
|
|
591
|
-
)
|
|
592
|
-
for row_index, row_total in enumerate(row_bucket.totals):
|
|
593
|
-
tci.reset_to_defaults()
|
|
594
|
-
for col_index, col_total in enumerate(col_bucket.totals):
|
|
595
|
-
# Check for totals from same measure and type
|
|
596
|
-
if row_total.measure_id == col_total.measure_id and row_total.type == col_total.type:
|
|
597
|
-
tci.update_compute_info(col_total.attribute_id, row_total.attribute_id)
|
|
598
|
-
|
|
599
|
-
if tci.has_row_and_column_sub_totals:
|
|
600
|
-
totals.append(_extend_marginal_totals(col_index, row_total, tci))
|
|
601
|
-
|
|
602
|
-
if tci.has_row_subtotal_and_column_grand_total:
|
|
603
|
-
totals.append(_extend_marginal_totals_of_rows(row_index, row_total, tci))
|
|
604
|
-
|
|
605
|
-
if tci.has_column_subtotal_and_row_grand_total:
|
|
606
|
-
totals.append(_extend_marginal_totals_of_cols(row_index, row_total, tci))
|
|
607
|
-
|
|
608
|
-
if tci.has_row_and_column_grand_totals:
|
|
609
|
-
totals.append(_extend_grand_totals(row_index, row_total, tci))
|
|
610
|
-
|
|
611
|
-
return totals
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
def _extend_grand_totals(row_index: int, row_total: VisualizationTotal, tci: TotalsComputeInfo) -> TotalDefinition:
|
|
615
|
-
# Extend grand totals payload
|
|
616
|
-
row_dim = [TotalDimension(idx=0, items=tci.measure_group_rows)] if tci.measure_group_rows else []
|
|
617
|
-
col_dim = [TotalDimension(idx=1, items=tci.measure_group_cols)] if tci.measure_group_cols else []
|
|
570
|
+
def _extend_marginal_totals(col_index: int, row_total: VisualizationTotal, tci: TotalsComputeInfo) -> TotalDefinition:
|
|
571
|
+
# Extend marginal totals payload
|
|
618
572
|
return TotalDefinition(
|
|
619
|
-
local_id=
|
|
573
|
+
local_id=_marginal_total_local_identifier(row_total, col_index),
|
|
620
574
|
aggregation=row_total.type,
|
|
621
575
|
metric_local_id=row_total.measure_id,
|
|
622
|
-
total_dims=
|
|
576
|
+
total_dims=[
|
|
577
|
+
TotalDimension(
|
|
578
|
+
idx=0,
|
|
579
|
+
items=tci.row_attr_ids[: tci.row_dimension_index] + tci.measure_group_rows,
|
|
580
|
+
),
|
|
581
|
+
TotalDimension(
|
|
582
|
+
idx=1,
|
|
583
|
+
items=tci.col_attr_ids[: tci.column_dimension_index] + tci.measure_group_cols,
|
|
584
|
+
),
|
|
585
|
+
],
|
|
623
586
|
)
|
|
624
587
|
|
|
625
588
|
|
|
@@ -663,23 +626,60 @@ def _extend_marginal_totals_of_rows(
|
|
|
663
626
|
)
|
|
664
627
|
|
|
665
628
|
|
|
666
|
-
def
|
|
667
|
-
# Extend
|
|
629
|
+
def _extend_grand_totals(row_index: int, row_total: VisualizationTotal, tci: TotalsComputeInfo) -> TotalDefinition:
|
|
630
|
+
# Extend grand totals payload
|
|
631
|
+
row_dim = [TotalDimension(idx=0, items=tci.measure_group_rows)] if tci.measure_group_rows else []
|
|
632
|
+
col_dim = [TotalDimension(idx=1, items=tci.measure_group_cols)] if tci.measure_group_cols else []
|
|
668
633
|
return TotalDefinition(
|
|
669
|
-
local_id=
|
|
634
|
+
local_id=_grand_total_local_identifier(row_total, row_index),
|
|
670
635
|
aggregation=row_total.type,
|
|
671
636
|
metric_local_id=row_total.measure_id,
|
|
672
|
-
total_dims=
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
637
|
+
total_dims=row_dim + col_dim,
|
|
638
|
+
)
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
def _get_additional_totals(visualization: Visualization, dimensions: list[TableDimension]) -> list[TotalDefinition]:
|
|
642
|
+
"""Construct special cases of pivot table totals.
|
|
643
|
+
|
|
644
|
+
These special cases are -
|
|
645
|
+
1. Grand totals - is the value obtained from row and column totals.
|
|
646
|
+
2. Marginal totals - is the value obtained within the subgroups from row and column subtotals.
|
|
647
|
+
|
|
648
|
+
For `Grand Totals`, in Tiger AFM, you specify that you want total of totals with total that have only
|
|
649
|
+
"measureGroup" present.
|
|
650
|
+
For `Marginal Total`, in Tiger AFM, would need to iterate through both dimensions and obtain the missing
|
|
651
|
+
totalDimensions items based on the attribute and column identifiers order in buckets.
|
|
652
|
+
"""
|
|
653
|
+
totals: list[TotalDefinition] = []
|
|
654
|
+
row_bucket = visualization.get_bucket_of_type(BucketType.ROWS)
|
|
655
|
+
col_bucket = visualization.get_bucket_of_type(BucketType.COLS)
|
|
656
|
+
|
|
657
|
+
tci = TotalsComputeInfo(
|
|
658
|
+
row_attr_ids=[a.local_id for a in row_bucket.attributes],
|
|
659
|
+
col_attr_ids=[a.local_id for a in col_bucket.attributes],
|
|
660
|
+
measure_group_rows=[_MEASURE_GROUP_IDENTIFIER] if _MEASURE_GROUP_IDENTIFIER in dimensions[0].item_ids else [],
|
|
661
|
+
measure_group_cols=[_MEASURE_GROUP_IDENTIFIER] if _MEASURE_GROUP_IDENTIFIER in dimensions[1].item_ids else [],
|
|
682
662
|
)
|
|
663
|
+
for row_index, row_total in enumerate(row_bucket.totals):
|
|
664
|
+
tci.reset_to_defaults()
|
|
665
|
+
for col_index, col_total in enumerate(col_bucket.totals):
|
|
666
|
+
# Check for totals from same measure and type
|
|
667
|
+
if row_total.measure_id == col_total.measure_id and row_total.type == col_total.type:
|
|
668
|
+
tci.update_compute_info(col_total.attribute_id, row_total.attribute_id)
|
|
669
|
+
|
|
670
|
+
if tci.has_row_and_column_sub_totals:
|
|
671
|
+
totals.append(_extend_marginal_totals(col_index, row_total, tci))
|
|
672
|
+
|
|
673
|
+
if tci.has_row_subtotal_and_column_grand_total:
|
|
674
|
+
totals.append(_extend_marginal_totals_of_rows(row_index, row_total, tci))
|
|
675
|
+
|
|
676
|
+
if tci.has_column_subtotal_and_row_grand_total:
|
|
677
|
+
totals.append(_extend_marginal_totals_of_cols(row_index, row_total, tci))
|
|
678
|
+
|
|
679
|
+
if tci.has_row_and_column_grand_totals:
|
|
680
|
+
totals.append(_extend_grand_totals(row_index, row_total, tci))
|
|
681
|
+
|
|
682
|
+
return totals
|
|
683
683
|
|
|
684
684
|
|
|
685
685
|
def _get_computable_totals(visualization: Visualization, dimensions: list[TableDimension]) -> list[TotalDefinition]:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gooddata-sdk-1.15.1.dev2 → gooddata-sdk-1.15.1.dev3}/gooddata_sdk.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|