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