anaplan-sdk 0.4.0a1__tar.gz → 0.4.0a2__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.0a2/PKG-INFO +87 -0
- anaplan_sdk-0.4.0a2/README.md +67 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_async_clients/_alm.py +1 -21
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_async_clients/_audit.py +9 -2
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_async_clients/_bulk.py +18 -6
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_async_clients/_transactional.py +0 -25
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_clients/_alm.py +1 -21
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_clients/_audit.py +7 -2
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_clients/_bulk.py +15 -6
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_clients/_transactional.py +0 -21
- anaplan_sdk-0.4.0a2/docs/anaplan_explained.md +68 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/api/async/async_alm_client.md +1 -1
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/api/async/async_audit_client.md +1 -1
- anaplan_sdk-0.4.0a2/docs/api/async/async_cw_client.md +5 -0
- anaplan_sdk-0.4.0a2/docs/api/async/async_flows_client.md +5 -0
- anaplan_sdk-0.4.0a2/docs/api/sync/sync_cw_client.md +5 -0
- anaplan_sdk-0.4.0a2/docs/api/sync/sync_flows_client.md +5 -0
- anaplan_sdk-0.4.0a2/docs/assets/overview.html +282 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/css/styles.css +8 -1
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/guides/alm.md +4 -17
- anaplan_sdk-0.4.0a2/docs/guides/authentication.md +205 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/guides/bulk.md +31 -57
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/guides/transactional.md +1 -14
- anaplan_sdk-0.4.0a2/docs/img/anaplan-sdk.webp +0 -0
- anaplan_sdk-0.4.0a2/docs/index.md +59 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/mkdocs.yml +2 -1
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/pyproject.toml +3 -2
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/async/conftest.py +6 -13
- anaplan_sdk-0.4.0a2/tests/async/test_async_audit_client.py +23 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/async/test_async_client.py +13 -3
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/async/test_async_transactional_client.py +1 -5
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/conftest.py +7 -1
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/sync/conftest.py +6 -13
- anaplan_sdk-0.4.0a2/tests/sync/test_audit_client.py +21 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/sync/test_client.py +13 -5
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/sync/test_transactional_client.py +1 -5
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/uv.lock +697 -511
- 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.0a2}/.github/dependabot.yml +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/.github/workflows/docs.yml +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/.github/workflows/lint.yml +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/.github/workflows/tests.yml +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/.gitignore +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/.pre-commit-config.yaml +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/LICENSE +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/__init__.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_async_clients/__init__.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_async_clients/_cloud_works.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_async_clients/_cw_flow.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_auth.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_base.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_clients/__init__.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_clients/_cloud_works.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/_clients/_cw_flow.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/exceptions.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/models/__init__.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/models/_alm.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/models/_base.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/models/_bulk.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/models/_transactional.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/models/cloud_works.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/anaplan_sdk/models/flows.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/api/async/async_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/api/async/async_transactional_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/api/exceptions.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/api/models.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/api/sync/sync_alm_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/api/sync/sync_audit_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/api/sync/sync_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/api/sync/sync_transactional_client.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/guides/audit.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/guides/bulk_vs_transactional.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/guides/cloud_works.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/guides/index.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/guides/logging.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/guides/multiple_models.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/installation.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/js/assets/hljs.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/js/assets/hljs.min.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/js/assets/python.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/js/assets/python.min.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/js/highlight.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/js/highlight.min.js +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/docs/quickstart.md +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/async/test_async_alm_client.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/async/test_async_cloud_works_client.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/async/test_async_flows_client.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/sync/test_alm_client.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/tests/sync/test_cloud_works_client.py +0 -0
- {anaplan_sdk-0.4.0a1 → anaplan_sdk-0.4.0a2}/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.0a2
|
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 integration
|
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:
|
@@ -169,25 +166,3 @@ class _AsyncTransactionalClient(_AsyncBaseClient):
|
|
169
166
|
"""
|
170
167
|
res = await self._post(f"{self._url}/modules/{module_id}/data", json=data)
|
171
168
|
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)
|
@@ -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
|
|
@@ -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
|
@@ -164,23 +163,3 @@ class _TransactionalClient(_BaseClient):
|
|
164
163
|
"""
|
165
164
|
res = self._post(f"{self._url}/modules/{module_id}/data", json=data)
|
166
165
|
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)
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Anaplan Basics
|
2
|
+
|
3
|
+
This guide explains key Anaplan concepts for developers working with the Bulk API. You can think of the flow of uploading data to Anaplan with the Bulk API like so:
|
4
|
+
|
5
|
+
<iframe id="bulk-overview" src="../assets/overview.html"></iframe>
|
6
|
+
|
7
|
+
---
|
8
|
+
|
9
|
+
## Quick Overview
|
10
|
+
|
11
|
+
- You upload data to files in Anaplan. The only supported file formats are `csv` and `xlsx`.
|
12
|
+
- Import Actions move data from files to Lists & Modules
|
13
|
+
- Export Actions move data from Lists & Modules to files
|
14
|
+
- You download these files to retrieve data
|
15
|
+
- Processes are sequences of actions
|
16
|
+
- **Never** run concurrent operations that reference the same file.
|
17
|
+
|
18
|
+
|
19
|
+
## Files
|
20
|
+
|
21
|
+
- All data exchange happens through files (referenced by ID (113000000000), not SFTP/FTP)
|
22
|
+
- Files have a 48-hour lifetime
|
23
|
+
- Files are **not safe for concurrent access**. You can override the content of a file while another import is reading
|
24
|
+
from it. Anaplan does not acquire locks and will not queue the task.
|
25
|
+
|
26
|
+
## Actions
|
27
|
+
|
28
|
+
All data is exchanged through files. When uploading data, you are uploading the data to a file previously registered
|
29
|
+
with Anaplan. When downloading data, you are downloading a file either registered with Anaplan or produced by an
|
30
|
+
export action. Anaplan does not use (S)FTP, you will reference these files only by their ID and send or receive their
|
31
|
+
content in the body of HTTP Requests.
|
32
|
+
|
33
|
+
- Anaplan has the following type of actions:
|
34
|
+
- Imports - 112000000000 IDs.
|
35
|
+
- Exports - 116000000000 IDs.
|
36
|
+
- Processes - 118000000000 IDs.
|
37
|
+
- Other Actions - 117000000000 IDs.
|
38
|
+
|
39
|
+
Imports read data from a file and load it into a module. Exports conversely load data from a module to a file. The
|
40
|
+
file id of the resulting file is identical to the export id. "Other Actions" move things around in Anaplan and can
|
41
|
+
also delete data etc. Processes are simply a sequence of the other three.
|
42
|
+
|
43
|
+
Invoking any Action will spawn a Task. You can then query the status of this task.
|
44
|
+
|
45
|
+
Files are **NOT Safe** for concurrent access. If you want to override the content of a file while an import is being
|
46
|
+
run against it, you can. Import and Export Actions, however, are. If you run an Export while an Import into a module
|
47
|
+
that will affect the data of the module you are trying to export from, Anaplan will queue this task. No dirty reads.
|
48
|
+
|
49
|
+
## Imports
|
50
|
+
|
51
|
+
Imports read data from a file and load it into a list or module. Only after running an Import against the file you just
|
52
|
+
uploaded is the data actually "in" Anaplan. Only uploading a file will do nothing and after 48h - the lifetime for files
|
53
|
+
in Anaplan - the content will simply vanish. Import Actions are quite powerful and can incur mapping of columns from
|
54
|
+
i.e. a csv structure to dimensions in Anaplan, type conversion, date parsing and more. They are also quite easy to get
|
55
|
+
wrong and very sensitive to change.
|
56
|
+
|
57
|
+
## Exports
|
58
|
+
|
59
|
+
When you want to get some data from Anaplan, you will have to do the reverse of an Import, in two similar steps. First,
|
60
|
+
you run an export and wait for the spawned task to complete. Then you can download the content of the file that was
|
61
|
+
populated by the export action. The File will have the same ID as the Export Action that produced it.
|
62
|
+
|
63
|
+
## Processes
|
64
|
+
|
65
|
+
A Process is just an arbitrary sequence of any kind of actions. These are useful for grouping actions that must only be
|
66
|
+
run together or just represent some logical grouping. Processes can include import an export actions. When loading data
|
67
|
+
to or from Anaplan with a process, you will have to find the Import or Export contained in the process, and the
|
68
|
+
referenced data source in the case of an Import.
|
@@ -0,0 +1,5 @@
|
|
1
|
+
???+ note
|
2
|
+
This Class is not meant to be instantiated directly, but rather accessed through the `cw` Property on an
|
3
|
+
instance of [AsyncClient](async_client.md). For more details, see the [Guide](../../guides/cloud_works.md).
|
4
|
+
|
5
|
+
::: anaplan_sdk._async_clients._AsyncCloudWorksClient
|
@@ -0,0 +1,5 @@
|
|
1
|
+
???+ note
|
2
|
+
This Class is not meant to be instantiated directly, but rather accessed through the `cw.flows` Property on an
|
3
|
+
instance of [AsyncClient](async_client.md). For more details, see the [Guide](../../guides/cloud_works.md).
|
4
|
+
|
5
|
+
::: anaplan_sdk._async_clients._cw_flow._AsyncFlowClient
|
@@ -0,0 +1,5 @@
|
|
1
|
+
???+ note
|
2
|
+
This Class is not meant to be instantiated directly, but rather accessed through the `cw` Property on an
|
3
|
+
instance of [Client](sync_client.md). For more details, see the [Guide](../../guides/cloud_works.md).
|
4
|
+
|
5
|
+
::: anaplan_sdk._async_clients._AsyncCloudWorksClient
|
@@ -0,0 +1,5 @@
|
|
1
|
+
???+ note
|
2
|
+
This Class is not meant to be instantiated directly, but rather accessed through the `cw.flows` Property on an
|
3
|
+
instance of [Client](sync_client.md). For more details, see the [Guide](../../guides/cloud_works.md).
|
4
|
+
|
5
|
+
::: anaplan_sdk._async_clients._cw_flow._AsyncFlowClient
|