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.
@@ -1,10 +1,8 @@
1
1
  import logging
2
2
  from typing import Any, Literal
3
3
 
4
- import httpx
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(_AsyncBaseClient):
35
- def __init__(self, client: httpx.AsyncClient, retry_count: int) -> None:
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(client, retry_count)
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._get_paginated(f"{self._url}/connections", "connections")
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._post(
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._put(f"{self._url}/connections/{con_id}", json=connection_body_payload(con_info))
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._patch(f"{self._url}/connections/{con_id}", json=body)
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._delete(f"{self._url}/connections/{con_id}")
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._get_paginated(f"{self._url}", "integrations", params=params)
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._get(f"{self._url}/{integration_id}"))["integration"]
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._post(f"{self._url}", json=json)
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._put(f"{self._url}/{integration_id}", json=json)
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._post_empty(f"{self._url}/{integration_id}/run"))["run"]["id"]
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._delete(f"{self._url}/{integration_id}")
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._get(f"{self._url}/runs/{integration_id}"))["history_of_runs"].get(
197
- "runs", []
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._get(f"{self._url}/run/{run_id}"))["run"])
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._get(f"{self._url}/runerror/{run_id}")
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._post(
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._put(
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._post_empty(f"{self._url}/{integration_id}/schedule/status/{status}")
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._delete(f"{self._url}/{integration_id}/schedule")
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._get(f"{self._url}/notification/{notification_id}"))["notifications"]
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._post(
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._put(
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._delete(f"{self._url}/notification/{notification_id}")
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._get_binary(f"{self._url}/run/{run_id}/dump")
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._get_binary(f"{self._url}/run/{run_id}/process/import/{action_id}/dumps")
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 httpx
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(_AsyncBaseClient):
13
- def __init__(self, client: httpx.AsyncClient, retry_count: int) -> None:
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._get_paginated(
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((await self._get(f"{self._url}/{flow_id}"))["integrationFlow"])
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._post(url, json={"stepsToRun": only_steps})
51
+ self._http.post(url, json={"stepsToRun": only_steps})
52
52
  if only_steps
53
- else self._post_empty(url)
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._post(self._url, json=construct_payload(FlowInput, flow))
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._put(f"{self._url}/{flow_id}", json=construct_payload(FlowInput, flow))
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._delete(f"{self._url}/{flow_id}")
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 httpx
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(_AsyncBaseClient):
38
- def __init__(self, client: httpx.AsyncClient, model_id: str, retry_count: int) -> None:
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._get(self._url, params={"modelDetails": "true"})
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._get(f"{self._url}/status")
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._post_empty(f"{self._url}/open", headers={"Content-Type": "application/text"})
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._post_empty(f"{self._url}/close", headers={"Content-Type": "application/text"})
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._get_paginated(f"{self._url}/modules", "modules")
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._get_paginated(f"{self._url}/views", "views", params=params)
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._get(f"{self._url}/views/{view_id}")))
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._get(
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) for e in await self._get_paginated(f"{self._url}/lists", "lists")
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._get(f"{self._url}/lists/{list_id}")).get("metadata")
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._get(f"{self._url}/lists/{list_id}/items?includeAll=true")
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._post(
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._post(f"{self._url}/lists/{list_id}/items?action=add", json={"items": chunk})
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._post(
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._post(
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._post_empty(f"{self._url}/lists/{list_id}/resetIndex")
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._post(f"{self._url}/modules/{module_id}/data", json=data)
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._get(f"{self._url}/currentPeriod")
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._put(f"{self._url}/currentPeriod", {"date": date})
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._put(f"{self._url}/modelCalendar/fiscalYear", {"year": year})
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._get(f"{self._url}/modelCalendar"))
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._get(f"{self._url}/dimensions/{validate_dimension_id(dimension_id)}/items")
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._post(
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._get(f"{self._url}/views/{view_id}/dimensions/{dimension_id}/items")
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._get(f"{self._url}/lineItems/{line_item_id}/dimensions")
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", [])]