anaplan-sdk 0.5.0a4__tar.gz → 0.5.0a5__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.0a4 → anaplan_sdk-0.5.0a5}/PKG-INFO +1 -1
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_async_clients/_audit.py +3 -1
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_async_clients/_bulk.py +20 -22
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_clients/_audit.py +3 -1
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_clients/_bulk.py +20 -22
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_services.py +14 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/models/_bulk.py +6 -4
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/guides/alm.md +2 -6
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/guides/bulk.md +7 -2
- anaplan_sdk-0.5.0a5/docs/guides/multiple_models.md +37 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/pyproject.toml +1 -1
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/async/conftest.py +6 -3
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/async/test_async_client.py +5 -4
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/async/test_async_transactional_client.py +1 -2
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/sync/conftest.py +6 -3
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/sync/test_client.py +6 -5
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/sync/test_transactional_client.py +1 -2
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/uv.lock +1 -1
- anaplan_sdk-0.5.0a4/docs/guides/multiple_models.md +0 -33
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/.github/dependabot.yml +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/.github/workflows/docs.yml +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/.github/workflows/lint.yml +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/.github/workflows/tests.yml +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/.gitignore +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/.pre-commit-config.yaml +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/LICENSE +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/README.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/__init__.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_async_clients/__init__.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_async_clients/_alm.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_async_clients/_cloud_works.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_async_clients/_cw_flow.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_async_clients/_transactional.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_auth.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_clients/__init__.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_clients/_alm.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_clients/_cloud_works.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_clients/_cw_flow.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_clients/_transactional.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/_oauth.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/exceptions.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/models/__init__.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/models/_alm.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/models/_base.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/models/_transactional.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/models/cloud_works.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/anaplan_sdk/models/flows.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/async/async_alm_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/async/async_audit_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/async/async_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/async/async_cw_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/async/async_flows_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/async/async_oauth_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/async/async_transactional_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/exceptions.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/models/alm.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/models/bulk.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/models/cloud_works.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/models/flows.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/models/transactional.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/sync/sync_alm_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/sync/sync_audit_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/sync/sync_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/sync/sync_cw_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/sync/sync_flows_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/sync/sync_oauth_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/api/sync/sync_transactional_client.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/assets/overview.html +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/concepts.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/css/styles.css +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/guides/audit.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/guides/authentication.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/guides/bulk_vs_transactional.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/guides/cloud_works.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/guides/index.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/guides/logging.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/guides/sorting.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/guides/transactional.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/img/anaplan-sdk.webp +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/index.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/installation.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/js/assets/hljs.js +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/js/assets/hljs.min.js +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/js/assets/python.js +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/js/assets/python.min.js +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/js/highlight.js +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/js/highlight.min.js +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/docs/quickstart.md +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/mkdocs.yml +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/async/test_async_alm_client.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/async/test_async_audit_client.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/async/test_async_cloud_works_client.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/async/test_async_flows_client.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/conftest.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/sync/test_alm_client.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/sync/test_audit_client.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/sync/test_cloud_works_client.py +0 -0
- {anaplan_sdk-0.5.0a4 → anaplan_sdk-0.5.0a5}/tests/sync/test_flows_client.py +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.0a5
|
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
|
@@ -21,7 +21,9 @@ class _AsyncAuditClient:
|
|
21
21
|
) -> list[User]:
|
22
22
|
"""
|
23
23
|
Lists all the Users in the authenticated users default tenant.
|
24
|
-
:param search_pattern:
|
24
|
+
:param search_pattern: **Caution: This is an undocumented Feature and may behave
|
25
|
+
unpredictably. It requires the Tenant Admin role. For non-admin users, it is
|
26
|
+
ignored.** Optionally filter for specific users. When provided,
|
25
27
|
case-insensitive matches users with emails or names containing this string.
|
26
28
|
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
27
29
|
When None (default), returns all users.
|
@@ -7,7 +7,7 @@ import httpx
|
|
7
7
|
from typing_extensions import Self
|
8
8
|
|
9
9
|
from anaplan_sdk._auth import _create_auth
|
10
|
-
from anaplan_sdk._services import _AsyncHttpService, action_url, sort_params
|
10
|
+
from anaplan_sdk._services import _AsyncHttpService, action_url, models_url, sort_params
|
11
11
|
from anaplan_sdk.exceptions import AnaplanActionError, InvalidIdentifierException
|
12
12
|
from anaplan_sdk.models import (
|
13
13
|
Action,
|
@@ -142,34 +142,24 @@ class AsyncClient:
|
|
142
142
|
f"Initialized AsyncClient with workspace_id={workspace_id}, model_id={model_id}"
|
143
143
|
)
|
144
144
|
|
145
|
-
|
146
|
-
def from_existing(
|
147
|
-
cls, existing: Self, *, workspace_id: str | None = None, model_id: str | None = None
|
148
|
-
) -> Self:
|
145
|
+
def with_model(self, model_id: str | None = None, workspace_id: str | None = None) -> Self:
|
149
146
|
"""
|
150
|
-
Create a new instance of the Client
|
151
|
-
|
152
|
-
authentication and configuration. This creates a shallow copy of the existing client and
|
153
|
-
optionally updates the relevant attributes to the new workspace and model. You can provide
|
154
|
-
either a new workspace Id or a new model Id, or both. If you do not provide one of them,
|
155
|
-
the existing value will be used. If you omit both, the new instance will be an identical
|
156
|
-
copy of the existing instance.
|
157
|
-
|
158
|
-
:param existing: The existing instance to copy.
|
147
|
+
Create a new instance of the Client with the given model and workspace Ids. **This creates
|
148
|
+
a copy of the current client. The current instance remains unchanged.**
|
159
149
|
:param workspace_id: The workspace Id to use or None to use the existing workspace Id.
|
160
150
|
:param model_id: The model Id to use or None to use the existing model Id.
|
161
151
|
:return: A new instance of the Client.
|
162
152
|
"""
|
163
|
-
client = copy(
|
164
|
-
new_ws_id = workspace_id or
|
165
|
-
new_model_id = model_id or
|
153
|
+
client = copy(self)
|
154
|
+
new_ws_id = workspace_id or self._workspace_id
|
155
|
+
new_model_id = model_id or self._model_id
|
166
156
|
logger.debug(
|
167
157
|
f"Creating a new AsyncClient from existing instance "
|
168
158
|
f"with workspace_id={new_ws_id}, model_id={new_model_id}."
|
169
159
|
)
|
170
160
|
client._url = f"https://api.anaplan.com/2/0/workspaces/{new_ws_id}/models/{new_model_id}"
|
171
|
-
client._transactional_client = _AsyncTransactionalClient(
|
172
|
-
client._alm_client = _AsyncAlmClient(
|
161
|
+
client._transactional_client = _AsyncTransactionalClient(self._http, new_model_id)
|
162
|
+
client._alm_client = _AsyncAlmClient(self._http, new_model_id)
|
173
163
|
return client
|
174
164
|
|
175
165
|
@property
|
@@ -235,7 +225,9 @@ class AsyncClient:
|
|
235
225
|
) -> list[Workspace]:
|
236
226
|
"""
|
237
227
|
Lists all the Workspaces the authenticated user has access to.
|
238
|
-
:param search_pattern:
|
228
|
+
:param search_pattern: **Caution: This is an undocumented Feature and may behave
|
229
|
+
unpredictably. It requires the Tenant Admin role. For non-admin users, it is
|
230
|
+
ignored.** Optionally filter for specific workspaces. When provided,
|
239
231
|
case-insensitive matches workspaces with names containing this string.
|
240
232
|
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
241
233
|
When None (default), returns all users.
|
@@ -253,13 +245,19 @@ class AsyncClient:
|
|
253
245
|
|
254
246
|
async def get_models(
|
255
247
|
self,
|
248
|
+
only_in_workspace: bool | str = False,
|
256
249
|
search_pattern: str | None = None,
|
257
250
|
sort_by: Literal["active_state", "name"] | None = None,
|
258
251
|
descending: bool = False,
|
259
252
|
) -> list[Model]:
|
260
253
|
"""
|
261
254
|
Lists all the Models the authenticated user has access to.
|
262
|
-
:param
|
255
|
+
:param only_in_workspace: If True, only lists models in the workspace provided when
|
256
|
+
instantiating the client. If a string is provided, only lists models in the workspace
|
257
|
+
with the given Id. If False (default), lists models in all workspaces the user
|
258
|
+
:param search_pattern: **Caution: This is an undocumented Feature and may behave
|
259
|
+
unpredictably. It requires the Tenant Admin role. For non-admin users, it is
|
260
|
+
ignored.** Optionally filter for specific models. When provided,
|
263
261
|
case-insensitive matches model names containing this string.
|
264
262
|
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
265
263
|
When None (default), returns all models.
|
@@ -271,7 +269,7 @@ class AsyncClient:
|
|
271
269
|
if search_pattern:
|
272
270
|
params["s"] = search_pattern
|
273
271
|
res = await self._http.get_paginated(
|
274
|
-
|
272
|
+
models_url(only_in_workspace, self._workspace_id), "models", params=params
|
275
273
|
)
|
276
274
|
return [Model.model_validate(e) for e in res]
|
277
275
|
|
@@ -21,7 +21,9 @@ class _AuditClient:
|
|
21
21
|
) -> list[User]:
|
22
22
|
"""
|
23
23
|
Lists all the Users in the authenticated users default tenant.
|
24
|
-
:param search_pattern:
|
24
|
+
:param search_pattern: **Caution: This is an undocumented Feature and may behave
|
25
|
+
unpredictably. It requires the Tenant Admin role. For non-admin users, it is
|
26
|
+
ignored.** Optionally filter for specific users. When provided,
|
25
27
|
case-insensitive matches users with emails or names containing this string.
|
26
28
|
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
27
29
|
When None (default), returns all users.
|
@@ -8,7 +8,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, sort_params
|
11
|
+
from anaplan_sdk._services import _HttpService, action_url, models_url, sort_params
|
12
12
|
from anaplan_sdk.exceptions import AnaplanActionError, InvalidIdentifierException
|
13
13
|
from anaplan_sdk.models import (
|
14
14
|
Action,
|
@@ -147,34 +147,24 @@ class Client:
|
|
147
147
|
self.allow_file_creation = allow_file_creation
|
148
148
|
logger.debug(f"Initialized Client with workspace_id={workspace_id}, model_id={model_id}")
|
149
149
|
|
150
|
-
|
151
|
-
def from_existing(
|
152
|
-
cls, existing: Self, *, workspace_id: str | None = None, model_id: str | None = None
|
153
|
-
) -> Self:
|
150
|
+
def with_model(self, model_id: str | None = None, workspace_id: str | None = None) -> Self:
|
154
151
|
"""
|
155
|
-
Create a new instance of the Client
|
156
|
-
|
157
|
-
authentication and configuration. This creates a shallow copy of the existing client and
|
158
|
-
optionally updates the relevant attributes to the new workspace and model. You can provide
|
159
|
-
either a new workspace Id or a new model Id, or both. If you do not provide one of them,
|
160
|
-
the existing value will be used. If you omit both, the new instance will be an identical
|
161
|
-
copy of the existing instance.
|
162
|
-
|
163
|
-
:param existing: The existing instance to copy.
|
152
|
+
Create a new instance of the Client with the given model and workspace Ids. **This creates
|
153
|
+
a copy of the current client. The current instance remains unchanged.**
|
164
154
|
:param workspace_id: The workspace Id to use or None to use the existing workspace Id.
|
165
155
|
:param model_id: The model Id to use or None to use the existing model Id.
|
166
156
|
:return: A new instance of the Client.
|
167
157
|
"""
|
168
|
-
client = copy(
|
169
|
-
new_ws_id = workspace_id or
|
170
|
-
new_model_id = model_id or
|
158
|
+
client = copy(self)
|
159
|
+
new_ws_id = workspace_id or self._workspace_id
|
160
|
+
new_model_id = model_id or self._model_id
|
171
161
|
logger.debug(
|
172
162
|
f"Creating a new AsyncClient from existing instance "
|
173
163
|
f"with workspace_id={new_ws_id}, model_id={new_model_id}."
|
174
164
|
)
|
175
165
|
client._url = f"https://api.anaplan.com/2/0/workspaces/{new_ws_id}/models/{new_model_id}"
|
176
|
-
client._transactional_client = _TransactionalClient(
|
177
|
-
client._alm_client = _AlmClient(
|
166
|
+
client._transactional_client = _TransactionalClient(self._http, new_model_id)
|
167
|
+
client._alm_client = _AlmClient(self._http, new_model_id)
|
178
168
|
return client
|
179
169
|
|
180
170
|
@property
|
@@ -240,7 +230,9 @@ class Client:
|
|
240
230
|
) -> list[Workspace]:
|
241
231
|
"""
|
242
232
|
Lists all the Workspaces the authenticated user has access to.
|
243
|
-
:param search_pattern:
|
233
|
+
:param search_pattern: **Caution: This is an undocumented Feature and may behave
|
234
|
+
unpredictably. It requires the Tenant Admin role. For non-admin users, it is
|
235
|
+
ignored.** Optionally filter for specific workspaces. When provided,
|
244
236
|
case-insensitive matches workspaces with names containing this string.
|
245
237
|
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
246
238
|
When None (default), returns all users.
|
@@ -258,13 +250,19 @@ class Client:
|
|
258
250
|
|
259
251
|
def get_models(
|
260
252
|
self,
|
253
|
+
only_in_workspace: bool | str = False,
|
261
254
|
search_pattern: str | None = None,
|
262
255
|
sort_by: Literal["active_state", "name"] | None = None,
|
263
256
|
descending: bool = False,
|
264
257
|
) -> list[Model]:
|
265
258
|
"""
|
266
259
|
Lists all the Models the authenticated user has access to.
|
267
|
-
:param
|
260
|
+
:param only_in_workspace: If True, only lists models in the workspace provided when
|
261
|
+
instantiating the client. If a string is provided, only lists models in the workspace
|
262
|
+
with the given Id. If False (default), lists models in all workspaces the user
|
263
|
+
:param search_pattern: **Caution: This is an undocumented Feature and may behave
|
264
|
+
unpredictably. It requires the Tenant Admin role. For non-admin users, it is
|
265
|
+
ignored.** Optionally filter for specific models. When provided,
|
268
266
|
case-insensitive matches model names containing this string.
|
269
267
|
You can use the wildcards `%` for 0-n characters, and `_` for exactly 1 character.
|
270
268
|
When None (default), returns all models.
|
@@ -276,7 +274,7 @@ class Client:
|
|
276
274
|
if search_pattern:
|
277
275
|
params["s"] = search_pattern
|
278
276
|
res = self._http.get_paginated(
|
279
|
-
|
277
|
+
models_url(only_in_workspace, self._workspace_id), "models", params=params
|
280
278
|
)
|
281
279
|
return [Model.model_validate(e) for e in res]
|
282
280
|
|
@@ -286,6 +286,20 @@ class _AsyncHttpService:
|
|
286
286
|
raise AnaplanException("Exhausted all retries without a successful response or Error.")
|
287
287
|
|
288
288
|
|
289
|
+
def models_url(only_in_workspace: bool | str, workspace_id: str | None) -> str:
|
290
|
+
if isinstance(only_in_workspace, bool) and only_in_workspace:
|
291
|
+
if not workspace_id:
|
292
|
+
raise ValueError(
|
293
|
+
"Cannot list models in the current workspace, since no workspace Id was "
|
294
|
+
"provided when instantiating the client. Either provide a workspace Id when "
|
295
|
+
"instantiating the client, or pass a specific workspace Id to this method."
|
296
|
+
)
|
297
|
+
return f"https://api.anaplan.com/2/0/workspaces/{workspace_id}/models"
|
298
|
+
if isinstance(only_in_workspace, str):
|
299
|
+
return f"https://api.anaplan.com/2/0/workspaces/{only_in_workspace}/models"
|
300
|
+
return "https://api.anaplan.com/2/0/models"
|
301
|
+
|
302
|
+
|
289
303
|
def sort_params(sort_by: str | None, descending: bool) -> dict[str, str | bool]:
|
290
304
|
"""
|
291
305
|
Construct search parameters for sorting. This also converts snake_case to camelCase.
|
@@ -39,11 +39,13 @@ class Model(AnaplanModel):
|
|
39
39
|
description="The unique identifier of the user who last modified this model."
|
40
40
|
)
|
41
41
|
memory_usage: int = Field(0, description="The memory usage of this model in bytes.")
|
42
|
-
|
43
|
-
|
42
|
+
workspace_id: str = Field(
|
43
|
+
validation_alias="currentWorkspaceId",
|
44
|
+
description="The unique identifier of the workspace that this model is currently in.",
|
44
45
|
)
|
45
|
-
|
46
|
-
|
46
|
+
workspace_name: str = Field(
|
47
|
+
validation_alias="currentWorkspaceName",
|
48
|
+
description="The name of the workspace that this model is currently in.",
|
47
49
|
)
|
48
50
|
url: str = Field(validation_alias="modelUrl", description="The current URL of this model.")
|
49
51
|
category_values: list = Field(description="The category values of this model.")
|
@@ -245,9 +245,7 @@ Here's an example of a complete deployment pipeline that creates a revision, syn
|
|
245
245
|
certificate="~/certs/anaplan.pem",
|
246
246
|
private_key="~/keys/anaplan.pem",
|
247
247
|
)
|
248
|
-
target_client =
|
249
|
-
source_client, model_id=target_model_id
|
250
|
-
)
|
248
|
+
target_client = source_client.with_model(target_model_id)
|
251
249
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
252
250
|
source_revision = source_client.alm.create_revision(
|
253
251
|
name=f"Production Deploy {now}",
|
@@ -273,9 +271,7 @@ Here's an example of a complete deployment pipeline that creates a revision, syn
|
|
273
271
|
certificate="~/certs/anaplan.pem",
|
274
272
|
private_key="~/keys/anaplan.pem",
|
275
273
|
)
|
276
|
-
target_client =
|
277
|
-
source_client, model_id=target_model_id
|
278
|
-
)
|
274
|
+
target_client = source_client.with_model(target_model_id)
|
279
275
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
280
276
|
source_revision, target_revision = await gather(
|
281
277
|
source_client.alm.create_revision(
|
@@ -55,6 +55,8 @@ provide the workspace and model IDs.
|
|
55
55
|
# Globals, this will work on an instance with auth info only
|
56
56
|
workspaces = anaplan.get_workspaces()
|
57
57
|
models = anaplan.get_models()
|
58
|
+
models_in_current_ws = anaplan.get_models(True) # This requires a workspace_id
|
59
|
+
models_in_other_ws = anaplan.get_models("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB")
|
58
60
|
|
59
61
|
# These require an instance with workspace and model info
|
60
62
|
imports = anaplan.get_imports()
|
@@ -64,8 +66,11 @@ provide the workspace and model IDs.
|
|
64
66
|
```
|
65
67
|
=== "Asynchronous"
|
66
68
|
```python
|
67
|
-
workspaces, models = await gather(
|
68
|
-
anaplan.get_workspaces(),
|
69
|
+
workspaces, models, models_in_current_ws, models_in_other_ws = await gather(
|
70
|
+
anaplan.get_workspaces(),
|
71
|
+
anaplan.get_models(),
|
72
|
+
anaplan.get_models(True), # This requires a workspace_id in
|
73
|
+
anaplan.get_models("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB")
|
69
74
|
) # Globals, this will work on an instance with auth info only
|
70
75
|
|
71
76
|
imports, exports, actions, processes = await gather(
|
@@ -0,0 +1,37 @@
|
|
1
|
+
---
|
2
|
+
hide:
|
3
|
+
- toc
|
4
|
+
---
|
5
|
+
|
6
|
+
If you find yourself working with several Models at the same time, you will want to reuse a Client Instance instead of
|
7
|
+
creating an entirely new one. This is both syntactically nicer and more efficient by avoiding duplicate authentication
|
8
|
+
and sharing underlying resources that can safely be shared. For this Purpose, you can use the `with_model()` method.
|
9
|
+
You can optionally pass a new Workspace ID and Model ID to this method. If you omit the Workspace ID - the second
|
10
|
+
argument - the existing one will be used.
|
11
|
+
|
12
|
+
=== "Synchronous"
|
13
|
+
```python
|
14
|
+
anaplan = Client(
|
15
|
+
workspace_id="8a81b09d599f3c6e0159f605560c2630",
|
16
|
+
model_id="8896D8C366BC48E5A3182B9F5CE10526",
|
17
|
+
certificate=getenv("ANAPLAN_CERT"),
|
18
|
+
private_key=getenv("ANAPLAN_PK"),
|
19
|
+
)
|
20
|
+
other = anaplan.with_model("22222222222222222222222222222222") # Updates the Model Id
|
21
|
+
other_ws = anaplan.with_model(
|
22
|
+
"22222222222222222222222222222222", "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
|
23
|
+
) # Updates the Model Id and the Workspace Id
|
24
|
+
```
|
25
|
+
=== "Asynchronous"
|
26
|
+
```python
|
27
|
+
anaplan = AsyncClient(
|
28
|
+
workspace_id="8a81b09d599f3c6e0159f605560c2630",
|
29
|
+
model_id="8896D8C366BC48E5A3182B9F5CE10526",
|
30
|
+
certificate=getenv("ANAPLAN_CERT"),
|
31
|
+
private_key=getenv("ANAPLAN_PK"),
|
32
|
+
)
|
33
|
+
other = anaplan.with_model("22222222222222222222222222222222") # Updates the Model Id
|
34
|
+
other_ws = anaplan.with_model(
|
35
|
+
"22222222222222222222222222222222", "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
|
36
|
+
) # Updates the Model Id and the Workspace Id
|
37
|
+
```
|
@@ -25,18 +25,21 @@ def client_small_pages() -> AsyncClient:
|
|
25
25
|
model_id=getenv("ANAPLAN_SDK_TEST_MODEL_ID"),
|
26
26
|
certificate=getenv("ANAPLAN_SDK_TEST_CERT"),
|
27
27
|
private_key=getenv("ANAPLAN_SDK_TEST_PK"),
|
28
|
-
page_size=
|
28
|
+
page_size=100,
|
29
|
+
retry_count=3,
|
30
|
+
backoff=5,
|
31
|
+
timeout=120,
|
29
32
|
)
|
30
33
|
|
31
34
|
|
32
35
|
@pytest.fixture(scope="session")
|
33
36
|
def alm_src_client(client: AsyncClient, alm_src_model_id) -> AsyncClient:
|
34
|
-
return
|
37
|
+
return client.with_model(alm_src_model_id)
|
35
38
|
|
36
39
|
|
37
40
|
@pytest.fixture(scope="session")
|
38
41
|
def alm_client(client: AsyncClient, alm_model_id) -> AsyncClient:
|
39
|
-
return
|
42
|
+
return client.with_model(alm_model_id)
|
40
43
|
|
41
44
|
|
42
45
|
@pytest.fixture(scope="session")
|
@@ -47,13 +47,14 @@ async def test_file_creation_raises_exception(client: AsyncClient):
|
|
47
47
|
|
48
48
|
|
49
49
|
async def test_list_models(client: AsyncClient):
|
50
|
-
models, search = await gather(
|
50
|
+
models, current_only, search = await gather(
|
51
|
+
client.get_models(), client.get_models(True), client.get_models(search_pattern="Demo")
|
52
|
+
)
|
51
53
|
assert isinstance(models, list)
|
52
54
|
assert all(isinstance(model, Model) for model in models)
|
55
|
+
assert all(isinstance(model, Model) for model in current_only)
|
53
56
|
assert all(isinstance(model, Model) for model in search)
|
54
|
-
assert len(models) > 0
|
55
|
-
assert len(search) > 0
|
56
|
-
assert len(search) < len(models)
|
57
|
+
assert len(models) > len(current_only) > len(search) > 0
|
57
58
|
|
58
59
|
|
59
60
|
async def test_list_models_multi_page(client_small_pages: AsyncClient):
|
@@ -24,8 +24,7 @@ async def test_wake_model(client: AsyncClient):
|
|
24
24
|
|
25
25
|
|
26
26
|
async def test_close_model(client: AsyncClient):
|
27
|
-
|
28
|
-
await other.tr.close_model()
|
27
|
+
await client.with_model("C87EBE934BD442B1A798540E0CA5A877").tr.close_model()
|
29
28
|
|
30
29
|
|
31
30
|
async def test_get_model(client: AsyncClient):
|
@@ -25,18 +25,21 @@ def client_small_pages() -> Client:
|
|
25
25
|
model_id=getenv("ANAPLAN_SDK_TEST_MODEL_ID"),
|
26
26
|
certificate=getenv("ANAPLAN_SDK_TEST_CERT"),
|
27
27
|
private_key=getenv("ANAPLAN_SDK_TEST_PK"),
|
28
|
-
page_size=
|
28
|
+
page_size=100,
|
29
|
+
retry_count=3,
|
30
|
+
backoff=5,
|
31
|
+
timeout=120,
|
29
32
|
)
|
30
33
|
|
31
34
|
|
32
35
|
@pytest.fixture(scope="session")
|
33
36
|
def alm_src_client(client: Client, alm_src_model_id) -> Client:
|
34
|
-
return
|
37
|
+
return client.with_model(alm_src_model_id)
|
35
38
|
|
36
39
|
|
37
40
|
@pytest.fixture(scope="session")
|
38
41
|
def alm_client(client: Client, alm_model_id) -> Client:
|
39
|
-
return
|
42
|
+
return client.with_model(alm_model_id)
|
40
43
|
|
41
44
|
|
42
45
|
@pytest.fixture(scope="session")
|
@@ -44,14 +44,15 @@ def test_file_creation_raises_exception(client: Client):
|
|
44
44
|
client.upload_file(115000000000, b"")
|
45
45
|
|
46
46
|
|
47
|
-
def test_list_models(client):
|
48
|
-
models
|
47
|
+
def test_list_models(client: Client):
|
48
|
+
models = client.get_models()
|
49
|
+
current_only = client.get_models(True)
|
50
|
+
search = client.get_models(search_pattern="Demo")
|
49
51
|
assert isinstance(models, list)
|
50
52
|
assert all(isinstance(model, Model) for model in models)
|
53
|
+
assert all(isinstance(model, Model) for model in current_only)
|
51
54
|
assert all(isinstance(model, Model) for model in search)
|
52
|
-
assert len(models) > 0
|
53
|
-
assert len(search) > 0
|
54
|
-
assert len(search) < len(models)
|
55
|
+
assert len(models) > len(current_only) > len(search) > 0
|
55
56
|
|
56
57
|
|
57
58
|
def test_list_models_multi_page(client_small_pages: Client):
|
@@ -24,8 +24,7 @@ def test_wake_model(client: Client):
|
|
24
24
|
|
25
25
|
|
26
26
|
def test_close_model(client: Client):
|
27
|
-
|
28
|
-
other.tr.close_model()
|
27
|
+
client.with_model("C87EBE934BD442B1A798540E0CA5A877").tr.close_model()
|
29
28
|
|
30
29
|
|
31
30
|
def test_get_model(client: Client):
|
@@ -1,33 +0,0 @@
|
|
1
|
-
If you find yourself working with several Models at the same time, you will want to reuse a Client Instance instead of
|
2
|
-
creating an entirely new one. This will be more efficient by avoiding duplicate authentication and sharing underlying
|
3
|
-
resources that can safely be shared. For this Purpose, you can use the `from_existing()` Class method. You can
|
4
|
-
optionally pass a new Workspace ID and Model ID to this method. If you omit the Workspace ID, the existing one will be used. If you omit both, the new client will be an identical copy of the existing one.
|
5
|
-
|
6
|
-
=== "Synchronous"
|
7
|
-
```python
|
8
|
-
anaplan = anaplan_sdk.Client(
|
9
|
-
workspace_id="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
10
|
-
model_id="11111111111111111111111111111111",
|
11
|
-
certificate="~/certs/anaplan.pem",
|
12
|
-
private_key="~/keys/anaplan.pem",
|
13
|
-
)
|
14
|
-
other = anaplan_sdk.Client.from_existing(
|
15
|
-
anaplan,
|
16
|
-
workspace_id="BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
|
17
|
-
model_id="22222222222222222222222222222222",
|
18
|
-
)
|
19
|
-
```
|
20
|
-
=== "Asynchronous"
|
21
|
-
```python
|
22
|
-
anaplan = anaplan_sdk.AsyncClient(
|
23
|
-
workspace_id="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
24
|
-
model_id="11111111111111111111111111111111",
|
25
|
-
certificate="~/certs/anaplan.pem",
|
26
|
-
private_key="~/keys/anaplan.pem",
|
27
|
-
)
|
28
|
-
other = anaplan_sdk.AsyncClient.from_existing(
|
29
|
-
anaplan,
|
30
|
-
workspace_id="BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
|
31
|
-
model_id="22222222222222222222222222222222",
|
32
|
-
)
|
33
|
-
```
|
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
|