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.
Files changed (78) hide show
  1. {tm1py-2.2.2 → tm1py-2.2.4}/PKG-INFO +1 -1
  2. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/MDXView.py +27 -2
  3. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ElementService.py +6 -3
  4. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/FileService.py +17 -1
  5. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ViewService.py +5 -2
  6. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py.egg-info/PKG-INFO +1 -1
  7. {tm1py-2.2.2 → tm1py-2.2.4}/pyproject.toml +1 -1
  8. {tm1py-2.2.2 → tm1py-2.2.4}/LICENSE +0 -0
  9. {tm1py-2.2.2 → tm1py-2.2.4}/README.md +0 -0
  10. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Exceptions/Exceptions.py +0 -0
  11. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Exceptions/__init__.py +0 -0
  12. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Annotation.py +0 -0
  13. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Application.py +0 -0
  14. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Axis.py +0 -0
  15. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Chore.py +0 -0
  16. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/ChoreFrequency.py +0 -0
  17. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/ChoreStartTime.py +0 -0
  18. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/ChoreTask.py +0 -0
  19. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Cube.py +0 -0
  20. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Dimension.py +0 -0
  21. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Element.py +0 -0
  22. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/ElementAttribute.py +0 -0
  23. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Git.py +0 -0
  24. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/GitCommit.py +0 -0
  25. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/GitPlan.py +0 -0
  26. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/GitProject.py +0 -0
  27. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/GitRemote.py +0 -0
  28. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Hierarchy.py +0 -0
  29. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/NativeView.py +0 -0
  30. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Process.py +0 -0
  31. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/ProcessDebugBreakpoint.py +0 -0
  32. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Rules.py +0 -0
  33. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Sandbox.py +0 -0
  34. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Server.py +0 -0
  35. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/Subset.py +0 -0
  36. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/TM1Object.py +0 -0
  37. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/User.py +0 -0
  38. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/View.py +0 -0
  39. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Objects/__init__.py +0 -0
  40. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/AnnotationService.py +0 -0
  41. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ApplicationService.py +0 -0
  42. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/AuditLogService.py +0 -0
  43. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/CellService.py +0 -0
  44. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ChoreService.py +0 -0
  45. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ConfigurationService.py +0 -0
  46. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/CubeService.py +0 -0
  47. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/DimensionService.py +0 -0
  48. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/GitService.py +0 -0
  49. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/HierarchyService.py +0 -0
  50. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/JobService.py +0 -0
  51. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/LoggerService.py +0 -0
  52. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ManageService.py +0 -0
  53. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/MessageLogService.py +0 -0
  54. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/MonitoringService.py +0 -0
  55. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ObjectService.py +0 -0
  56. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/PowerBiService.py +0 -0
  57. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ProcessService.py +0 -0
  58. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/RestService.py +0 -0
  59. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/SandboxService.py +0 -0
  60. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/SecurityService.py +0 -0
  61. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ServerService.py +0 -0
  62. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/SessionService.py +0 -0
  63. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/SubsetService.py +0 -0
  64. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/TM1Service.py +0 -0
  65. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/ThreadService.py +0 -0
  66. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/TransactionLogService.py +0 -0
  67. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/UserService.py +0 -0
  68. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Services/__init__.py +0 -0
  69. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Utils/MDXUtils.py +0 -0
  70. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Utils/Utils.py +0 -0
  71. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/Utils/__init__.py +0 -0
  72. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py/__init__.py +0 -0
  73. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py.egg-info/SOURCES.txt +0 -0
  74. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py.egg-info/dependency_links.txt +0 -0
  75. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py.egg-info/requires.txt +0 -0
  76. {tm1py-2.2.2 → tm1py-2.2.4}/TM1py.egg-info/top_level.txt +0 -0
  77. {tm1py-2.2.2 → tm1py-2.2.4}/setup.cfg +0 -0
  78. {tm1py-2.2.2 → tm1py-2.2.4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TM1py
3
- Version: 2.2.2
3
+ Version: 2.2.4
4
4
  Summary: A python module for TM1.
5
5
  Author-email: Marius Wirtz <MWirtz@cubewise.com>
6
6
  License: MIT
@@ -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 (Archict, Perspectives). They do exist though!
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
- raw_dict = response.json()
1245
- return [tuples["Members"] for tuples in raw_dict["Tuples"]]
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": folder_name.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(cube_name=cube_name, view_name=view_name, MDX=view_as_dict["MDX"])
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TM1py
3
- Version: 2.2.2
3
+ Version: 2.2.4
4
4
  Summary: A python module for TM1.
5
5
  Author-email: Marius Wirtz <MWirtz@cubewise.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "TM1py"
7
- version = "2.2.2"
7
+ version = "2.2.4"
8
8
  description = "A python module for TM1."
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
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