anaplan-sdk 0.4.0a1__tar.gz → 0.4.0a3__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.4.0a3/PKG-INFO +87 -0
- anaplan_sdk-0.4.0a3/README.md +67 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_async_clients/_alm.py +1 -21
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_async_clients/_audit.py +9 -2
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_async_clients/_bulk.py +18 -6
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_async_clients/_transactional.py +26 -29
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_base.py +1 -5
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_clients/_alm.py +1 -21
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_clients/_audit.py +7 -2
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_clients/_bulk.py +16 -8
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_clients/_transactional.py +26 -25
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/models/_base.py +1 -6
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/models/cloud_works.py +5 -9
- anaplan_sdk-0.4.0a3/docs/anaplan_explained.md +68 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/api/async/async_alm_client.md +1 -1
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/api/async/async_audit_client.md +1 -1
- anaplan_sdk-0.4.0a3/docs/api/async/async_cw_client.md +5 -0
- anaplan_sdk-0.4.0a3/docs/api/async/async_flows_client.md +5 -0
- anaplan_sdk-0.4.0a3/docs/api/sync/sync_cw_client.md +5 -0
- anaplan_sdk-0.4.0a3/docs/api/sync/sync_flows_client.md +5 -0
- anaplan_sdk-0.4.0a3/docs/assets/overview.html +282 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/css/styles.css +8 -1
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/guides/alm.md +4 -17
- anaplan_sdk-0.4.0a3/docs/guides/authentication.md +205 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/guides/bulk.md +31 -57
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/guides/transactional.md +1 -14
- anaplan_sdk-0.4.0a3/docs/img/anaplan-sdk.webp +0 -0
- anaplan_sdk-0.4.0a3/docs/index.md +59 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/mkdocs.yml +2 -1
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/pyproject.toml +16 -7
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/async/conftest.py +7 -13
- anaplan_sdk-0.4.0a3/tests/async/test_async_audit_client.py +23 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/async/test_async_client.py +13 -3
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/async/test_async_transactional_client.py +1 -1
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/conftest.py +8 -7
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/sync/conftest.py +7 -13
- anaplan_sdk-0.4.0a3/tests/sync/test_audit_client.py +21 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/sync/test_client.py +13 -5
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/sync/test_transactional_client.py +1 -1
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/uv.lock +1 -1
- anaplan_sdk-0.4.0a1/PKG-INFO +0 -140
- anaplan_sdk-0.4.0a1/README.md +0 -120
- anaplan_sdk-0.4.0a1/docs/anaplan_explained.md +0 -56
- anaplan_sdk-0.4.0a1/docs/api/async/async_cw_client.md +0 -1
- anaplan_sdk-0.4.0a1/docs/api/async/async_flows_client.md +0 -1
- anaplan_sdk-0.4.0a1/docs/api/sync/sync_cw_client.md +0 -1
- anaplan_sdk-0.4.0a1/docs/api/sync/sync_flows_client.md +0 -1
- anaplan_sdk-0.4.0a1/docs/img/anaplan-overview.webp +0 -0
- anaplan_sdk-0.4.0a1/docs/img/anaplan-sdk.webp +0 -0
- anaplan_sdk-0.4.0a1/docs/index.md +0 -41
- anaplan_sdk-0.4.0a1/tests/async/test_async_audit_client.py +0 -17
- anaplan_sdk-0.4.0a1/tests/sync/test_audit_client.py +0 -19
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/.github/dependabot.yml +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/.github/workflows/docs.yml +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/.github/workflows/lint.yml +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/.github/workflows/tests.yml +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/.gitignore +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/.pre-commit-config.yaml +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/LICENSE +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/__init__.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_async_clients/__init__.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_async_clients/_cloud_works.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_async_clients/_cw_flow.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_auth.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_clients/__init__.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_clients/_cloud_works.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/_clients/_cw_flow.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/exceptions.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/models/__init__.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/models/_alm.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/models/_bulk.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/models/_transactional.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/anaplan_sdk/models/flows.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/api/async/async_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/api/async/async_transactional_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/api/exceptions.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/api/models.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/api/sync/sync_alm_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/api/sync/sync_audit_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/api/sync/sync_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/api/sync/sync_transactional_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/guides/audit.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/guides/bulk_vs_transactional.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/guides/cloud_works.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/guides/index.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/guides/logging.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/guides/multiple_models.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/installation.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/js/assets/hljs.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/js/assets/hljs.min.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/js/assets/python.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/js/assets/python.min.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/js/highlight.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/js/highlight.min.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/docs/quickstart.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/async/test_async_alm_client.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/async/test_async_cloud_works_client.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/async/test_async_flows_client.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/sync/test_alm_client.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/sync/test_cloud_works_client.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a3}/tests/sync/test_flows_client.py +0 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: anaplan-sdk
|
3
|
+
Version: 0.4.0a3
|
4
|
+
Summary: Provides pythonic access to the Anaplan API
|
5
|
+
Project-URL: Homepage, https://vinzenzklass.github.io/anaplan-sdk/
|
6
|
+
Project-URL: Repository, https://github.com/VinzenzKlass/anaplan-sdk
|
7
|
+
Project-URL: Documentation, https://vinzenzklass.github.io/anaplan-sdk/
|
8
|
+
Author-email: Vinzenz Klass <vinzenz.klass@valantic.com>
|
9
|
+
License-Expression: Apache-2.0
|
10
|
+
License-File: LICENSE
|
11
|
+
Keywords: anaplan,anaplan alm api,anaplan api,anaplan audit api,anaplan bulk api,anaplan cloudworks api,anaplan integration,anaplan integration api,anaplan sdk,anaplan transactional api
|
12
|
+
Requires-Python: >=3.10.4
|
13
|
+
Requires-Dist: httpx<1.0.0,>=0.27.0
|
14
|
+
Requires-Dist: pydantic<3.0.0,>=2.7.2
|
15
|
+
Provides-Extra: cert
|
16
|
+
Requires-Dist: cryptography<45.0.0,>=42.0.7; extra == 'cert'
|
17
|
+
Provides-Extra: oauth
|
18
|
+
Requires-Dist: oauthlib<4.0.0,>=3.0.0; extra == 'oauth'
|
19
|
+
Description-Content-Type: text/markdown
|
20
|
+
|
21
|
+
<p align="center">
|
22
|
+
<img width="160" height="160" src="https://vinzenzklass.github.io/anaplan-sdk/img/anaplan-sdk.webp" alt='Python' style="border-radius: 15px">
|
23
|
+
</p>
|
24
|
+
|
25
|
+
<h3 align="center" style="font-size: 3rem; font-weight: 600;">
|
26
|
+
Anaplan SDK
|
27
|
+
</h3>
|
28
|
+
|
29
|
+
<p align="center" style="font-size: 1.2rem; font-weight: 300; margin: 15px 0">
|
30
|
+
Streamlined Python Interface for Anaplan
|
31
|
+
</p>
|
32
|
+
|
33
|
+
<div align="center">
|
34
|
+
<a href="https://pepy.tech/projects/anaplan-sdk">
|
35
|
+
<img src="https://static.pepy.tech/badge/anaplan-sdk" alt="">
|
36
|
+
</a>
|
37
|
+
<a href="https://pypi.org/project/anaplan-sdk/">
|
38
|
+
<img src="https://img.shields.io/pypi/v/anaplan-sdk.svg" alt="PyPi Latest Release"/>
|
39
|
+
</a>
|
40
|
+
<a href="https://pepy.tech/projects/anaplan-sdk">
|
41
|
+
<img src="https://static.pepy.tech/badge/anaplan-sdk/month" alt="PyPI Downloads">
|
42
|
+
</a>
|
43
|
+
</div>
|
44
|
+
|
45
|
+
---
|
46
|
+
|
47
|
+
Anaplan SDK is an independent, unofficial project providing pythonic access to Anaplan. It delivers high-level
|
48
|
+
abstractions over all Anaplan APIs, allowing you to focus on business requirements rather than implementation details.
|
49
|
+
|
50
|
+
## Key Features
|
51
|
+
|
52
|
+
- **Pythonic Interface**: Clean, intuitive access to Anaplan functionality
|
53
|
+
- **Simplified API Interactions**: Automatic handling of authentication, error handling, and data formatting
|
54
|
+
- **Performance Optimizations**: Built-in chunking and compression techniques
|
55
|
+
- **Multiple API Support**: Compatible with all major Anaplan API endpoints
|
56
|
+
- **Flexible Client Options**: Both synchronous and asynchronous implementations
|
57
|
+
- **Developer-Friendly**: Designed to reduce boilerplate code and accelerate development
|
58
|
+
|
59
|
+
## Getting Started
|
60
|
+
|
61
|
+
Head over to the [Quick Start](quickstart.md) for basic usage instructions and examples.
|
62
|
+
|
63
|
+
## Contributing
|
64
|
+
|
65
|
+
Pull Requests are welcome. For major changes,
|
66
|
+
please [open an issue](https://github.com/VinzenzKlass/anaplan-sdk/issues/new) first to discuss what you would like to
|
67
|
+
change. To submit a pull request, please follow the
|
68
|
+
standard [Fork & Pull Request workflow](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork).
|
69
|
+
|
70
|
+
Before submitting your pull request, please ensure that all the files pass linting and formatting checks. You can do
|
71
|
+
this by running the following command:
|
72
|
+
|
73
|
+
```shell
|
74
|
+
uv sync --dev
|
75
|
+
|
76
|
+
ruff check
|
77
|
+
ruff format
|
78
|
+
```
|
79
|
+
|
80
|
+
You can also enable [pre-commit](https://pre-commit.com/) hooks to automatically format and lint your code before
|
81
|
+
committing:
|
82
|
+
|
83
|
+
```shell
|
84
|
+
pre-commit install
|
85
|
+
```
|
86
|
+
|
87
|
+
If your PR goes beyond a simple bug fix or small changes, please add tests to cover your changes.
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<p align="center">
|
2
|
+
<img width="160" height="160" src="https://vinzenzklass.github.io/anaplan-sdk/img/anaplan-sdk.webp" alt='Python' style="border-radius: 15px">
|
3
|
+
</p>
|
4
|
+
|
5
|
+
<h3 align="center" style="font-size: 3rem; font-weight: 600;">
|
6
|
+
Anaplan SDK
|
7
|
+
</h3>
|
8
|
+
|
9
|
+
<p align="center" style="font-size: 1.2rem; font-weight: 300; margin: 15px 0">
|
10
|
+
Streamlined Python Interface for Anaplan
|
11
|
+
</p>
|
12
|
+
|
13
|
+
<div align="center">
|
14
|
+
<a href="https://pepy.tech/projects/anaplan-sdk">
|
15
|
+
<img src="https://static.pepy.tech/badge/anaplan-sdk" alt="">
|
16
|
+
</a>
|
17
|
+
<a href="https://pypi.org/project/anaplan-sdk/">
|
18
|
+
<img src="https://img.shields.io/pypi/v/anaplan-sdk.svg" alt="PyPi Latest Release"/>
|
19
|
+
</a>
|
20
|
+
<a href="https://pepy.tech/projects/anaplan-sdk">
|
21
|
+
<img src="https://static.pepy.tech/badge/anaplan-sdk/month" alt="PyPI Downloads">
|
22
|
+
</a>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
---
|
26
|
+
|
27
|
+
Anaplan SDK is an independent, unofficial project providing pythonic access to Anaplan. It delivers high-level
|
28
|
+
abstractions over all Anaplan APIs, allowing you to focus on business requirements rather than implementation details.
|
29
|
+
|
30
|
+
## Key Features
|
31
|
+
|
32
|
+
- **Pythonic Interface**: Clean, intuitive access to Anaplan functionality
|
33
|
+
- **Simplified API Interactions**: Automatic handling of authentication, error handling, and data formatting
|
34
|
+
- **Performance Optimizations**: Built-in chunking and compression techniques
|
35
|
+
- **Multiple API Support**: Compatible with all major Anaplan API endpoints
|
36
|
+
- **Flexible Client Options**: Both synchronous and asynchronous implementations
|
37
|
+
- **Developer-Friendly**: Designed to reduce boilerplate code and accelerate development
|
38
|
+
|
39
|
+
## Getting Started
|
40
|
+
|
41
|
+
Head over to the [Quick Start](quickstart.md) for basic usage instructions and examples.
|
42
|
+
|
43
|
+
## Contributing
|
44
|
+
|
45
|
+
Pull Requests are welcome. For major changes,
|
46
|
+
please [open an issue](https://github.com/VinzenzKlass/anaplan-sdk/issues/new) first to discuss what you would like to
|
47
|
+
change. To submit a pull request, please follow the
|
48
|
+
standard [Fork & Pull Request workflow](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork).
|
49
|
+
|
50
|
+
Before submitting your pull request, please ensure that all the files pass linting and formatting checks. You can do
|
51
|
+
this by running the following command:
|
52
|
+
|
53
|
+
```shell
|
54
|
+
uv sync --dev
|
55
|
+
|
56
|
+
ruff check
|
57
|
+
ruff format
|
58
|
+
```
|
59
|
+
|
60
|
+
You can also enable [pre-commit](https://pre-commit.com/) hooks to automatically format and lint your code before
|
61
|
+
committing:
|
62
|
+
|
63
|
+
```shell
|
64
|
+
pre-commit install
|
65
|
+
```
|
66
|
+
|
67
|
+
If your PR goes beyond a simple bug fix or small changes, please add tests to cover your changes.
|
@@ -1,11 +1,7 @@
|
|
1
|
-
import warnings
|
2
|
-
|
3
1
|
import httpx
|
4
2
|
|
5
3
|
from anaplan_sdk._base import _AsyncBaseClient
|
6
|
-
from anaplan_sdk.models import ModelRevision, Revision, SyncTask
|
7
|
-
|
8
|
-
warnings.filterwarnings("always", category=DeprecationWarning)
|
4
|
+
from anaplan_sdk.models import ModelRevision, Revision, SyncTask
|
9
5
|
|
10
6
|
|
11
7
|
class _AsyncAlmClient(_AsyncBaseClient):
|
@@ -13,22 +9,6 @@ class _AsyncAlmClient(_AsyncBaseClient):
|
|
13
9
|
self._url = f"https://api.anaplan.com/2/0/models/{model_id}/alm"
|
14
10
|
super().__init__(retry_count, client)
|
15
11
|
|
16
|
-
async def list_users(self) -> list[User]:
|
17
|
-
"""
|
18
|
-
Lists all the Users in the authenticated users default tenant.
|
19
|
-
:return: The List of Users.
|
20
|
-
"""
|
21
|
-
warnings.warn(
|
22
|
-
"`list_users()` on the ALM client is deprecated and will be removed in a "
|
23
|
-
"future version. Use `list_users()` on the Audit client instead.",
|
24
|
-
DeprecationWarning,
|
25
|
-
stacklevel=1,
|
26
|
-
)
|
27
|
-
return [
|
28
|
-
User.model_validate(e)
|
29
|
-
for e in (await self._get("https://api.anaplan.com/2/0/users")).get("users")
|
30
|
-
]
|
31
|
-
|
32
12
|
async def get_syncable_revisions(self, source_model_id: str) -> list[Revision]:
|
33
13
|
"""
|
34
14
|
Use this call to return the list of revisions from your source model that can be
|
@@ -14,14 +14,21 @@ class _AsyncAuditClient(_AsyncBaseClient):
|
|
14
14
|
self._url = "https://audit.anaplan.com/audit/api/1/events"
|
15
15
|
super().__init__(retry_count, client)
|
16
16
|
|
17
|
-
async def list_users(self) -> list[User]:
|
17
|
+
async def list_users(self, search_pattern: str | None = None) -> list[User]:
|
18
18
|
"""
|
19
19
|
Lists all the Users in the authenticated users default tenant.
|
20
|
+
:param search_pattern: Optionally filter for specific users. When provided,
|
21
|
+
case-insensitive matches users with emails or names containing this string.
|
22
|
+
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
23
|
+
When None (default), returns all users.
|
20
24
|
:return: The List of Users.
|
21
25
|
"""
|
26
|
+
params = {"s": search_pattern} if search_pattern else None
|
22
27
|
return [
|
23
28
|
User.model_validate(e)
|
24
|
-
for e in await self._get_paginated(
|
29
|
+
for e in await self._get_paginated(
|
30
|
+
"https://api.anaplan.com/2/0/users", "users", params=params
|
31
|
+
)
|
25
32
|
]
|
26
33
|
|
27
34
|
async def get_user(self, user_id: str = "me") -> User:
|
@@ -219,29 +219,41 @@ class AsyncClient(_AsyncBaseClient):
|
|
219
219
|
)
|
220
220
|
return self._alm_client
|
221
221
|
|
222
|
-
async def list_workspaces(self) -> list[Workspace]:
|
222
|
+
async def list_workspaces(self, search_pattern: str | None = None) -> list[Workspace]:
|
223
223
|
"""
|
224
224
|
Lists all the Workspaces the authenticated user has access to.
|
225
|
+
:param search_pattern: Optionally filter for specific workspaces. When provided,
|
226
|
+
case-insensitive matches workspaces with names containing this string.
|
227
|
+
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
228
|
+
When None (default), returns all users.
|
225
229
|
:return: The List of Workspaces.
|
226
230
|
"""
|
231
|
+
params = {"tenantDetails": "true"}
|
232
|
+
if search_pattern:
|
233
|
+
params["s"] = search_pattern
|
227
234
|
return [
|
228
235
|
Workspace.model_validate(e)
|
229
236
|
for e in await self._get_paginated(
|
230
|
-
"https://api.anaplan.com/2/0/workspaces",
|
231
|
-
"workspaces",
|
232
|
-
params={"tenantDetails": "true"},
|
237
|
+
"https://api.anaplan.com/2/0/workspaces", "workspaces", params=params
|
233
238
|
)
|
234
239
|
]
|
235
240
|
|
236
|
-
async def list_models(self) -> list[Model]:
|
241
|
+
async def list_models(self, search_pattern: str | None = None) -> list[Model]:
|
237
242
|
"""
|
238
243
|
Lists all the Models the authenticated user has access to.
|
244
|
+
:param search_pattern: Optionally filter for specific models. When provided,
|
245
|
+
case-insensitive matches models names containing this string.
|
246
|
+
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
247
|
+
When None (default), returns all users.
|
239
248
|
:return: The List of Models.
|
240
249
|
"""
|
250
|
+
params = {"modelDetails": "true"}
|
251
|
+
if search_pattern:
|
252
|
+
params["s"] = search_pattern
|
241
253
|
return [
|
242
254
|
Model.model_validate(e)
|
243
255
|
for e in await self._get_paginated(
|
244
|
-
"https://api.anaplan.com/2/0/models", "models", params=
|
256
|
+
"https://api.anaplan.com/2/0/models", "models", params=params
|
245
257
|
)
|
246
258
|
]
|
247
259
|
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import warnings
|
2
1
|
from asyncio import gather
|
3
2
|
from itertools import chain
|
4
3
|
from typing import Any
|
@@ -16,8 +15,6 @@ from anaplan_sdk.models import (
|
|
16
15
|
Module,
|
17
16
|
)
|
18
17
|
|
19
|
-
warnings.filterwarnings("always", category=DeprecationWarning)
|
20
|
-
|
21
18
|
|
22
19
|
class _AsyncTransactionalClient(_AsyncBaseClient):
|
23
20
|
def __init__(self, client: httpx.AsyncClient, model_id: str, retry_count: int) -> None:
|
@@ -95,7 +92,15 @@ class _AsyncTransactionalClient(_AsyncBaseClient):
|
|
95
92
|
"""
|
96
93
|
Insert new items to the given list. The items must be a list of dictionaries with at least
|
97
94
|
the keys `code` and `name`. You can optionally pass further keys for parents, extra
|
98
|
-
properties etc.
|
95
|
+
properties etc. If you pass a long list, it will be split into chunks of 100,000 items, the
|
96
|
+
maximum allowed by the API.
|
97
|
+
|
98
|
+
**Warning**: If one or some of the requests timeout during large batch operations, the
|
99
|
+
operation may actually complete on the server. Retries for these chunks will then report
|
100
|
+
these items as "ignored" rather than "added", leading to misleading results. The results in
|
101
|
+
Anaplan will be correct, but this function may report otherwise. Be generous with your
|
102
|
+
timeouts and retries if you are using this function for large batch operations.
|
103
|
+
|
99
104
|
:param list_id: The ID of the List.
|
100
105
|
:param items: The items to insert into the List.
|
101
106
|
:return: The result of the insertion, indicating how many items were added,
|
@@ -126,7 +131,16 @@ class _AsyncTransactionalClient(_AsyncBaseClient):
|
|
126
131
|
|
127
132
|
async def delete_list_items(self, list_id: int, items: list[dict[str, str | int]]) -> int:
|
128
133
|
"""
|
129
|
-
Deletes items from a List.
|
134
|
+
Deletes items from a List. If you pass a long list, it will be split into chunks of 100,000
|
135
|
+
items, the maximum allowed by the API.
|
136
|
+
|
137
|
+
**Warning**: If one or some of the requests timeout during large batch operations, the
|
138
|
+
operation may actually complete on the server. Retries for these chunks will then report
|
139
|
+
none of these items as deleted, since on the retry none are removed, leading to misleading
|
140
|
+
results. The results in Anaplan will be correct, but this function may report otherwise.
|
141
|
+
Be generous with your timeouts and retries if you are using this function for large batch
|
142
|
+
operations.
|
143
|
+
|
130
144
|
:param list_id: The ID of the List.
|
131
145
|
:param items: The items to delete from the List. Must be a dict with either `code` or `id`
|
132
146
|
as the keys to identify the records to delete.
|
@@ -161,33 +175,16 @@ class _AsyncTransactionalClient(_AsyncBaseClient):
|
|
161
175
|
"""
|
162
176
|
Write the passed items to the specified module. If successful, the number of cells changed
|
163
177
|
is returned, if only partially successful or unsuccessful, the response with the according
|
164
|
-
details is returned instead.
|
165
|
-
|
178
|
+
details is returned instead.
|
179
|
+
|
180
|
+
**You can update a maximum of 100,000 cells or 15 MB of data (whichever is lower) in a
|
181
|
+
single request.** You must chunk your data accordingly. This is not done by this SDK,
|
182
|
+
since it is discouraged. For larger imports, you should use the Bulk API instead.
|
183
|
+
|
184
|
+
For more details see: https://anaplan.docs.apiary.io/#UpdateModuleCellData.
|
166
185
|
:param module_id: The ID of the Module.
|
167
186
|
:param data: The data to write to the Module.
|
168
187
|
:return: The number of cells changed or the response with the according error details.
|
169
188
|
"""
|
170
189
|
res = await self._post(f"{self._url}/modules/{module_id}/data", json=data)
|
171
190
|
return res if "failures" in res else res["numberOfCellsChanged"]
|
172
|
-
|
173
|
-
async def write_to_module(
|
174
|
-
self, module_id: int, data: list[dict[str, Any]]
|
175
|
-
) -> int | dict[str, Any]:
|
176
|
-
warnings.warn(
|
177
|
-
"`write_to_module()` is deprecated and will be removed in a future version. "
|
178
|
-
"Use `update_module_data()` instead.",
|
179
|
-
DeprecationWarning,
|
180
|
-
stacklevel=1,
|
181
|
-
)
|
182
|
-
return await self.update_module_data(module_id, data)
|
183
|
-
|
184
|
-
async def add_items_to_list(
|
185
|
-
self, list_id: int, items: list[dict[str, str | int | dict]]
|
186
|
-
) -> InsertionResult:
|
187
|
-
warnings.warn(
|
188
|
-
"`add_items_to_list()` is deprecated and will be removed in a future version. "
|
189
|
-
"Use `insert_list_items()` instead.",
|
190
|
-
DeprecationWarning,
|
191
|
-
stacklevel=1,
|
192
|
-
)
|
193
|
-
return await self.insert_list_items(list_id, items)
|
@@ -12,11 +12,7 @@ from typing import Any, Callable, Coroutine, Iterator, Literal, Type, TypeVar
|
|
12
12
|
import httpx
|
13
13
|
from httpx import HTTPError, Response
|
14
14
|
|
15
|
-
from .exceptions import
|
16
|
-
AnaplanException,
|
17
|
-
AnaplanTimeoutException,
|
18
|
-
InvalidIdentifierException,
|
19
|
-
)
|
15
|
+
from .exceptions import AnaplanException, AnaplanTimeoutException, InvalidIdentifierException
|
20
16
|
from .models import AnaplanModel
|
21
17
|
from .models.cloud_works import (
|
22
18
|
AmazonS3ConnectionInput,
|
@@ -1,11 +1,7 @@
|
|
1
|
-
import warnings
|
2
|
-
|
3
1
|
import httpx
|
4
2
|
|
5
3
|
from anaplan_sdk._base import _BaseClient
|
6
|
-
from anaplan_sdk.models import ModelRevision, Revision, SyncTask
|
7
|
-
|
8
|
-
warnings.filterwarnings("always", category=DeprecationWarning)
|
4
|
+
from anaplan_sdk.models import ModelRevision, Revision, SyncTask
|
9
5
|
|
10
6
|
|
11
7
|
class _AlmClient(_BaseClient):
|
@@ -13,22 +9,6 @@ class _AlmClient(_BaseClient):
|
|
13
9
|
self._url = f"https://api.anaplan.com/2/0/models/{model_id}/alm"
|
14
10
|
super().__init__(retry_count, client)
|
15
11
|
|
16
|
-
def list_users(self) -> list[User]:
|
17
|
-
"""
|
18
|
-
Lists all the Users in the authenticated users default tenant.
|
19
|
-
:return: The List of Users.
|
20
|
-
"""
|
21
|
-
warnings.warn(
|
22
|
-
"`list_users()` on the ALM client is deprecated and will be removed in a "
|
23
|
-
"future version. Use `list_users()` on the Audit client instead.",
|
24
|
-
DeprecationWarning,
|
25
|
-
stacklevel=1,
|
26
|
-
)
|
27
|
-
return [
|
28
|
-
User.model_validate(e)
|
29
|
-
for e in self._get("https://api.anaplan.com/2/0/users").get("users")
|
30
|
-
]
|
31
|
-
|
32
12
|
def get_syncable_revisions(self, source_model_id: str) -> list[Revision]:
|
33
13
|
"""
|
34
14
|
Use this call to return the list of revisions from your source model that can be
|
@@ -15,14 +15,19 @@ class _AuditClient(_BaseClient):
|
|
15
15
|
self._url = "https://audit.anaplan.com/audit/api/1/events"
|
16
16
|
super().__init__(retry_count, client)
|
17
17
|
|
18
|
-
def list_users(self) -> list[User]:
|
18
|
+
def list_users(self, search_pattern: str | None = None) -> list[User]:
|
19
19
|
"""
|
20
20
|
Lists all the Users in the authenticated users default tenant.
|
21
|
+
:param search_pattern: Optional filter for users. When provided, case-insensitive matches
|
22
|
+
users with emails containing this string. When None (default), returns all users.
|
21
23
|
:return: The List of Users.
|
22
24
|
"""
|
25
|
+
params = {"s": search_pattern} if search_pattern else None
|
23
26
|
return [
|
24
27
|
User.model_validate(e)
|
25
|
-
for e in self._get_paginated(
|
28
|
+
for e in self._get_paginated(
|
29
|
+
"https://api.anaplan.com/2/0/users", "users", params=params
|
30
|
+
)
|
26
31
|
]
|
27
32
|
|
28
33
|
def get_user(self, user_id: str = "me") -> User:
|
@@ -225,29 +225,38 @@ class Client(_BaseClient):
|
|
225
225
|
)
|
226
226
|
return self._alm_client
|
227
227
|
|
228
|
-
def list_workspaces(self) -> list[Workspace]:
|
228
|
+
def list_workspaces(self, search_pattern: str | None = None) -> list[Workspace]:
|
229
229
|
"""
|
230
230
|
Lists all the Workspaces the authenticated user has access to.
|
231
|
+
:param search_pattern: Optional filter for workspaces. When provided, case-insensitive
|
232
|
+
matches workspaces with names containing this string. When None (default),
|
233
|
+
returns all workspaces.
|
231
234
|
:return: The List of Workspaces.
|
232
235
|
"""
|
236
|
+
params = {"tenantDetails": "true"}
|
237
|
+
if search_pattern:
|
238
|
+
params["s"] = search_pattern
|
233
239
|
return [
|
234
240
|
Workspace.model_validate(e)
|
235
241
|
for e in self._get_paginated(
|
236
|
-
"https://api.anaplan.com/2/0/workspaces",
|
237
|
-
"workspaces",
|
238
|
-
params={"tenantDetails": "true"},
|
242
|
+
"https://api.anaplan.com/2/0/workspaces", "workspaces", params=params
|
239
243
|
)
|
240
244
|
]
|
241
245
|
|
242
|
-
def list_models(self) -> list[Model]:
|
246
|
+
def list_models(self, search_pattern: str | None = None) -> list[Model]:
|
243
247
|
"""
|
244
248
|
Lists all the Models the authenticated user has access to.
|
249
|
+
:param search_pattern: Optional filter for models. When provided, case-insensitive matches
|
250
|
+
models with names containing this string. When None (default), returns all models.
|
245
251
|
:return: The List of Models.
|
246
252
|
"""
|
253
|
+
params = {"modelDetails": "true"}
|
254
|
+
if search_pattern:
|
255
|
+
params["s"] = search_pattern
|
247
256
|
return [
|
248
257
|
Model.model_validate(e)
|
249
258
|
for e in self._get_paginated(
|
250
|
-
"https://api.anaplan.com/2/0/models", "models", params=
|
259
|
+
"https://api.anaplan.com/2/0/models", "models", params=params
|
251
260
|
)
|
252
261
|
]
|
253
262
|
|
@@ -464,8 +473,7 @@ class Client(_BaseClient):
|
|
464
473
|
:return: The identifier of the spawned Task.
|
465
474
|
"""
|
466
475
|
response = self._post(
|
467
|
-
f"{self._url}/{action_url(action_id)}/{action_id}/tasks",
|
468
|
-
json={"localeName": "en_US"},
|
476
|
+
f"{self._url}/{action_url(action_id)}/{action_id}/tasks", json={"localeName": "en_US"}
|
469
477
|
)
|
470
478
|
task_id = response.get("task").get("taskId")
|
471
479
|
logger.info(f"Invoked Action '{action_id}', spawned Task: '{task_id}'.")
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import warnings
|
2
1
|
from concurrent.futures import ThreadPoolExecutor
|
3
2
|
from itertools import chain
|
4
3
|
from typing import Any
|
@@ -87,7 +86,15 @@ class _TransactionalClient(_BaseClient):
|
|
87
86
|
"""
|
88
87
|
Insert new items to the given list. The items must be a list of dictionaries with at least
|
89
88
|
the keys `code` and `name`. You can optionally pass further keys for parents, extra
|
90
|
-
properties etc.
|
89
|
+
properties etc. If you pass a long list, it will be split into chunks of 100,000 items, the
|
90
|
+
maximum allowed by the API.
|
91
|
+
|
92
|
+
**Warning**: If one or some of the requests timeout during large batch operations, the
|
93
|
+
operation may actually complete on the server. Retries for these chunks will then report
|
94
|
+
these items as "ignored" rather than "added", leading to misleading results. The results in
|
95
|
+
Anaplan will be correct, but this function may report otherwise. Be generous with your
|
96
|
+
timeouts and retries if you are using this function for large batch operations.
|
97
|
+
|
91
98
|
:param list_id: The ID of the List.
|
92
99
|
:param items: The items to insert into the List.
|
93
100
|
:return: The result of the insertion, indicating how many items were added,
|
@@ -121,7 +128,16 @@ class _TransactionalClient(_BaseClient):
|
|
121
128
|
|
122
129
|
def delete_list_items(self, list_id: int, items: list[dict[str, str | int]]) -> int:
|
123
130
|
"""
|
124
|
-
Deletes items from a List.
|
131
|
+
Deletes items from a List. If you pass a long list, it will be split into chunks of 100,000
|
132
|
+
items, the maximum allowed by the API.
|
133
|
+
|
134
|
+
**Warning**: If one or some of the requests timeout during large batch operations, the
|
135
|
+
operation may actually complete on the server. Retries for these chunks will then report
|
136
|
+
none of these items as deleted, since on the retry none are removed, leading to misleading
|
137
|
+
results. The results in Anaplan will be correct, but this function may report otherwise.
|
138
|
+
Be generous with your timeouts and retries if you are using this function for large batch
|
139
|
+
operations.
|
140
|
+
|
125
141
|
:param list_id: The ID of the List.
|
126
142
|
:param items: The items to delete from the List. Must be a dict with either `code` or `id`
|
127
143
|
as the keys to identify the records to delete.
|
@@ -156,31 +172,16 @@ class _TransactionalClient(_BaseClient):
|
|
156
172
|
"""
|
157
173
|
Write the passed items to the specified module. If successful, the number of cells changed
|
158
174
|
is returned, if only partially successful or unsuccessful, the response with the according
|
159
|
-
details is returned instead.
|
160
|
-
|
175
|
+
details is returned instead.
|
176
|
+
|
177
|
+
**You can update a maximum of 100,000 cells or 15 MB of data (whichever is lower) in a
|
178
|
+
single request.** You must chunk your data accordingly. This is not done by this SDK,
|
179
|
+
since it is discouraged. For larger imports, you should use the Bulk API instead.
|
180
|
+
|
181
|
+
For more details see: https://anaplan.docs.apiary.io/#UpdateModuleCellData.
|
161
182
|
:param module_id: The ID of the Module.
|
162
183
|
:param data: The data to write to the Module.
|
163
184
|
:return: The number of cells changed or the response with the according error details.
|
164
185
|
"""
|
165
186
|
res = self._post(f"{self._url}/modules/{module_id}/data", json=data)
|
166
187
|
return res if "failures" in res else res["numberOfCellsChanged"]
|
167
|
-
|
168
|
-
def write_to_module(self, module_id: int, data: list[dict[str, Any]]) -> int | dict[str, Any]:
|
169
|
-
warnings.warn(
|
170
|
-
"`write_to_module()` is deprecated and will be removed in a future version. "
|
171
|
-
"Use `update_module_data()` instead.",
|
172
|
-
DeprecationWarning,
|
173
|
-
stacklevel=1,
|
174
|
-
)
|
175
|
-
return self.update_module_data(module_id, data)
|
176
|
-
|
177
|
-
def add_items_to_list(
|
178
|
-
self, list_id: int, items: list[dict[str, str | int | dict]]
|
179
|
-
) -> InsertionResult:
|
180
|
-
warnings.warn(
|
181
|
-
"`add_items_to_list()` is deprecated and will be removed in a future version. "
|
182
|
-
"Use `insert_list_items()` instead.",
|
183
|
-
DeprecationWarning,
|
184
|
-
stacklevel=1,
|
185
|
-
)
|
186
|
-
return self.insert_list_items(list_id, items)
|
@@ -6,12 +6,7 @@ class AnaplanModel(BaseModel):
|
|
6
6
|
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
|
7
7
|
|
8
8
|
@field_serializer(
|
9
|
-
"action_id",
|
10
|
-
"file_id",
|
11
|
-
"process_id",
|
12
|
-
"id",
|
13
|
-
when_used="unless-none",
|
14
|
-
check_fields=False,
|
9
|
+
"action_id", "file_id", "process_id", "id", when_used="unless-none", check_fields=False
|
15
10
|
) # While these are of type int, they are serialized as strings in the API payloads
|
16
11
|
def str_serializer(self, v: int) -> str:
|
17
12
|
return str(v)
|
@@ -262,8 +262,7 @@ class SingleIntegration(Integration):
|
|
262
262
|
|
263
263
|
class AnaplanSource(AnaplanModel):
|
264
264
|
type: Literal["Anaplan"] = Field(
|
265
|
-
default="Anaplan",
|
266
|
-
description="Literal signifying this is an Anaplan source.",
|
265
|
+
default="Anaplan", description="Literal signifying this is an Anaplan source."
|
267
266
|
)
|
268
267
|
action_id: int = Field(
|
269
268
|
description=(
|
@@ -294,20 +293,18 @@ class TableSource(AnaplanModel):
|
|
294
293
|
|
295
294
|
class TableTarget(TableSource):
|
296
295
|
overwrite: bool = Field(
|
297
|
-
default=False,
|
298
|
-
description="Whether to overwrite the table if it exists.",
|
296
|
+
default=False, description="Whether to overwrite the table if it exists."
|
299
297
|
)
|
300
298
|
|
301
299
|
|
302
300
|
class AnaplanTarget(AnaplanModel):
|
303
301
|
type: Literal["Anaplan"] = Field(
|
304
|
-
default="Anaplan",
|
305
|
-
description="Literal signifying this is an Anaplan target.",
|
302
|
+
default="Anaplan", description="Literal signifying this is an Anaplan target."
|
306
303
|
)
|
307
304
|
action_id: int = Field(
|
308
305
|
description=(
|
309
306
|
"The ID of the action to be used as a target. This can be a process, or import."
|
310
|
-
)
|
307
|
+
)
|
311
308
|
)
|
312
309
|
file_id: int = Field(description="The ID of the file to be used as a target.")
|
313
310
|
|
@@ -342,8 +339,7 @@ class IntegrationInput(AnaplanModel):
|
|
342
339
|
),
|
343
340
|
)
|
344
341
|
nux_visible: bool = Field(
|
345
|
-
default=False,
|
346
|
-
description="Whether this integration is visible in the UI.",
|
342
|
+
default=False, description="Whether this integration is visible in the UI."
|
347
343
|
)
|
348
344
|
jobs: list[IntegrationJobInput] = Field(
|
349
345
|
description="The jobs in this integration.", min_length=1
|