TM1py 2.2.2__tar.gz → 2.2.4__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.
- {tm1py-2.2.2 → tm1py-2.2.4}/PKG-INFO +1 -1
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/MDXView.py +27 -2
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ElementService.py +6 -3
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/FileService.py +17 -1
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ViewService.py +5 -2
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py.egg-info/PKG-INFO +1 -1
- {tm1py-2.2.2 → tm1py-2.2.4}/pyproject.toml +1 -1
- {tm1py-2.2.2 → tm1py-2.2.4}/LICENSE +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/README.md +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Exceptions/Exceptions.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Exceptions/__init__.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Annotation.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Application.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Axis.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Chore.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/ChoreFrequency.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/ChoreStartTime.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/ChoreTask.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Cube.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Dimension.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Element.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/ElementAttribute.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Git.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/GitCommit.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/GitPlan.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/GitProject.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/GitRemote.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Hierarchy.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/NativeView.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Process.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/ProcessDebugBreakpoint.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Rules.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Sandbox.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Server.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Subset.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/TM1Object.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/User.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/View.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/__init__.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/AnnotationService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ApplicationService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/AuditLogService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/CellService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ChoreService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ConfigurationService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/CubeService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/DimensionService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/GitService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/HierarchyService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/JobService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/LoggerService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ManageService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/MessageLogService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/MonitoringService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ObjectService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/PowerBiService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ProcessService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/RestService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/SandboxService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/SecurityService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ServerService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/SessionService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/SubsetService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/TM1Service.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ThreadService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/TransactionLogService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/UserService.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/__init__.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Utils/MDXUtils.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Utils/Utils.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Utils/__init__.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/__init__.py +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py.egg-info/SOURCES.txt +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py.egg-info/dependency_links.txt +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py.egg-info/requires.txt +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/TM1py.egg-info/top_level.txt +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/setup.cfg +0 -0
- {tm1py-2.2.2 → tm1py-2.2.4}/setup.py +0 -0
|
@@ -8,16 +8,31 @@ from typing import Dict, Optional
|
|
|
8
8
|
from TM1py.Objects.View import View
|
|
9
9
|
from TM1py.Utils import case_and_space_insensitive_equals
|
|
10
10
|
|
|
11
|
+
MDX_VIEW_EXCLUDED_KEYS = frozenset(
|
|
12
|
+
{
|
|
13
|
+
"@odata.type",
|
|
14
|
+
"@odata.context",
|
|
15
|
+
"@odata.etag",
|
|
16
|
+
"Name",
|
|
17
|
+
"MDX",
|
|
18
|
+
"Cube",
|
|
19
|
+
"Attributes",
|
|
20
|
+
"LocalizedAttributes",
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
11
24
|
|
|
12
25
|
class MDXView(View):
|
|
13
26
|
"""Abstraction on TM1 MDX view
|
|
14
27
|
|
|
15
|
-
IMPORTANT. MDXViews can't be seen through the old TM1 clients (
|
|
28
|
+
IMPORTANT. MDXViews can't be seen through the old TM1 clients (Architect, Perspectives). They do exist though!
|
|
16
29
|
"""
|
|
17
30
|
|
|
18
|
-
def __init__(self, cube_name: str, view_name: str, MDX: str):
|
|
31
|
+
def __init__(self, cube_name: str, view_name: str, MDX: str, dynamic_properties: Optional[Dict] = None):
|
|
19
32
|
View.__init__(self, cube_name, view_name)
|
|
20
33
|
self._mdx = MDX
|
|
34
|
+
self._dynamic_properties = {}
|
|
35
|
+
self.dynamic_properties = dynamic_properties
|
|
21
36
|
|
|
22
37
|
@property
|
|
23
38
|
def mdx(self):
|
|
@@ -35,6 +50,14 @@ class MDXView(View):
|
|
|
35
50
|
def MDX(self, value: str):
|
|
36
51
|
self._mdx = value
|
|
37
52
|
|
|
53
|
+
@property
|
|
54
|
+
def dynamic_properties(self) -> Dict:
|
|
55
|
+
return self._dynamic_properties
|
|
56
|
+
|
|
57
|
+
@dynamic_properties.setter
|
|
58
|
+
def dynamic_properties(self, value: Optional[Dict]) -> None:
|
|
59
|
+
self._dynamic_properties = value or {}
|
|
60
|
+
|
|
38
61
|
@property
|
|
39
62
|
def body(self) -> str:
|
|
40
63
|
return self.construct_body()
|
|
@@ -74,6 +97,7 @@ class MDXView(View):
|
|
|
74
97
|
cube_name=view_as_dict["Cube"]["Name"] if not cube_name else cube_name,
|
|
75
98
|
view_name=view_as_dict["Name"],
|
|
76
99
|
MDX=view_as_dict["MDX"],
|
|
100
|
+
dynamic_properties={k: v for k, v in view_as_dict.items() if k not in MDX_VIEW_EXCLUDED_KEYS},
|
|
77
101
|
)
|
|
78
102
|
|
|
79
103
|
def construct_body(self) -> str:
|
|
@@ -81,4 +105,5 @@ class MDXView(View):
|
|
|
81
105
|
mdx_view_as_dict["@odata.type"] = "ibm.tm1.api.v1.MDXView"
|
|
82
106
|
mdx_view_as_dict["Name"] = self._name
|
|
83
107
|
mdx_view_as_dict["MDX"] = self._mdx
|
|
108
|
+
mdx_view_as_dict.update({k: v for k, v in self._dynamic_properties.items() if k not in MDX_VIEW_EXCLUDED_KEYS})
|
|
84
109
|
return json.dumps(mdx_view_as_dict, ensure_ascii=False)
|
|
@@ -1187,7 +1187,7 @@ class ElementService(ObjectService):
|
|
|
1187
1187
|
to return, can be None or empty
|
|
1188
1188
|
:param element_properties: list of element properties (e.g., Name, UniqueName, Type, Level, Index,
|
|
1189
1189
|
Attributes/Color) to return, can be empty
|
|
1190
|
-
:return: dictionary of members, unique names, weights, types, and parents
|
|
1190
|
+
:return: dictionary of members, unique names, weights, types, and parents or async id when return_async_id is True
|
|
1191
1191
|
"""
|
|
1192
1192
|
|
|
1193
1193
|
top = f"$top={top_records};" if top_records else ""
|
|
@@ -1241,8 +1241,11 @@ class ElementService(ObjectService):
|
|
|
1241
1241
|
|
|
1242
1242
|
payload = {"MDX": mdx}
|
|
1243
1243
|
response = self._rest.POST(url, json.dumps(payload, ensure_ascii=False), **kwargs)
|
|
1244
|
-
|
|
1245
|
-
|
|
1244
|
+
if kwargs.get("return_async_id", False):
|
|
1245
|
+
return response
|
|
1246
|
+
else:
|
|
1247
|
+
raw_dict = response.json()
|
|
1248
|
+
return [tuples["Members"] for tuples in raw_dict["Tuples"]]
|
|
1246
1249
|
|
|
1247
1250
|
def remove_edge(self, dimension_name: str, hierarchy_name: str, parent: str, component: str, **kwargs) -> Response:
|
|
1248
1251
|
"""Remove one edge from hierarchy. Fails if parent or child element doesn't exist.
|
|
@@ -78,9 +78,25 @@ class FileService(ObjectService):
|
|
|
78
78
|
path = Path(folder_name)
|
|
79
79
|
url = self._construct_content_url(path, exclude_path_end=True, extension="Contents")
|
|
80
80
|
|
|
81
|
-
body = {"@odata.type": "#ibm.tm1.api.v1.Folder", "Name":
|
|
81
|
+
body = {"@odata.type": "#ibm.tm1.api.v1.Folder", "Name": path.name}
|
|
82
82
|
self._rest.POST(url, json.dumps(body), **kwargs)
|
|
83
83
|
|
|
84
|
+
@require_version(version="12")
|
|
85
|
+
def create_folder(self, folder_name: Union[str, Path], **kwargs):
|
|
86
|
+
"""Create folder(s)
|
|
87
|
+
|
|
88
|
+
Supports recursive creation (e.g., 'folderA/folderB/folderC')
|
|
89
|
+
|
|
90
|
+
:param folder_name: folder name or path to nested folders
|
|
91
|
+
:return: None
|
|
92
|
+
"""
|
|
93
|
+
path = Path(folder_name)
|
|
94
|
+
folder_path = Path()
|
|
95
|
+
for part in path.parts:
|
|
96
|
+
folder_path = folder_path.joinpath(part)
|
|
97
|
+
if not self.exists(folder_path, **kwargs):
|
|
98
|
+
self._create_folder(folder_name=folder_path, **kwargs)
|
|
99
|
+
|
|
84
100
|
def _construct_content_url(self, path: Path, exclude_path_end: bool = True, extension: str = "Contents") -> str:
|
|
85
101
|
"""Dynamically construct URL to use in FileService functions
|
|
86
102
|
|
|
@@ -7,7 +7,7 @@ from requests import Response
|
|
|
7
7
|
|
|
8
8
|
from TM1py.Exceptions.Exceptions import TM1pyRestException
|
|
9
9
|
from TM1py.Objects import View
|
|
10
|
-
from TM1py.Objects.MDXView import MDXView
|
|
10
|
+
from TM1py.Objects.MDXView import MDX_VIEW_EXCLUDED_KEYS, MDXView
|
|
11
11
|
from TM1py.Objects.NativeView import NativeView
|
|
12
12
|
from TM1py.Services.ObjectService import ObjectService
|
|
13
13
|
from TM1py.Services.RestService import RestService
|
|
@@ -65,8 +65,11 @@ class ViewService(ObjectService):
|
|
|
65
65
|
url = format_url("/Cubes('{}')/{}('{}')?$expand=*", cube_name, view_type, view_name)
|
|
66
66
|
response = self._rest.GET(url, **kwargs)
|
|
67
67
|
view_as_dict = response.json()
|
|
68
|
+
dynamic_properties = {k: v for k, v in view_as_dict.items() if k not in MDX_VIEW_EXCLUDED_KEYS}
|
|
68
69
|
if "MDX" in view_as_dict:
|
|
69
|
-
return MDXView(
|
|
70
|
+
return MDXView(
|
|
71
|
+
cube_name=cube_name, view_name=view_name, MDX=view_as_dict["MDX"], dynamic_properties=dynamic_properties
|
|
72
|
+
)
|
|
70
73
|
else:
|
|
71
74
|
return self.get_native_view(cube_name=cube_name, view_name=view_name, private=private)
|
|
72
75
|
|
|
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
|
|
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
|
|
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
|