anaplan-sdk 0.5.0a3__tar.gz → 0.5.0a4__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.
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/PKG-INFO +1 -1
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_async_clients/_alm.py +12 -4
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_async_clients/_audit.py +17 -9
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_async_clients/_bulk.py +17 -27
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_async_clients/_cloud_works.py +4 -3
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_async_clients/_transactional.py +5 -7
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_clients/_alm.py +12 -4
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_clients/_audit.py +19 -11
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_clients/_bulk.py +71 -45
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_clients/_cloud_works.py +4 -3
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_clients/_transactional.py +25 -11
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_services.py +16 -2
- anaplan_sdk-0.5.0a4/docs/guides/sorting.md +41 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/mkdocs.yml +1 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/pyproject.toml +2 -4
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/async/test_async_cloud_works_client.py +1 -1
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/sync/test_cloud_works_client.py +1 -1
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/.github/dependabot.yml +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/.github/workflows/docs.yml +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/.github/workflows/lint.yml +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/.github/workflows/tests.yml +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/.gitignore +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/.pre-commit-config.yaml +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/LICENSE +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/README.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/__init__.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_async_clients/__init__.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_async_clients/_cw_flow.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_auth.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_clients/__init__.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_clients/_cw_flow.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/_oauth.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/exceptions.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/models/__init__.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/models/_alm.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/models/_base.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/models/_bulk.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/models/_transactional.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/models/cloud_works.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/anaplan_sdk/models/flows.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/async/async_alm_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/async/async_audit_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/async/async_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/async/async_cw_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/async/async_flows_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/async/async_oauth_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/async/async_transactional_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/exceptions.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/models/alm.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/models/bulk.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/models/cloud_works.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/models/flows.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/models/transactional.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/sync/sync_alm_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/sync/sync_audit_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/sync/sync_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/sync/sync_cw_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/sync/sync_flows_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/sync/sync_oauth_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/api/sync/sync_transactional_client.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/assets/overview.html +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/concepts.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/css/styles.css +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/guides/alm.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/guides/audit.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/guides/authentication.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/guides/bulk.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/guides/bulk_vs_transactional.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/guides/cloud_works.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/guides/index.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/guides/logging.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/guides/multiple_models.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/guides/transactional.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/img/anaplan-sdk.webp +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/index.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/installation.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/js/assets/hljs.js +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/js/assets/hljs.min.js +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/js/assets/python.js +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/js/assets/python.min.js +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/js/highlight.js +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/js/highlight.min.js +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/docs/quickstart.md +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/async/conftest.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/async/test_async_alm_client.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/async/test_async_audit_client.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/async/test_async_client.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/async/test_async_flows_client.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/async/test_async_transactional_client.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/conftest.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/sync/conftest.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/sync/test_alm_client.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/sync/test_audit_client.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/sync/test_client.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/sync/test_flows_client.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/tests/sync/test_transactional_client.py +0 -0
- {anaplan_sdk-0.5.0a3 → anaplan_sdk-0.5.0a4}/uv.lock +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: anaplan-sdk
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.0a4
|
4
4
|
Summary: Streamlined Python Interface for the Anaplan API.
|
5
5
|
Project-URL: Homepage, https://vinzenzklass.github.io/anaplan-sdk/
|
6
6
|
Project-URL: Repository, https://github.com/VinzenzKlass/anaplan-sdk
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import logging
|
2
2
|
from typing import Literal, overload
|
3
3
|
|
4
|
-
from anaplan_sdk._services import _AsyncHttpService
|
4
|
+
from anaplan_sdk._services import _AsyncHttpService, sort_params
|
5
5
|
from anaplan_sdk.exceptions import AnaplanActionError
|
6
6
|
from anaplan_sdk.models import (
|
7
7
|
ModelRevision,
|
@@ -29,13 +29,21 @@ class _AsyncAlmClient:
|
|
29
29
|
logger.info(f"Changed model status to '{status}' for model {self._model_id}.")
|
30
30
|
await self._http.put(f"{self._url}/onlineStatus", json={"status": status})
|
31
31
|
|
32
|
-
async def get_revisions(
|
32
|
+
async def get_revisions(
|
33
|
+
self,
|
34
|
+
sort_by: Literal["id", "name", "applied_on", "created_on"] | None = None,
|
35
|
+
descending: bool = False,
|
36
|
+
) -> list[Revision]:
|
33
37
|
"""
|
34
38
|
Use this call to return a list of revisions for a specific model.
|
39
|
+
:param sort_by: The field to sort the results by.
|
40
|
+
:param descending: If True, the results will be sorted in descending order.
|
35
41
|
:return: A list of revisions for a specific model.
|
36
42
|
"""
|
37
|
-
res = await self._http.
|
38
|
-
|
43
|
+
res = await self._http.get_paginated(
|
44
|
+
f"{self._url}/alm/revisions", "revisions", params=sort_params(sort_by, descending)
|
45
|
+
)
|
46
|
+
return [Revision.model_validate(e) for e in res]
|
39
47
|
|
40
48
|
async def get_latest_revision(self) -> Revision | None:
|
41
49
|
"""
|
@@ -1,9 +1,10 @@
|
|
1
1
|
from typing import Any, Literal
|
2
2
|
|
3
|
-
from anaplan_sdk._services import _AsyncHttpService
|
3
|
+
from anaplan_sdk._services import _AsyncHttpService, sort_params
|
4
4
|
from anaplan_sdk.models import User
|
5
5
|
|
6
6
|
Event = Literal["all", "byok", "user_activity"]
|
7
|
+
UserSortBy = Literal["first_name", "last_name", "email", "active", "last_login_date"] | None
|
7
8
|
|
8
9
|
|
9
10
|
class _AsyncAuditClient:
|
@@ -12,22 +13,29 @@ class _AsyncAuditClient:
|
|
12
13
|
self._limit = 10_000
|
13
14
|
self._url = "https://audit.anaplan.com/audit/api/1/events"
|
14
15
|
|
15
|
-
async def get_users(
|
16
|
+
async def get_users(
|
17
|
+
self,
|
18
|
+
search_pattern: str | None = None,
|
19
|
+
sort_by: UserSortBy = None,
|
20
|
+
descending: bool = False,
|
21
|
+
) -> list[User]:
|
16
22
|
"""
|
17
23
|
Lists all the Users in the authenticated users default tenant.
|
18
24
|
:param search_pattern: Optionally filter for specific users. When provided,
|
19
25
|
case-insensitive matches users with emails or names containing this string.
|
20
26
|
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
21
27
|
When None (default), returns all users.
|
28
|
+
:param sort_by: The field to sort the results by.
|
29
|
+
:param descending: If True, the results will be sorted in descending order.
|
22
30
|
:return: The List of Users.
|
23
31
|
"""
|
24
|
-
params =
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
]
|
32
|
+
params = sort_params(sort_by, descending)
|
33
|
+
if search_pattern:
|
34
|
+
params["s"] = search_pattern
|
35
|
+
res = await self._http.get_paginated(
|
36
|
+
"https://api.anaplan.com/2/0/users", "users", params=params
|
37
|
+
)
|
38
|
+
return [User.model_validate(e) for e in res]
|
31
39
|
|
32
40
|
async def get_user(self, user_id: str = "me") -> User:
|
33
41
|
"""
|
@@ -27,6 +27,8 @@ from ._audit import _AsyncAuditClient
|
|
27
27
|
from ._cloud_works import _AsyncCloudWorksClient
|
28
28
|
from ._transactional import _AsyncTransactionalClient
|
29
29
|
|
30
|
+
SortBy = Literal["id", "name"] | None
|
31
|
+
|
30
32
|
logger = logging.getLogger("anaplan_sdk")
|
31
33
|
|
32
34
|
|
@@ -228,7 +230,7 @@ class AsyncClient:
|
|
228
230
|
async def get_workspaces(
|
229
231
|
self,
|
230
232
|
search_pattern: str | None = None,
|
231
|
-
sort_by: Literal["size_allowance", "name"] =
|
233
|
+
sort_by: Literal["size_allowance", "name"] | None = None,
|
232
234
|
descending: bool = False,
|
233
235
|
) -> list[Workspace]:
|
234
236
|
"""
|
@@ -244,17 +246,15 @@ class AsyncClient:
|
|
244
246
|
params = {"tenantDetails": "true"} | sort_params(sort_by, descending)
|
245
247
|
if search_pattern:
|
246
248
|
params["s"] = search_pattern
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
)
|
252
|
-
]
|
249
|
+
res = await self._http.get_paginated(
|
250
|
+
"https://api.anaplan.com/2/0/workspaces", "workspaces", params=params
|
251
|
+
)
|
252
|
+
return [Workspace.model_validate(e) for e in res]
|
253
253
|
|
254
254
|
async def get_models(
|
255
255
|
self,
|
256
256
|
search_pattern: str | None = None,
|
257
|
-
sort_by: Literal["active_state", "name"] =
|
257
|
+
sort_by: Literal["active_state", "name"] | None = None,
|
258
258
|
descending: bool = False,
|
259
259
|
) -> list[Model]:
|
260
260
|
"""
|
@@ -270,12 +270,10 @@ class AsyncClient:
|
|
270
270
|
params = {"modelDetails": "true"} | sort_params(sort_by, descending)
|
271
271
|
if search_pattern:
|
272
272
|
params["s"] = search_pattern
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
)
|
278
|
-
]
|
273
|
+
res = await self._http.get_paginated(
|
274
|
+
"https://api.anaplan.com/2/0/models", "models", params=params
|
275
|
+
)
|
276
|
+
return [Model.model_validate(e) for e in res]
|
279
277
|
|
280
278
|
async def delete_models(self, model_ids: list[str]) -> ModelDeletionResult:
|
281
279
|
"""
|
@@ -291,9 +289,7 @@ class AsyncClient:
|
|
291
289
|
)
|
292
290
|
return ModelDeletionResult.model_validate(res)
|
293
291
|
|
294
|
-
async def get_files(
|
295
|
-
self, sort_by: Literal["id", "name"] = "id", descending: bool = False
|
296
|
-
) -> list[File]:
|
292
|
+
async def get_files(self, sort_by: SortBy = None, descending: bool = False) -> list[File]:
|
297
293
|
"""
|
298
294
|
Lists all the Files in the Model.
|
299
295
|
:param sort_by: The field to sort the results by.
|
@@ -305,9 +301,7 @@ class AsyncClient:
|
|
305
301
|
)
|
306
302
|
return [File.model_validate(e) for e in res]
|
307
303
|
|
308
|
-
async def get_actions(
|
309
|
-
self, sort_by: Literal["id", "name"] = "id", descending: bool = False
|
310
|
-
) -> list[Action]:
|
304
|
+
async def get_actions(self, sort_by: SortBy = None, descending: bool = False) -> list[Action]:
|
311
305
|
"""
|
312
306
|
Lists all the Actions in the Model. This will only return the Actions listed under
|
313
307
|
`Other Actions` in Anaplan. For Imports, exports, and processes, see their respective
|
@@ -322,7 +316,7 @@ class AsyncClient:
|
|
322
316
|
return [Action.model_validate(e) for e in res]
|
323
317
|
|
324
318
|
async def get_processes(
|
325
|
-
self, sort_by:
|
319
|
+
self, sort_by: SortBy = None, descending: bool = False
|
326
320
|
) -> list[Process]:
|
327
321
|
"""
|
328
322
|
Lists all the Processes in the Model.
|
@@ -335,9 +329,7 @@ class AsyncClient:
|
|
335
329
|
)
|
336
330
|
return [Process.model_validate(e) for e in res]
|
337
331
|
|
338
|
-
async def get_imports(
|
339
|
-
self, sort_by: Literal["id", "name"] = "id", descending: bool = False
|
340
|
-
) -> list[Import]:
|
332
|
+
async def get_imports(self, sort_by: SortBy = None, descending: bool = False) -> list[Import]:
|
341
333
|
"""
|
342
334
|
Lists all the Imports in the Model.
|
343
335
|
:param sort_by: The field to sort the results by.
|
@@ -349,9 +341,7 @@ class AsyncClient:
|
|
349
341
|
)
|
350
342
|
return [Import.model_validate(e) for e in res]
|
351
343
|
|
352
|
-
async def get_exports(
|
353
|
-
self, sort_by: Literal["id", "name"] = "id", descending: bool = False
|
354
|
-
) -> list[Export]:
|
344
|
+
async def get_exports(self, sort_by: SortBy = None, descending: bool = False) -> list[Export]:
|
355
345
|
"""
|
356
346
|
Lists all the Exports in the Model.
|
357
347
|
:param sort_by: The field to sort the results by.
|
@@ -99,14 +99,15 @@ class _AsyncCloudWorksClient:
|
|
99
99
|
logger.info(f"Deleted connection '{con_id}'.")
|
100
100
|
|
101
101
|
async def get_integrations(
|
102
|
-
self,
|
102
|
+
self, sort_by: Literal["name"] | None = None, descending: bool = False
|
103
103
|
) -> list[Integration]:
|
104
104
|
"""
|
105
105
|
List all integrations in CloudWorks.
|
106
|
-
:param
|
106
|
+
:param sort_by: The field to sort the results by.
|
107
|
+
:param descending: If True, the results will be sorted in descending order.
|
107
108
|
:return: A list of integrations.
|
108
109
|
"""
|
109
|
-
params = {"sortBy": "
|
110
|
+
params = {"sortBy": f"{'-' if descending else ''}{sort_by}"} if sort_by else None
|
110
111
|
return [
|
111
112
|
Integration.model_validate(e)
|
112
113
|
for e in await self._http.get_paginated(f"{self._url}", "integrations", params=params)
|
@@ -30,6 +30,8 @@ from anaplan_sdk.models import (
|
|
30
30
|
ViewInfo,
|
31
31
|
)
|
32
32
|
|
33
|
+
SortBy = Literal["id", "name"] | None
|
34
|
+
|
33
35
|
logger = logging.getLogger("anaplan_sdk")
|
34
36
|
|
35
37
|
|
@@ -69,9 +71,7 @@ class _AsyncTransactionalClient:
|
|
69
71
|
)
|
70
72
|
logger.info(f"Closed model '{self._model_id}'.")
|
71
73
|
|
72
|
-
async def get_modules(
|
73
|
-
self, sort_by: Literal["id", "name"] = "id", descending: bool = False
|
74
|
-
) -> list[Module]:
|
74
|
+
async def get_modules(self, sort_by: SortBy = None, descending: bool = False) -> list[Module]:
|
75
75
|
"""
|
76
76
|
Lists all the Modules in the Model.
|
77
77
|
:param sort_by: The field to sort the results by.
|
@@ -84,7 +84,7 @@ class _AsyncTransactionalClient:
|
|
84
84
|
return [Module.model_validate(e) for e in res]
|
85
85
|
|
86
86
|
async def get_views(
|
87
|
-
self, sort_by: Literal["id", "module_id", "name"] =
|
87
|
+
self, sort_by: Literal["id", "module_id", "name"] | None = None, descending: bool = False
|
88
88
|
) -> list[View]:
|
89
89
|
"""
|
90
90
|
Lists all the Views in the Model. This will include all Modules and potentially other saved
|
@@ -120,9 +120,7 @@ class _AsyncTransactionalClient:
|
|
120
120
|
)
|
121
121
|
return [LineItem.model_validate(e) for e in res.get("items", [])]
|
122
122
|
|
123
|
-
async def get_lists(
|
124
|
-
self, sort_by: Literal["id", "name"] = "id", descending: bool = False
|
125
|
-
) -> list[List]:
|
123
|
+
async def get_lists(self, sort_by: SortBy = None, descending: bool = False) -> list[List]:
|
126
124
|
"""
|
127
125
|
Lists all the Lists in the Model.
|
128
126
|
:param sort_by: The field to sort the results by.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import logging
|
2
2
|
from typing import Literal, overload
|
3
3
|
|
4
|
-
from anaplan_sdk._services import _HttpService
|
4
|
+
from anaplan_sdk._services import _HttpService, sort_params
|
5
5
|
from anaplan_sdk.exceptions import AnaplanActionError
|
6
6
|
from anaplan_sdk.models import (
|
7
7
|
ModelRevision,
|
@@ -29,13 +29,21 @@ class _AlmClient:
|
|
29
29
|
logger.info(f"Changed model status to '{status}' for model {self._model_id}.")
|
30
30
|
self._http.put(f"{self._url}/onlineStatus", json={"status": status})
|
31
31
|
|
32
|
-
def get_revisions(
|
32
|
+
def get_revisions(
|
33
|
+
self,
|
34
|
+
sort_by: Literal["id", "name", "applied_on", "created_on"] | None = None,
|
35
|
+
descending: bool = False,
|
36
|
+
) -> list[Revision]:
|
33
37
|
"""
|
34
38
|
Use this call to return a list of revisions for a specific model.
|
39
|
+
:param sort_by: The field to sort the results by.
|
40
|
+
:param descending: If True, the results will be sorted in descending order.
|
35
41
|
:return: A list of revisions for a specific model.
|
36
42
|
"""
|
37
|
-
res = self._http.
|
38
|
-
|
43
|
+
res = self._http.get_paginated(
|
44
|
+
f"{self._url}/alm/revisions", "revisions", params=sort_params(sort_by, descending)
|
45
|
+
)
|
46
|
+
return [Revision.model_validate(e) for e in res]
|
39
47
|
|
40
48
|
def get_latest_revision(self) -> Revision | None:
|
41
49
|
"""
|
@@ -1,9 +1,10 @@
|
|
1
1
|
from typing import Any, Literal
|
2
2
|
|
3
|
-
from anaplan_sdk._services import _HttpService
|
3
|
+
from anaplan_sdk._services import _HttpService, sort_params
|
4
4
|
from anaplan_sdk.models import User
|
5
5
|
|
6
6
|
Event = Literal["all", "byok", "user_activity"]
|
7
|
+
UserSortBy = Literal["first_name", "last_name", "email", "active", "last_login_date"] | None
|
7
8
|
|
8
9
|
|
9
10
|
class _AuditClient:
|
@@ -12,20 +13,27 @@ class _AuditClient:
|
|
12
13
|
self._limit = 10_000
|
13
14
|
self._url = "https://audit.anaplan.com/audit/api/1/events"
|
14
15
|
|
15
|
-
def get_users(
|
16
|
+
def get_users(
|
17
|
+
self,
|
18
|
+
search_pattern: str | None = None,
|
19
|
+
sort_by: UserSortBy = None,
|
20
|
+
descending: bool = False,
|
21
|
+
) -> list[User]:
|
16
22
|
"""
|
17
23
|
Lists all the Users in the authenticated users default tenant.
|
18
|
-
:param search_pattern:
|
19
|
-
users with emails containing this string.
|
24
|
+
:param search_pattern: Optionally filter for specific users. When provided,
|
25
|
+
case-insensitive matches users with emails or names containing this string.
|
26
|
+
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
27
|
+
When None (default), returns all users.
|
28
|
+
:param sort_by: The field to sort the results by.
|
29
|
+
:param descending: If True, the results will be sorted in descending order.
|
20
30
|
:return: The List of Users.
|
21
31
|
"""
|
22
|
-
params =
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
)
|
28
|
-
]
|
32
|
+
params = sort_params(sort_by, descending)
|
33
|
+
if search_pattern:
|
34
|
+
params["s"] = search_pattern
|
35
|
+
res = self._http.get_paginated("https://api.anaplan.com/2/0/users", "users", params=params)
|
36
|
+
return [User.model_validate(e) for e in res]
|
29
37
|
|
30
38
|
def get_user(self, user_id: str = "me") -> User:
|
31
39
|
"""
|
@@ -2,13 +2,13 @@ import logging
|
|
2
2
|
import multiprocessing
|
3
3
|
from concurrent.futures import ThreadPoolExecutor
|
4
4
|
from copy import copy
|
5
|
-
from typing import Iterator
|
5
|
+
from typing import Iterator, Literal
|
6
6
|
|
7
7
|
import httpx
|
8
8
|
from typing_extensions import Self
|
9
9
|
|
10
10
|
from anaplan_sdk._auth import _create_auth
|
11
|
-
from anaplan_sdk._services import _HttpService, action_url
|
11
|
+
from anaplan_sdk._services import _HttpService, action_url, sort_params
|
12
12
|
from anaplan_sdk.exceptions import AnaplanActionError, InvalidIdentifierException
|
13
13
|
from anaplan_sdk.models import (
|
14
14
|
Action,
|
@@ -28,6 +28,8 @@ from ._audit import _AuditClient
|
|
28
28
|
from ._cloud_works import _CloudWorksClient
|
29
29
|
from ._transactional import _TransactionalClient
|
30
30
|
|
31
|
+
SortBy = Literal["id", "name"] | None
|
32
|
+
|
31
33
|
logger = logging.getLogger("anaplan_sdk")
|
32
34
|
|
33
35
|
|
@@ -230,42 +232,53 @@ class Client:
|
|
230
232
|
)
|
231
233
|
return self._alm_client
|
232
234
|
|
233
|
-
def get_workspaces(
|
235
|
+
def get_workspaces(
|
236
|
+
self,
|
237
|
+
search_pattern: str | None = None,
|
238
|
+
sort_by: Literal["size_allowance", "name"] | None = None,
|
239
|
+
descending: bool = False,
|
240
|
+
) -> list[Workspace]:
|
234
241
|
"""
|
235
242
|
Lists all the Workspaces the authenticated user has access to.
|
236
|
-
:param search_pattern:
|
237
|
-
matches workspaces with names containing this string.
|
238
|
-
|
243
|
+
:param search_pattern: Optionally filter for specific workspaces. When provided,
|
244
|
+
case-insensitive matches workspaces with names containing this string.
|
245
|
+
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
246
|
+
When None (default), returns all users.
|
247
|
+
:param sort_by: The field to sort the results by.
|
248
|
+
:param descending: If True, the results will be sorted in descending order.
|
239
249
|
:return: The List of Workspaces.
|
240
250
|
"""
|
241
|
-
params = {"tenantDetails": "true"}
|
251
|
+
params = {"tenantDetails": "true"} | sort_params(sort_by, descending)
|
242
252
|
if search_pattern:
|
243
253
|
params["s"] = search_pattern
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
)
|
249
|
-
]
|
254
|
+
res = self._http.get_paginated(
|
255
|
+
"https://api.anaplan.com/2/0/workspaces", "workspaces", params=params
|
256
|
+
)
|
257
|
+
return [Workspace.model_validate(e) for e in res]
|
250
258
|
|
251
|
-
def get_models(
|
259
|
+
def get_models(
|
260
|
+
self,
|
261
|
+
search_pattern: str | None = None,
|
262
|
+
sort_by: Literal["active_state", "name"] | None = None,
|
263
|
+
descending: bool = False,
|
264
|
+
) -> list[Model]:
|
252
265
|
"""
|
253
266
|
Lists all the Models the authenticated user has access to.
|
254
267
|
:param search_pattern: Optionally filter for specific models. When provided,
|
255
268
|
case-insensitive matches model names containing this string.
|
256
269
|
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
257
270
|
When None (default), returns all models.
|
271
|
+
:param sort_by: The field to sort the results by.
|
272
|
+
:param descending: If True, the results will be sorted in descending order.
|
258
273
|
:return: The List of Models.
|
259
274
|
"""
|
260
|
-
params = {"modelDetails": "true"}
|
275
|
+
params = {"modelDetails": "true"} | sort_params(sort_by, descending)
|
261
276
|
if search_pattern:
|
262
277
|
params["s"] = search_pattern
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
)
|
268
|
-
]
|
278
|
+
res = self._http.get_paginated(
|
279
|
+
"https://api.anaplan.com/2/0/models", "models", params=params
|
280
|
+
)
|
281
|
+
return [Model.model_validate(e) for e in res]
|
269
282
|
|
270
283
|
def delete_models(self, model_ids: list[str]) -> ModelDeletionResult:
|
271
284
|
"""
|
@@ -281,56 +294,69 @@ class Client:
|
|
281
294
|
)
|
282
295
|
return ModelDeletionResult.model_validate(res)
|
283
296
|
|
284
|
-
def get_files(
|
297
|
+
def get_files(
|
298
|
+
self, sort_by: Literal["id", "name"] = "id", descending: bool = False
|
299
|
+
) -> list[File]:
|
285
300
|
"""
|
286
301
|
Lists all the Files in the Model.
|
302
|
+
:param sort_by: The field to sort the results by.
|
303
|
+
:param descending: If True, the results will be sorted in descending order.
|
287
304
|
:return: The List of Files.
|
288
305
|
"""
|
289
|
-
|
290
|
-
|
291
|
-
|
306
|
+
res = self._http.get_paginated(
|
307
|
+
f"{self._url}/files", "files", params=sort_params(sort_by, descending)
|
308
|
+
)
|
309
|
+
return [File.model_validate(e) for e in res]
|
292
310
|
|
293
|
-
def get_actions(self) -> list[Action]:
|
311
|
+
def get_actions(self, sort_by: SortBy = None, descending: bool = False) -> list[Action]:
|
294
312
|
"""
|
295
313
|
Lists all the Actions in the Model. This will only return the Actions listed under
|
296
314
|
`Other Actions` in Anaplan. For Imports, exports, and processes, see their respective
|
297
315
|
methods instead.
|
316
|
+
:param sort_by: The field to sort the results by.
|
317
|
+
:param descending: If True, the results will be sorted in descending order.
|
298
318
|
:return: The List of Actions.
|
299
319
|
"""
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
]
|
320
|
+
res = self._http.get_paginated(
|
321
|
+
f"{self._url}/actions", "actions", params=sort_params(sort_by, descending)
|
322
|
+
)
|
323
|
+
return [Action.model_validate(e) for e in res]
|
304
324
|
|
305
|
-
def get_processes(self) -> list[Process]:
|
325
|
+
def get_processes(self, sort_by: SortBy = None, descending: bool = False) -> list[Process]:
|
306
326
|
"""
|
307
327
|
Lists all the Processes in the Model.
|
328
|
+
:param sort_by: The field to sort the results by.
|
329
|
+
:param descending: If True, the results will be sorted in descending order.
|
308
330
|
:return: The List of Processes.
|
309
331
|
"""
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
]
|
332
|
+
res = self._http.get_paginated(
|
333
|
+
f"{self._url}/processes", "processes", params=sort_params(sort_by, descending)
|
334
|
+
)
|
335
|
+
return [Process.model_validate(e) for e in res]
|
314
336
|
|
315
|
-
def get_imports(self) -> list[Import]:
|
337
|
+
def get_imports(self, sort_by: SortBy = None, descending: bool = False) -> list[Import]:
|
316
338
|
"""
|
317
339
|
Lists all the Imports in the Model.
|
340
|
+
:param sort_by: The field to sort the results by.
|
341
|
+
:param descending: If True, the results will be sorted in descending order.
|
318
342
|
:return: The List of Imports.
|
319
343
|
"""
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
]
|
344
|
+
res = self._http.get_paginated(
|
345
|
+
f"{self._url}/imports", "imports", params=sort_params(sort_by, descending)
|
346
|
+
)
|
347
|
+
return [Import.model_validate(e) for e in res]
|
324
348
|
|
325
|
-
def get_exports(self) -> list[Export]:
|
349
|
+
def get_exports(self, sort_by: SortBy = None, descending: bool = False) -> list[Export]:
|
326
350
|
"""
|
327
351
|
Lists all the Exports in the Model.
|
352
|
+
:param sort_by: The field to sort the results by.
|
353
|
+
:param descending: If True, the results will be sorted in descending order.
|
328
354
|
:return: The List of Exports.
|
329
355
|
"""
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
]
|
356
|
+
res = self._http.get_paginated(
|
357
|
+
f"{self._url}/exports", "exports", params=sort_params(sort_by, descending)
|
358
|
+
)
|
359
|
+
return [Export.model_validate(e) for e in res]
|
334
360
|
|
335
361
|
def run_action(self, action_id: int, wait_for_completion: bool = True) -> TaskStatus:
|
336
362
|
"""
|
@@ -95,14 +95,15 @@ class _CloudWorksClient:
|
|
95
95
|
logger.info(f"Deleted connection '{con_id}'.")
|
96
96
|
|
97
97
|
def get_integrations(
|
98
|
-
self,
|
98
|
+
self, sort_by: Literal["name"] | None = None, descending: bool = False
|
99
99
|
) -> list[Integration]:
|
100
100
|
"""
|
101
101
|
List all integrations in CloudWorks.
|
102
|
-
:param
|
102
|
+
:param sort_by: The field to sort the results by.
|
103
|
+
:param descending: If True, the results will be sorted in descending order.
|
103
104
|
:return: A list of integrations.
|
104
105
|
"""
|
105
|
-
params = {"sortBy": "
|
106
|
+
params = {"sortBy": f"{'-' if descending else ''}{sort_by}"} if sort_by else None
|
106
107
|
return [
|
107
108
|
Integration.model_validate(e)
|
108
109
|
for e in self._http.get_paginated(f"{self._url}", "integrations", params=params)
|
@@ -7,6 +7,7 @@ from anaplan_sdk._services import (
|
|
7
7
|
_HttpService,
|
8
8
|
parse_calendar_response,
|
9
9
|
parse_insertion_response,
|
10
|
+
sort_params,
|
10
11
|
validate_dimension_id,
|
11
12
|
)
|
12
13
|
from anaplan_sdk.exceptions import InvalidIdentifierException
|
@@ -29,6 +30,8 @@ from anaplan_sdk.models import (
|
|
29
30
|
ViewInfo,
|
30
31
|
)
|
31
32
|
|
33
|
+
SortBy = Literal["id", "name"] | None
|
34
|
+
|
32
35
|
logger = logging.getLogger("anaplan_sdk")
|
33
36
|
|
34
37
|
|
@@ -66,24 +69,32 @@ class _TransactionalClient:
|
|
66
69
|
self._http.post_empty(f"{self._url}/close", headers={"Content-Type": "application/text"})
|
67
70
|
logger.info(f"Closed model '{self._model_id}'.")
|
68
71
|
|
69
|
-
def get_modules(self) -> list[Module]:
|
72
|
+
def get_modules(self, sort_by: SortBy = None, descending: bool = False) -> list[Module]:
|
70
73
|
"""
|
71
74
|
Lists all the Modules in the Model.
|
75
|
+
:param sort_by: The field to sort the results by.
|
76
|
+
:param descending: If True, the results will be sorted in descending order.
|
72
77
|
:return: The List of Modules.
|
73
78
|
"""
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
]
|
79
|
+
res = self._http.get_paginated(
|
80
|
+
f"{self._url}/modules", "modules", params=sort_params(sort_by, descending)
|
81
|
+
)
|
82
|
+
return [Module.model_validate(e) for e in res]
|
78
83
|
|
79
|
-
def get_views(
|
84
|
+
def get_views(
|
85
|
+
self, sort_by: Literal["id", "module_id", "name"] | None = None, descending: bool = False
|
86
|
+
) -> list[View]:
|
80
87
|
"""
|
81
88
|
Lists all the Views in the Model. This will include all Modules and potentially other saved
|
82
89
|
views.
|
90
|
+
:param sort_by: The field to sort the results by.
|
91
|
+
:param descending: If True, the results will be sorted in descending order.
|
83
92
|
:return: The List of Views.
|
84
93
|
"""
|
94
|
+
params = {"includesubsidiaryviews": True} | sort_params(sort_by, descending)
|
85
95
|
return [
|
86
|
-
View.model_validate(e)
|
96
|
+
View.model_validate(e)
|
97
|
+
for e in self._http.get_paginated(f"{self._url}/views", "views", params=params)
|
87
98
|
]
|
88
99
|
|
89
100
|
def get_view_info(self, view_id: int) -> ViewInfo:
|
@@ -107,14 +118,17 @@ class _TransactionalClient:
|
|
107
118
|
)
|
108
119
|
return [LineItem.model_validate(e) for e in self._http.get(url).get("items", [])]
|
109
120
|
|
110
|
-
def get_lists(self) -> list[List]:
|
121
|
+
def get_lists(self, sort_by: SortBy = None, descending: bool = False) -> list[List]:
|
111
122
|
"""
|
112
123
|
Lists all the Lists in the Model.
|
124
|
+
:param sort_by: The field to sort the results by.
|
125
|
+
:param descending: If True, the results will be sorted in descending order.
|
113
126
|
:return: All Lists on this model.
|
114
127
|
"""
|
115
|
-
|
116
|
-
|
117
|
-
|
128
|
+
res = self._http.get_paginated(
|
129
|
+
f"{self._url}/lists", "lists", params=sort_params(sort_by, descending)
|
130
|
+
)
|
131
|
+
return [List.model_validate(e) for e in res]
|
118
132
|
|
119
133
|
def get_list_metadata(self, list_id: int) -> ListMetadata:
|
120
134
|
"""
|
@@ -33,6 +33,15 @@ from .models.cloud_works import (
|
|
33
33
|
ScheduleInput,
|
34
34
|
)
|
35
35
|
|
36
|
+
SORT_WARNING = (
|
37
|
+
"If you are sorting by a field that is potentially ambiguous (e.g., name), the order of "
|
38
|
+
"results is not guaranteed to be internally consistent across multiple requests. This will "
|
39
|
+
"lead to wrong results when paginating through result sets where the ambiguous order can cause "
|
40
|
+
"records to slip between pages or be duplicated on multiple pages. The only way to ensure "
|
41
|
+
"correct results when sorting is to make sure the entire result set fits in one page, or to "
|
42
|
+
"sort by a field that is guaranteed to be unique (e.g., id)."
|
43
|
+
)
|
44
|
+
|
36
45
|
logger = logging.getLogger("anaplan_sdk")
|
37
46
|
|
38
47
|
_json_header = {"Content-Type": "application/json"}
|
@@ -104,7 +113,8 @@ class _HttpService:
|
|
104
113
|
if total_items <= self._page_size:
|
105
114
|
logger.debug("All items fit in first page, no additional requests needed.")
|
106
115
|
return iter(first_page)
|
107
|
-
|
116
|
+
if kwargs and (kwargs.get("params") or {}).get("sort", None):
|
117
|
+
logger.warning(SORT_WARNING)
|
108
118
|
pages_needed = ceil(total_items / actual_size)
|
109
119
|
logger.debug(f"Fetching {pages_needed - 1} additional pages with {actual_size} items each.")
|
110
120
|
with ThreadPoolExecutor() as executor:
|
@@ -222,6 +232,8 @@ class _AsyncHttpService:
|
|
222
232
|
if total_items <= self._page_size:
|
223
233
|
logger.debug("All items fit in first page, no additional requests needed.")
|
224
234
|
return iter(first_page)
|
235
|
+
if kwargs and (kwargs.get("params") or {}).get("sort", None):
|
236
|
+
logger.warning(SORT_WARNING)
|
225
237
|
pages = await gather(
|
226
238
|
*(
|
227
239
|
self._get_page(url, actual_size, n * actual_size, result_key, **kwargs)
|
@@ -274,13 +286,15 @@ class _AsyncHttpService:
|
|
274
286
|
raise AnaplanException("Exhausted all retries without a successful response or Error.")
|
275
287
|
|
276
288
|
|
277
|
-
def sort_params(sort_by: str, descending: bool) -> dict[str, str | bool]:
|
289
|
+
def sort_params(sort_by: str | None, descending: bool) -> dict[str, str | bool]:
|
278
290
|
"""
|
279
291
|
Construct search parameters for sorting. This also converts snake_case to camelCase.
|
280
292
|
:param sort_by: The field to sort by, optionally in snake_case.
|
281
293
|
:param descending: Whether to sort in descending order.
|
282
294
|
:return: A dictionary of search parameters in Anaplan's expected format.
|
283
295
|
"""
|
296
|
+
if not sort_by:
|
297
|
+
return {}
|
284
298
|
return {"sort": f"{'-' if descending else '+'}{to_camel(sort_by)}"}
|
285
299
|
|
286
300
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
!!! danger "Anaplan Sorting is not consistent"
|
2
|
+
If you are sorting by a field that is potentially ambiguous (e.g., `name`), the order of results is not guaranteed
|
3
|
+
to be internally consistent across multiple requests. This will lead to wrong results when paginating through
|
4
|
+
result sets where the ambiguous order can cause records to slip between pages or be duplicated on multiple pages.
|
5
|
+
The only way to ensure correct results when sorting is to make sure the entire result set fits in one page,
|
6
|
+
or to sort by a field that is guaranteed to be unique (e.g., `id`).
|
7
|
+
|
8
|
+
Some endpoints support sorting results by a specified field in either ascending or descending order. The methods for
|
9
|
+
these endpoints include a `sort_by` parameter to specify the field to sort on, and a `descending` boolean parameter
|
10
|
+
to specify the sort order (default is ascending).
|
11
|
+
|
12
|
+
## Syntax
|
13
|
+
|
14
|
+
These Methods support sorting. The Type Literals for the `sort_by` will tell you which fields are supported for sorting.
|
15
|
+
|
16
|
+
```python
|
17
|
+
# Audit
|
18
|
+
anaplan.audit.get_users(sort_by="email")
|
19
|
+
|
20
|
+
# Workspaces & Models
|
21
|
+
anaplan.get_workspaces(sort_by="size_allowance", descending=True)
|
22
|
+
anaplan.get_models(sort_by="active_state")
|
23
|
+
|
24
|
+
# Model Objects
|
25
|
+
anaplan.get_files(sort_by="name")
|
26
|
+
anaplan.get_actions(sort_by="id")
|
27
|
+
anaplan.get_processes(sort_by="name")
|
28
|
+
anaplan.get_imports(sort_by="id")
|
29
|
+
anaplan.get_exports(sort_by="name")
|
30
|
+
|
31
|
+
# Transactional
|
32
|
+
anaplan.tr.get_modules(sort_by="name")
|
33
|
+
anaplan.tr.get_views(sort_by="module_id")
|
34
|
+
anaplan.tr.get_lists(sort_by="id")
|
35
|
+
|
36
|
+
# ALM
|
37
|
+
anaplan.alm.get_revisions(sort_by="created_on")
|
38
|
+
|
39
|
+
# CloudWorks
|
40
|
+
anaplan.cw.get_integrations(sort_by_name="descending")
|
41
|
+
```
|
@@ -1,11 +1,9 @@
|
|
1
1
|
[project]
|
2
2
|
name = "anaplan-sdk"
|
3
|
-
version = "0.5.
|
3
|
+
version = "0.5.0a4"
|
4
4
|
description = "Streamlined Python Interface for the Anaplan API."
|
5
5
|
license = "Apache-2.0"
|
6
|
-
authors = [
|
7
|
-
{ name = "Vinzenz Klass", email = "vinzenz.klass@valantic.com" }
|
8
|
-
]
|
6
|
+
authors = [{ name = "Vinzenz Klass", email = "vinzenz.klass@valantic.com" }]
|
9
7
|
readme = "README.md"
|
10
8
|
keywords = [
|
11
9
|
"anaplan",
|
@@ -51,7 +51,7 @@ async def test_list_integrations(client):
|
|
51
51
|
|
52
52
|
|
53
53
|
async def test_list_integrations_desc(client):
|
54
|
-
integrations_desc = await client.cw.get_integrations(
|
54
|
+
integrations_desc = await client.cw.get_integrations(sort_by="name", descending=True)
|
55
55
|
assert isinstance(integrations_desc, list)
|
56
56
|
assert all(isinstance(i, Integration) for i in integrations_desc)
|
57
57
|
|
@@ -49,7 +49,7 @@ def test_list_integrations(client):
|
|
49
49
|
|
50
50
|
|
51
51
|
def test_list_integrations_desc(client):
|
52
|
-
integrations_desc = client.cw.get_integrations(
|
52
|
+
integrations_desc = client.cw.get_integrations(sort_by="name", descending=True)
|
53
53
|
assert isinstance(integrations_desc, list)
|
54
54
|
assert all(isinstance(i, Integration) for i in integrations_desc)
|
55
55
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
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
|