anaplan-sdk 0.5.0a1__py3-none-any.whl → 0.5.0a2__py3-none-any.whl
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.
- anaplan_sdk/_async_clients/_alm.py +24 -31
- anaplan_sdk/_async_clients/_audit.py +7 -9
- anaplan_sdk/_async_clients/_bulk.py +66 -64
- anaplan_sdk/_async_clients/_cloud_works.py +36 -34
- anaplan_sdk/_async_clients/_cw_flow.py +13 -13
- anaplan_sdk/_async_clients/_transactional.py +40 -33
- anaplan_sdk/_clients/_alm.py +22 -31
- anaplan_sdk/_clients/_audit.py +7 -10
- anaplan_sdk/_clients/_bulk.py +63 -62
- anaplan_sdk/_clients/_cloud_works.py +32 -32
- anaplan_sdk/_clients/_cw_flow.py +13 -13
- anaplan_sdk/_clients/_transactional.py +42 -33
- anaplan_sdk/{_base.py → _services.py} +86 -72
- anaplan_sdk/models/__init__.py +2 -0
- anaplan_sdk/models/_bulk.py +2 -9
- {anaplan_sdk-0.5.0a1.dist-info → anaplan_sdk-0.5.0a2.dist-info}/METADATA +1 -1
- anaplan_sdk-0.5.0a2.dist-info/RECORD +30 -0
- anaplan_sdk-0.5.0a1.dist-info/RECORD +0 -30
- {anaplan_sdk-0.5.0a1.dist-info → anaplan_sdk-0.5.0a2.dist-info}/WHEEL +0 -0
- {anaplan_sdk-0.5.0a1.dist-info → anaplan_sdk-0.5.0a2.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +1,8 @@
|
|
1
1
|
import logging
|
2
2
|
from typing import Any, Literal
|
3
3
|
|
4
|
-
import
|
5
|
-
|
6
|
-
from anaplan_sdk._base import (
|
7
|
-
_BaseClient,
|
4
|
+
from anaplan_sdk._services import (
|
5
|
+
_HttpService,
|
8
6
|
connection_body_payload,
|
9
7
|
construct_payload,
|
10
8
|
integration_payload,
|
@@ -31,11 +29,11 @@ from ._cw_flow import _FlowClient
|
|
31
29
|
logger = logging.getLogger("anaplan_sdk")
|
32
30
|
|
33
31
|
|
34
|
-
class _CloudWorksClient
|
35
|
-
def __init__(self,
|
32
|
+
class _CloudWorksClient:
|
33
|
+
def __init__(self, http: _HttpService) -> None:
|
34
|
+
self._http = http
|
36
35
|
self._url = "https://api.cloudworks.anaplan.com/2/0/integrations"
|
37
|
-
self._flow = _FlowClient(
|
38
|
-
super().__init__(retry_count, client)
|
36
|
+
self._flow = _FlowClient(self._http)
|
39
37
|
|
40
38
|
@property
|
41
39
|
def flows(self) -> _FlowClient:
|
@@ -51,7 +49,7 @@ class _CloudWorksClient(_BaseClient):
|
|
51
49
|
"""
|
52
50
|
return [
|
53
51
|
Connection.model_validate(e)
|
54
|
-
for e in self.
|
52
|
+
for e in self._http.get_paginated(f"{self._url}/connections", "connections")
|
55
53
|
]
|
56
54
|
|
57
55
|
def create_connection(self, con_info: ConnectionInput | dict[str, Any]) -> str:
|
@@ -62,7 +60,7 @@ class _CloudWorksClient(_BaseClient):
|
|
62
60
|
against the ConnectionInput model before sending the request.
|
63
61
|
:return: The ID of the new connection.
|
64
62
|
"""
|
65
|
-
res = self.
|
63
|
+
res = self._http.post(
|
66
64
|
f"{self._url}/connections", json=construct_payload(ConnectionInput, con_info)
|
67
65
|
)
|
68
66
|
connection_id = res["connections"]["connectionId"]
|
@@ -77,7 +75,7 @@ class _CloudWorksClient(_BaseClient):
|
|
77
75
|
as when initially creating the connection again. If you want to update only some of
|
78
76
|
the details, use the `patch_connection` method instead.
|
79
77
|
"""
|
80
|
-
self.
|
78
|
+
self._http.put(f"{self._url}/connections/{con_id}", json=connection_body_payload(con_info))
|
81
79
|
|
82
80
|
def patch_connection(self, con_id: str, body: dict[str, Any]) -> None:
|
83
81
|
"""
|
@@ -86,14 +84,14 @@ class _CloudWorksClient(_BaseClient):
|
|
86
84
|
:param body: The name and details of the connection. You can pass all the same details as
|
87
85
|
when initially creating the connection again, or just any one of them.
|
88
86
|
"""
|
89
|
-
self.
|
87
|
+
self._http.patch(f"{self._url}/connections/{con_id}", json=body)
|
90
88
|
|
91
89
|
def delete_connection(self, con_id: str) -> None:
|
92
90
|
"""
|
93
91
|
Delete an existing connection in CloudWorks.
|
94
92
|
:param con_id: The ID of the connection to delete.
|
95
93
|
"""
|
96
|
-
self.
|
94
|
+
self._http.delete(f"{self._url}/connections/{con_id}")
|
97
95
|
logger.info(f"Deleted connection '{con_id}'.")
|
98
96
|
|
99
97
|
def get_integrations(
|
@@ -107,7 +105,7 @@ class _CloudWorksClient(_BaseClient):
|
|
107
105
|
params = {"sortBy": "name" if sort_by_name == "ascending" else "-name"}
|
108
106
|
return [
|
109
107
|
Integration.model_validate(e)
|
110
|
-
for e in self.
|
108
|
+
for e in self._http.get_paginated(f"{self._url}", "integrations", params=params)
|
111
109
|
]
|
112
110
|
|
113
111
|
def get_integration(self, integration_id: str) -> SingleIntegration:
|
@@ -120,7 +118,7 @@ class _CloudWorksClient(_BaseClient):
|
|
120
118
|
:return: The details of the integration, without the integration type.
|
121
119
|
"""
|
122
120
|
return SingleIntegration.model_validate(
|
123
|
-
(self.
|
121
|
+
(self._http.get(f"{self._url}/{integration_id}"))["integration"]
|
124
122
|
)
|
125
123
|
|
126
124
|
def create_integration(
|
@@ -147,7 +145,9 @@ class _CloudWorksClient(_BaseClient):
|
|
147
145
|
:return: The ID of the new integration.
|
148
146
|
"""
|
149
147
|
json = integration_payload(body)
|
150
|
-
integration_id = (self.
|
148
|
+
integration_id = (self._http.post(f"{self._url}", json=json))["integration"][
|
149
|
+
"integrationId"
|
150
|
+
]
|
151
151
|
logger.info(f"Created integration '{integration_id}'.")
|
152
152
|
return integration_id
|
153
153
|
|
@@ -162,7 +162,7 @@ class _CloudWorksClient(_BaseClient):
|
|
162
162
|
of the details, use the `patch_integration` method instead.
|
163
163
|
"""
|
164
164
|
json = integration_payload(body)
|
165
|
-
self.
|
165
|
+
self._http.put(f"{self._url}/{integration_id}", json=json)
|
166
166
|
|
167
167
|
def run_integration(self, integration_id: str) -> str:
|
168
168
|
"""
|
@@ -170,7 +170,7 @@ class _CloudWorksClient(_BaseClient):
|
|
170
170
|
:param integration_id: The ID of the integration to run.
|
171
171
|
:return: The ID of the run instance.
|
172
172
|
"""
|
173
|
-
run_id = (self.
|
173
|
+
run_id = (self._http.post_empty(f"{self._url}/{integration_id}/run"))["run"]["id"]
|
174
174
|
logger.info(f"Started integration run '{run_id}' for integration '{integration_id}'.")
|
175
175
|
return run_id
|
176
176
|
|
@@ -179,7 +179,7 @@ class _CloudWorksClient(_BaseClient):
|
|
179
179
|
Delete an existing integration in CloudWorks.
|
180
180
|
:param integration_id: The ID of the integration to delete.
|
181
181
|
"""
|
182
|
-
self.
|
182
|
+
self._http.delete(f"{self._url}/{integration_id}")
|
183
183
|
logger.info(f"Deleted integration '{integration_id}'.")
|
184
184
|
|
185
185
|
def get_run_history(self, integration_id: str) -> list[RunSummary]:
|
@@ -190,7 +190,7 @@ class _CloudWorksClient(_BaseClient):
|
|
190
190
|
"""
|
191
191
|
return [
|
192
192
|
RunSummary.model_validate(e)
|
193
|
-
for e in (self.
|
193
|
+
for e in (self._http.get(f"{self._url}/runs/{integration_id}"))["history_of_runs"].get(
|
194
194
|
"runs", []
|
195
195
|
)
|
196
196
|
]
|
@@ -201,7 +201,7 @@ class _CloudWorksClient(_BaseClient):
|
|
201
201
|
:param run_id: The ID of the run to retrieve.
|
202
202
|
:return: The details of the run.
|
203
203
|
"""
|
204
|
-
return RunStatus.model_validate((self.
|
204
|
+
return RunStatus.model_validate((self._http.get(f"{self._url}/run/{run_id}"))["run"])
|
205
205
|
|
206
206
|
def get_run_error(self, run_id: str) -> RunError | None:
|
207
207
|
"""
|
@@ -210,7 +210,7 @@ class _CloudWorksClient(_BaseClient):
|
|
210
210
|
:param run_id: The ID of the run to retrieve.
|
211
211
|
:return: The details of the run error.
|
212
212
|
"""
|
213
|
-
run = self.
|
213
|
+
run = self._http.get(f"{self._url}/runerror/{run_id}")
|
214
214
|
return RunError.model_validate(run["runs"]) if run.get("runs") else None
|
215
215
|
|
216
216
|
def create_schedule(
|
@@ -223,7 +223,7 @@ class _CloudWorksClient(_BaseClient):
|
|
223
223
|
dictionary as per the documentation. If a dictionary is passed, it will be validated
|
224
224
|
against the ScheduleInput model before sending the request.
|
225
225
|
"""
|
226
|
-
self.
|
226
|
+
self._http.post(
|
227
227
|
f"{self._url}/{integration_id}/schedule",
|
228
228
|
json=schedule_payload(integration_id, schedule),
|
229
229
|
)
|
@@ -239,7 +239,7 @@ class _CloudWorksClient(_BaseClient):
|
|
239
239
|
dictionary as per the documentation. If a dictionary is passed, it will be validated
|
240
240
|
against the ScheduleInput model before sending the request.
|
241
241
|
"""
|
242
|
-
self.
|
242
|
+
self._http.put(
|
243
243
|
f"{self._url}/{integration_id}/schedule",
|
244
244
|
json=schedule_payload(integration_id, schedule),
|
245
245
|
)
|
@@ -253,7 +253,7 @@ class _CloudWorksClient(_BaseClient):
|
|
253
253
|
:param integration_id: The ID of the integration to schedule.
|
254
254
|
:param status: The status of the schedule. This can be either "enabled" or "disabled".
|
255
255
|
"""
|
256
|
-
self.
|
256
|
+
self._http.post_empty(f"{self._url}/{integration_id}/schedule/status/{status}")
|
257
257
|
logger.info(f"Set schedule status to '{status}' for integration '{integration_id}'.")
|
258
258
|
|
259
259
|
def delete_schedule(self, integration_id: str) -> None:
|
@@ -261,7 +261,7 @@ class _CloudWorksClient(_BaseClient):
|
|
261
261
|
Delete an integration schedule in CloudWorks. A schedule must already exist.
|
262
262
|
:param integration_id: The ID of the integration to schedule.
|
263
263
|
"""
|
264
|
-
self.
|
264
|
+
self._http.delete(f"{self._url}/{integration_id}/schedule")
|
265
265
|
logger.info(f"Deleted schedule for integration '{integration_id}'.")
|
266
266
|
|
267
267
|
def get_notification_config(
|
@@ -281,7 +281,7 @@ class _CloudWorksClient(_BaseClient):
|
|
281
281
|
if integration_id:
|
282
282
|
notification_id = (self.get_integration(integration_id)).notification_id
|
283
283
|
return NotificationConfig.model_validate(
|
284
|
-
(self.
|
284
|
+
(self._http.get(f"{self._url}/notification/{notification_id}"))["notifications"]
|
285
285
|
)
|
286
286
|
|
287
287
|
def create_notification_config(self, config: NotificationInput | dict[str, Any]) -> str:
|
@@ -295,7 +295,7 @@ class _CloudWorksClient(_BaseClient):
|
|
295
295
|
validated against the NotificationConfig model before sending the request.
|
296
296
|
:return: The ID of the new notification configuration.
|
297
297
|
"""
|
298
|
-
res = self.
|
298
|
+
res = self._http.post(
|
299
299
|
f"{self._url}/notification", json=construct_payload(NotificationInput, config)
|
300
300
|
)
|
301
301
|
notification_id = res["notification"]["notificationId"]
|
@@ -315,7 +315,7 @@ class _CloudWorksClient(_BaseClient):
|
|
315
315
|
a dictionary as per the documentation. If a dictionary is passed, it will be
|
316
316
|
validated against the NotificationConfig model before sending the request.
|
317
317
|
"""
|
318
|
-
self.
|
318
|
+
self._http.put(
|
319
319
|
f"{self._url}/notification/{notification_id}",
|
320
320
|
json=construct_payload(NotificationInput, config),
|
321
321
|
)
|
@@ -334,7 +334,7 @@ class _CloudWorksClient(_BaseClient):
|
|
334
334
|
raise ValueError("Either notification_id or integration_id must be specified.")
|
335
335
|
if integration_id:
|
336
336
|
notification_id = (self.get_integration(integration_id)).notification_id
|
337
|
-
self.
|
337
|
+
self._http.delete(f"{self._url}/notification/{notification_id}")
|
338
338
|
logger.info(f"Deleted notification configuration '{notification_id}'.")
|
339
339
|
|
340
340
|
def get_import_error_dump(self, run_id: str) -> bytes:
|
@@ -347,7 +347,7 @@ class _CloudWorksClient(_BaseClient):
|
|
347
347
|
:param run_id: The ID of the run to retrieve.
|
348
348
|
:return: The error dump.
|
349
349
|
"""
|
350
|
-
return self.
|
350
|
+
return self._http.get_binary(f"{self._url}/run/{run_id}/dump")
|
351
351
|
|
352
352
|
def get_process_error_dump(self, run_id: str, action_id: int | str) -> bytes:
|
353
353
|
"""
|
@@ -357,4 +357,4 @@ class _CloudWorksClient(_BaseClient):
|
|
357
357
|
:param action_id: The ID of the action to retrieve. This can be found in the RunError.
|
358
358
|
:return: The error dump.
|
359
359
|
"""
|
360
|
-
return self.
|
360
|
+
return self._http.get_binary(f"{self._url}/run/{run_id}/process/import/{action_id}/dumps")
|
anaplan_sdk/_clients/_cw_flow.py
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
import logging
|
2
2
|
from typing import Any
|
3
3
|
|
4
|
-
import
|
5
|
-
|
6
|
-
from anaplan_sdk._base import _BaseClient, construct_payload
|
4
|
+
from anaplan_sdk._services import _HttpService, construct_payload
|
7
5
|
from anaplan_sdk.models.flows import Flow, FlowInput, FlowSummary
|
8
6
|
|
9
7
|
logger = logging.getLogger("anaplan_sdk")
|
10
8
|
|
11
9
|
|
12
|
-
class _FlowClient
|
13
|
-
def __init__(self,
|
10
|
+
class _FlowClient:
|
11
|
+
def __init__(self, http: _HttpService) -> None:
|
12
|
+
self._http = http
|
14
13
|
self._url = "https://api.cloudworks.anaplan.com/2/0/integrationflows"
|
15
|
-
super().__init__(retry_count, client)
|
16
14
|
|
17
15
|
def get_flows(self, current_user_only: bool = False) -> list[FlowSummary]:
|
18
16
|
"""
|
@@ -23,7 +21,9 @@ class _FlowClient(_BaseClient):
|
|
23
21
|
params = {"myIntegrations": 1 if current_user_only else 0}
|
24
22
|
return [
|
25
23
|
FlowSummary.model_validate(e)
|
26
|
-
for e in self.
|
24
|
+
for e in self._http.get_paginated(
|
25
|
+
self._url, "integrationFlows", page_size=25, params=params
|
26
|
+
)
|
27
27
|
]
|
28
28
|
|
29
29
|
def get_flow(self, flow_id: str) -> Flow:
|
@@ -33,7 +33,7 @@ class _FlowClient(_BaseClient):
|
|
33
33
|
:param flow_id: The ID of the flow to get.
|
34
34
|
:return: The Flow object.
|
35
35
|
"""
|
36
|
-
return Flow.model_validate((self.
|
36
|
+
return Flow.model_validate((self._http.get(f"{self._url}/{flow_id}"))["integrationFlow"])
|
37
37
|
|
38
38
|
def run_flow(self, flow_id: str, only_steps: list[str] = None) -> str:
|
39
39
|
"""
|
@@ -46,9 +46,9 @@ class _FlowClient(_BaseClient):
|
|
46
46
|
"""
|
47
47
|
url = f"{self._url}/{flow_id}/run"
|
48
48
|
res = (
|
49
|
-
self.
|
49
|
+
self._http.post(url, json={"stepsToRun": only_steps})
|
50
50
|
if only_steps
|
51
|
-
else self.
|
51
|
+
else self._http.post_empty(url)
|
52
52
|
)
|
53
53
|
run_id = res["run"]["id"]
|
54
54
|
logger.info(f"Started flow run '{run_id}' for flow '{flow_id}'.")
|
@@ -62,7 +62,7 @@ class _FlowClient(_BaseClient):
|
|
62
62
|
:param flow: The flow to create. This can be a FlowInput object or a dictionary.
|
63
63
|
:return: The ID of the created flow.
|
64
64
|
"""
|
65
|
-
res = self.
|
65
|
+
res = self._http.post(self._url, json=construct_payload(FlowInput, flow))
|
66
66
|
flow_id = res["integrationFlow"]["integrationFlowId"]
|
67
67
|
logger.info(f"Created flow '{flow_id}'.")
|
68
68
|
return flow_id
|
@@ -74,7 +74,7 @@ class _FlowClient(_BaseClient):
|
|
74
74
|
:param flow_id: The ID of the flow to update.
|
75
75
|
:param flow: The flow to update. This can be a FlowInput object or a dictionary.
|
76
76
|
"""
|
77
|
-
self.
|
77
|
+
self._http.put(f"{self._url}/{flow_id}", json=construct_payload(FlowInput, flow))
|
78
78
|
logger.info(f"Updated flow '{flow_id}'.")
|
79
79
|
|
80
80
|
def delete_flow(self, flow_id: str) -> None:
|
@@ -83,5 +83,5 @@ class _FlowClient(_BaseClient):
|
|
83
83
|
the flow is running or if it has any running steps.
|
84
84
|
:param flow_id: The ID of the flow to delete.
|
85
85
|
"""
|
86
|
-
self.
|
86
|
+
self._http.delete(f"{self._url}/{flow_id}")
|
87
87
|
logger.info(f"Deleted flow '{flow_id}'.")
|
@@ -3,10 +3,8 @@ from concurrent.futures import ThreadPoolExecutor
|
|
3
3
|
from itertools import chain
|
4
4
|
from typing import Any, Literal, overload
|
5
5
|
|
6
|
-
import
|
7
|
-
|
8
|
-
from anaplan_sdk._base import (
|
9
|
-
_BaseClient,
|
6
|
+
from anaplan_sdk._services import (
|
7
|
+
_HttpService,
|
10
8
|
parse_calendar_response,
|
11
9
|
parse_insertion_response,
|
12
10
|
validate_dimension_id,
|
@@ -20,6 +18,7 @@ from anaplan_sdk.models import (
|
|
20
18
|
InsertionResult,
|
21
19
|
LineItem,
|
22
20
|
List,
|
21
|
+
ListDeletionResult,
|
23
22
|
ListItem,
|
24
23
|
ListMetadata,
|
25
24
|
Model,
|
@@ -29,39 +28,42 @@ from anaplan_sdk.models import (
|
|
29
28
|
View,
|
30
29
|
ViewInfo,
|
31
30
|
)
|
32
|
-
from anaplan_sdk.models._transactional import ListDeletionResult
|
33
31
|
|
34
32
|
logger = logging.getLogger("anaplan_sdk")
|
35
33
|
|
36
34
|
|
37
|
-
class _TransactionalClient
|
38
|
-
def __init__(self,
|
35
|
+
class _TransactionalClient:
|
36
|
+
def __init__(self, http: _HttpService, model_id: str) -> None:
|
37
|
+
self._http = http
|
39
38
|
self._url = f"https://api.anaplan.com/2/0/models/{model_id}"
|
40
39
|
self._model_id = model_id
|
41
|
-
super().__init__(retry_count, client)
|
42
40
|
|
43
41
|
def get_model_details(self) -> Model:
|
44
42
|
"""
|
45
43
|
Retrieves the Model details for the current Model.
|
46
44
|
:return: The Model details.
|
47
45
|
"""
|
48
|
-
return Model.model_validate(
|
46
|
+
return Model.model_validate(
|
47
|
+
self._http.get(self._url, params={"modelDetails": "true"})["model"]
|
48
|
+
)
|
49
49
|
|
50
50
|
def get_model_status(self) -> ModelStatus:
|
51
51
|
"""
|
52
52
|
Gets the current status of the Model.
|
53
53
|
:return: The current status of the Mode.
|
54
54
|
"""
|
55
|
-
return ModelStatus.model_validate(
|
55
|
+
return ModelStatus.model_validate(
|
56
|
+
self._http.get(f"{self._url}/status").get("requestStatus")
|
57
|
+
)
|
56
58
|
|
57
59
|
def wake_model(self) -> None:
|
58
60
|
"""Wake up the current model."""
|
59
|
-
self.
|
61
|
+
self._http.post_empty(f"{self._url}/open", headers={"Content-Type": "application/text"})
|
60
62
|
logger.info(f"Woke up model '{self._model_id}'.")
|
61
63
|
|
62
64
|
def close_model(self) -> None:
|
63
65
|
"""Close the current model."""
|
64
|
-
self.
|
66
|
+
self._http.post_empty(f"{self._url}/close", headers={"Content-Type": "application/text"})
|
65
67
|
logger.info(f"Closed model '{self._model_id}'.")
|
66
68
|
|
67
69
|
def get_modules(self) -> list[Module]:
|
@@ -70,7 +72,8 @@ class _TransactionalClient(_BaseClient):
|
|
70
72
|
:return: The List of Modules.
|
71
73
|
"""
|
72
74
|
return [
|
73
|
-
Module.model_validate(e)
|
75
|
+
Module.model_validate(e)
|
76
|
+
for e in self._http.get_paginated(f"{self._url}/modules", "modules")
|
74
77
|
]
|
75
78
|
|
76
79
|
def get_views(self) -> list[View]:
|
@@ -79,7 +82,9 @@ class _TransactionalClient(_BaseClient):
|
|
79
82
|
views.
|
80
83
|
:return: The List of Views.
|
81
84
|
"""
|
82
|
-
return [
|
85
|
+
return [
|
86
|
+
View.model_validate(e) for e in self._http.get_paginated(f"{self._url}/views", "views")
|
87
|
+
]
|
83
88
|
|
84
89
|
def get_view_info(self, view_id: int) -> ViewInfo:
|
85
90
|
"""
|
@@ -87,7 +92,7 @@ class _TransactionalClient(_BaseClient):
|
|
87
92
|
:param view_id: The ID of the View.
|
88
93
|
:return: The information about the View.
|
89
94
|
"""
|
90
|
-
return ViewInfo.model_validate(self.
|
95
|
+
return ViewInfo.model_validate(self._http.get(f"{self._url}/views/{view_id}"))
|
91
96
|
|
92
97
|
def get_line_items(self, only_module_id: int | None = None) -> list[LineItem]:
|
93
98
|
"""
|
@@ -100,14 +105,16 @@ class _TransactionalClient(_BaseClient):
|
|
100
105
|
if only_module_id
|
101
106
|
else f"{self._url}/lineItems?includeAll=true"
|
102
107
|
)
|
103
|
-
return [LineItem.model_validate(e) for e in self.
|
108
|
+
return [LineItem.model_validate(e) for e in self._http.get(url).get("items", [])]
|
104
109
|
|
105
110
|
def get_lists(self) -> list[List]:
|
106
111
|
"""
|
107
112
|
Lists all the Lists in the Model.
|
108
113
|
:return: All Lists on this model.
|
109
114
|
"""
|
110
|
-
return [
|
115
|
+
return [
|
116
|
+
List.model_validate(e) for e in self._http.get_paginated(f"{self._url}/lists", "lists")
|
117
|
+
]
|
111
118
|
|
112
119
|
def get_list_metadata(self, list_id: int) -> ListMetadata:
|
113
120
|
"""
|
@@ -116,7 +123,7 @@ class _TransactionalClient(_BaseClient):
|
|
116
123
|
:return: The Metadata for the List.
|
117
124
|
"""
|
118
125
|
return ListMetadata.model_validate(
|
119
|
-
self.
|
126
|
+
self._http.get(f"{self._url}/lists/{list_id}").get("metadata")
|
120
127
|
)
|
121
128
|
|
122
129
|
@overload
|
@@ -140,7 +147,7 @@ class _TransactionalClient(_BaseClient):
|
|
140
147
|
data, you will want to set this to avoid unnecessary (de-)serialization.
|
141
148
|
:return: All items in the List.
|
142
149
|
"""
|
143
|
-
res = self.
|
150
|
+
res = self._http.get(f"{self._url}/lists/{list_id}/items?includeAll=true")
|
144
151
|
if return_raw:
|
145
152
|
return res.get("listItems", [])
|
146
153
|
return [ListItem.model_validate(e) for e in res.get("listItems", [])]
|
@@ -169,7 +176,9 @@ class _TransactionalClient(_BaseClient):
|
|
169
176
|
return InsertionResult(added=0, ignored=0, failures=[], total=0)
|
170
177
|
if len(items) <= 100_000:
|
171
178
|
result = InsertionResult.model_validate(
|
172
|
-
self.
|
179
|
+
self._http.post(
|
180
|
+
f"{self._url}/lists/{list_id}/items?action=add", json={"items": items}
|
181
|
+
)
|
173
182
|
)
|
174
183
|
logger.info(f"Inserted {result.added} items into list '{list_id}'.")
|
175
184
|
return result
|
@@ -177,7 +186,7 @@ class _TransactionalClient(_BaseClient):
|
|
177
186
|
with ThreadPoolExecutor() as executor:
|
178
187
|
responses = list(
|
179
188
|
executor.map(
|
180
|
-
lambda chunk: self.
|
189
|
+
lambda chunk: self._http.post(
|
181
190
|
f"{self._url}/lists/{list_id}/items?action=add", json={"items": chunk}
|
182
191
|
),
|
183
192
|
[items[i : i + 100_000] for i in range(0, len(items), 100_000)],
|
@@ -209,7 +218,7 @@ class _TransactionalClient(_BaseClient):
|
|
209
218
|
if not items:
|
210
219
|
return ListDeletionResult(deleted=0, failures=[])
|
211
220
|
if len(items) <= 100_000:
|
212
|
-
res = self.
|
221
|
+
res = self._http.post(
|
213
222
|
f"{self._url}/lists/{list_id}/items?action=delete", json={"items": items}
|
214
223
|
)
|
215
224
|
info = ListDeletionResult.model_validate(res)
|
@@ -219,7 +228,7 @@ class _TransactionalClient(_BaseClient):
|
|
219
228
|
with ThreadPoolExecutor() as executor:
|
220
229
|
responses = list(
|
221
230
|
executor.map(
|
222
|
-
lambda chunk: self.
|
231
|
+
lambda chunk: self._http.post(
|
223
232
|
f"{self._url}/lists/{list_id}/items?action=delete", json={"items": chunk}
|
224
233
|
),
|
225
234
|
[items[i : i + 100_000] for i in range(0, len(items), 100_000)],
|
@@ -237,7 +246,7 @@ class _TransactionalClient(_BaseClient):
|
|
237
246
|
Resets the index of a List. The List must be empty to do so.
|
238
247
|
:param list_id: The ID of the List.
|
239
248
|
"""
|
240
|
-
self.
|
249
|
+
self._http.post_empty(f"{self._url}/lists/{list_id}/resetIndex")
|
241
250
|
logger.info(f"Reset index for list '{list_id}'.")
|
242
251
|
|
243
252
|
def update_module_data(
|
@@ -257,7 +266,7 @@ class _TransactionalClient(_BaseClient):
|
|
257
266
|
:param data: The data to write to the Module.
|
258
267
|
:return: The number of cells changed or the response with the according error details.
|
259
268
|
"""
|
260
|
-
res = self.
|
269
|
+
res = self._http.post(f"{self._url}/modules/{module_id}/data", json=data)
|
261
270
|
if "failures" not in res:
|
262
271
|
logger.info(f"Updated {res['numberOfCellsChanged']} cells in module '{module_id}'.")
|
263
272
|
return res if "failures" in res else res["numberOfCellsChanged"]
|
@@ -267,7 +276,7 @@ class _TransactionalClient(_BaseClient):
|
|
267
276
|
Gets the current period of the model.
|
268
277
|
:return: The current period of the model.
|
269
278
|
"""
|
270
|
-
res = self.
|
279
|
+
res = self._http.get(f"{self._url}/currentPeriod")
|
271
280
|
return CurrentPeriod.model_validate(res["currentPeriod"])
|
272
281
|
|
273
282
|
def set_current_period(self, date: str) -> CurrentPeriod:
|
@@ -276,7 +285,7 @@ class _TransactionalClient(_BaseClient):
|
|
276
285
|
:param date: The date to set the current period to, in the format 'YYYY-MM-DD'.
|
277
286
|
:return: The updated current period of the model.
|
278
287
|
"""
|
279
|
-
res = self.
|
288
|
+
res = self._http.put(f"{self._url}/currentPeriod", {"date": date})
|
280
289
|
logger.info(f"Set current period to '{date}'.")
|
281
290
|
return CurrentPeriod.model_validate(res["currentPeriod"])
|
282
291
|
|
@@ -286,7 +295,7 @@ class _TransactionalClient(_BaseClient):
|
|
286
295
|
:param year: The fiscal year to set, in the format specified in the model, e.g. FY24.
|
287
296
|
:return: The updated fiscal year of the model.
|
288
297
|
"""
|
289
|
-
res = self.
|
298
|
+
res = self._http.put(f"{self._url}/modelCalendar/fiscalYear", {"year": year})
|
290
299
|
logger.info(f"Set current fiscal year to '{year}'.")
|
291
300
|
return FiscalYear.model_validate(res["modelCalendar"]["fiscalYear"])
|
292
301
|
|
@@ -295,7 +304,7 @@ class _TransactionalClient(_BaseClient):
|
|
295
304
|
Get the calendar settings of the model.
|
296
305
|
:return: The calendar settings of the model.
|
297
306
|
"""
|
298
|
-
return parse_calendar_response(self.
|
307
|
+
return parse_calendar_response(self._http.get(f"{self._url}/modelCalendar"))
|
299
308
|
|
300
309
|
def get_dimension_items(self, dimension_id: int) -> list[DimensionWithCode]:
|
301
310
|
"""
|
@@ -311,7 +320,7 @@ class _TransactionalClient(_BaseClient):
|
|
311
320
|
:param dimension_id: The ID of the dimension to list items for.
|
312
321
|
:return: A list of Dimension items.
|
313
322
|
"""
|
314
|
-
res = self.
|
323
|
+
res = self._http.get(f"{self._url}/dimensions/{validate_dimension_id(dimension_id)}/items")
|
315
324
|
return [DimensionWithCode.model_validate(e) for e in res.get("items", [])]
|
316
325
|
|
317
326
|
def lookup_dimension_items(
|
@@ -343,7 +352,7 @@ class _TransactionalClient(_BaseClient):
|
|
343
352
|
"Invalid dimension_id. Must be a List (101xxxxxxxxx), Time (20000000003), "
|
344
353
|
"Version (20000000020), or Users (101999999999)."
|
345
354
|
)
|
346
|
-
res = self.
|
355
|
+
res = self._http.post(
|
347
356
|
f"{self._url}/dimensions/{dimension_id}/items", json={"codes": codes, "names": names}
|
348
357
|
)
|
349
358
|
return [DimensionWithCode.model_validate(e) for e in res.get("items", [])]
|
@@ -360,7 +369,7 @@ class _TransactionalClient(_BaseClient):
|
|
360
369
|
:param dimension_id: The ID of the Dimension to get items for.
|
361
370
|
:return: A list of Dimensions used in the View.
|
362
371
|
"""
|
363
|
-
res = self.
|
372
|
+
res = self._http.get(f"{self._url}/views/{view_id}/dimensions/{dimension_id}/items")
|
364
373
|
return [Dimension.model_validate(e) for e in res.get("items", [])]
|
365
374
|
|
366
375
|
def get_line_item_dimensions(self, line_item_id: int) -> list[Dimension]:
|
@@ -370,5 +379,5 @@ class _TransactionalClient(_BaseClient):
|
|
370
379
|
:param line_item_id: The ID of the Line Item.
|
371
380
|
:return: A list of Dimensions used in the Line Item.
|
372
381
|
"""
|
373
|
-
res = self.
|
382
|
+
res = self._http.get(f"{self._url}/lineItems/{line_item_id}/dimensions")
|
374
383
|
return [Dimension.model_validate(e) for e in res.get("dimensions", [])]
|