dominus-sdk-python 4.6.1__tar.gz → 5.0.0__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.
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/PKG-INFO +2 -2
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/README.md +1 -1
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/__init__.py +1 -1
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/authority.py +64 -61
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/recipes.py +23 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/start.py +2 -2
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus_sdk_python.egg-info/PKG-INFO +2 -2
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus_sdk_python.egg-info/SOURCES.txt +1 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/pyproject.toml +1 -1
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_authority_public_vocabulary.py +64 -22
- dominus_sdk_python-5.0.0/tests/test_recipes_namespace.py +49 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/config/__init__.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/config/endpoints.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/errors.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/helpers/__init__.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/helpers/auth.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/helpers/cache.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/helpers/console_capture.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/helpers/core.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/helpers/crypto.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/helpers/sse.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/helpers/trace.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/__init__.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/admin.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/ai.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/artifacts.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/auth.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/browser.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/courier.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/db.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/ddl.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/deployer.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/fastapi.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/files.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/health.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/jobs.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/logs.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/portal.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/processor.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/redis.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/secrets.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/secure.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/stash.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/sync.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/warden.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/namespaces/workflow.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus/services/__init__.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus_sdk_python.egg-info/dependency_links.txt +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus_sdk_python.egg-info/requires.txt +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus_sdk_python.egg-info/top_level.txt +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/setup.cfg +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_auth.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_browser_namespace.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_control_plane_namespaces.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_errors.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_flat_commands.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_health.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_logs.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_provisioning_parity.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_public_exports.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_transport_compat.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_workflow_lifecycle.py +0 -0
- {dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_workflow_refs.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dominus-sdk-python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.0
|
|
4
4
|
Summary: Python SDK for the Dominus gateway-first platform
|
|
5
5
|
Author-email: CareBridge Systems <dev@carebridge.io>
|
|
6
6
|
License: Proprietary
|
|
@@ -198,7 +198,7 @@ JWT and selected scope headers directly through Gateway.
|
|
|
198
198
|
| `jobs` | Job Worker | Enqueue, poll, dead-letter management |
|
|
199
199
|
| `processor` | Processor | Batch and single-job processing |
|
|
200
200
|
| `sync` | Sync Worker | KV synchronization |
|
|
201
|
-
| `authority` | Dominus Authority | Runs,
|
|
201
|
+
| `authority` | Dominus Authority | Runs, provisioning targets, deploys, managed clients, context |
|
|
202
202
|
| `browser` | Browser Worker | Browser run health, ensure/start/status/result/retry/nudge/cancel/timeline/dossier |
|
|
203
203
|
| `deployer` | Deployer | Thin operator control-plane request surface |
|
|
204
204
|
| `warden` | Warden | Thin operator control-plane request surface |
|
|
@@ -164,7 +164,7 @@ JWT and selected scope headers directly through Gateway.
|
|
|
164
164
|
| `jobs` | Job Worker | Enqueue, poll, dead-letter management |
|
|
165
165
|
| `processor` | Processor | Batch and single-job processing |
|
|
166
166
|
| `sync` | Sync Worker | KV synchronization |
|
|
167
|
-
| `authority` | Dominus Authority | Runs,
|
|
167
|
+
| `authority` | Dominus Authority | Runs, provisioning targets, deploys, managed clients, context |
|
|
168
168
|
| `browser` | Browser Worker | Browser run health, ensure/start/status/result/retry/nudge/cancel/timeline/dossier |
|
|
169
169
|
| `deployer` | Deployer | Thin operator control-plane request surface |
|
|
170
170
|
| `warden` | Warden | Thin operator control-plane request surface |
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Authority Namespace - Dominus Authority service surface.
|
|
3
3
|
|
|
4
4
|
Canonical SDK entry point for the dominus-authority service. Mirrors the MCP
|
|
5
|
-
``authority_*`` tool surface so application code can drive runs,
|
|
6
|
-
deploys, managed clients, timelines, dossiers, and Authority context resolution
|
|
5
|
+
``authority_*`` tool surface so application code can drive runs, provisioning
|
|
6
|
+
targets, deploys, managed clients, timelines, dossiers, and Authority context resolution
|
|
7
7
|
without touching workflow-manager / client-worker / deploy-worker routes
|
|
8
8
|
directly.
|
|
9
9
|
|
|
@@ -44,8 +44,8 @@ def _normalize_run_kind_token(raw: Optional[str]) -> str:
|
|
|
44
44
|
return s
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
def
|
|
48
|
-
return _normalize_run_kind_token(run_kind) == "
|
|
47
|
+
def _is_provisioning_bootstrap_run_kind(run_kind: Optional[str]) -> bool:
|
|
48
|
+
return _normalize_run_kind_token(run_kind) == "provisioning_bootstrap"
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
def _query_string(params: Mapping[str, Any]) -> str:
|
|
@@ -62,7 +62,7 @@ class AuthorityNamespace:
|
|
|
62
62
|
Usage::
|
|
63
63
|
|
|
64
64
|
await dominus.authority.ensure_run(workflow_id="...", subject="PCM47474562")
|
|
65
|
-
await dominus.authority.
|
|
65
|
+
await dominus.authority.list_provisioning_targets()
|
|
66
66
|
await dominus.authority.get_run_dossier(run_id)
|
|
67
67
|
"""
|
|
68
68
|
|
|
@@ -170,9 +170,8 @@ class AuthorityNamespace:
|
|
|
170
170
|
workflow_id: Optional[str] = None,
|
|
171
171
|
workflow_ref: Optional[str] = None,
|
|
172
172
|
run_kind: Optional[str] = None,
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
slug: Optional[str] = None,
|
|
173
|
+
bootstrap_profile_ref: Optional[str] = None,
|
|
174
|
+
provisioning_target_slug: Optional[str] = None,
|
|
176
175
|
instance_id: Optional[str] = None,
|
|
177
176
|
instance_key: Optional[str] = None,
|
|
178
177
|
group: Optional[str] = None,
|
|
@@ -209,22 +208,20 @@ class AuthorityNamespace:
|
|
|
209
208
|
|
|
210
209
|
Calls ``POST /api/authority/runs/ensure``.
|
|
211
210
|
|
|
212
|
-
For
|
|
213
|
-
``
|
|
214
|
-
``
|
|
211
|
+
For provisioning bootstrap, pass ``run_kind="provisioning.bootstrap"`` plus
|
|
212
|
+
``provisioning_target_slug``. Optional bootstrap fields mirror
|
|
213
|
+
``bootstrap_provisioning_target`` (``execution_mode``, ``region``, ``bootstrap_profile_ref``, ...).
|
|
215
214
|
"""
|
|
216
|
-
bootstrap =
|
|
215
|
+
bootstrap = _is_provisioning_bootstrap_run_kind(run_kind)
|
|
217
216
|
if not bootstrap and not workflow_id and not workflow_ref:
|
|
218
217
|
raise ValueError(
|
|
219
218
|
"ensure_run requires workflow_id or workflow_ref unless run_kind is "
|
|
220
|
-
"
|
|
219
|
+
"provisioning.bootstrap"
|
|
221
220
|
)
|
|
222
221
|
if bootstrap:
|
|
223
|
-
|
|
224
|
-
if not
|
|
225
|
-
raise ValueError(
|
|
226
|
-
"ensure_run with run_kind company.bootstrap requires company, company_slug, or slug"
|
|
227
|
-
)
|
|
222
|
+
target_slug = (provisioning_target_slug or "").strip()
|
|
223
|
+
if not target_slug:
|
|
224
|
+
raise ValueError("ensure_run with run_kind provisioning.bootstrap requires provisioning_target_slug")
|
|
228
225
|
if mode == "streaming":
|
|
229
226
|
raise ValueError(
|
|
230
227
|
"Authority runs do not support streaming mode; "
|
|
@@ -237,7 +234,8 @@ class AuthorityNamespace:
|
|
|
237
234
|
if bootstrap:
|
|
238
235
|
body = _compact({
|
|
239
236
|
"run_kind": run_kind,
|
|
240
|
-
"
|
|
237
|
+
"bootstrap_profile_ref": bootstrap_profile_ref,
|
|
238
|
+
"provisioning_target_slug": provisioning_target_slug,
|
|
241
239
|
"workflow_id": workflow_id,
|
|
242
240
|
"workflow_ref": workflow_ref,
|
|
243
241
|
"instance_id": instance_id,
|
|
@@ -245,9 +243,6 @@ class AuthorityNamespace:
|
|
|
245
243
|
"group": group,
|
|
246
244
|
"owner": owner,
|
|
247
245
|
"subject": subject,
|
|
248
|
-
"company": company,
|
|
249
|
-
"company_slug": company_slug,
|
|
250
|
-
"slug": slug,
|
|
251
246
|
"bindings": bindings,
|
|
252
247
|
"inputs": inputs,
|
|
253
248
|
"context": context,
|
|
@@ -269,7 +264,6 @@ class AuthorityNamespace:
|
|
|
269
264
|
body = _compact({
|
|
270
265
|
"workflow_id": workflow_id,
|
|
271
266
|
"workflow_ref": workflow_ref,
|
|
272
|
-
"bootstrap_profile": bootstrap_profile,
|
|
273
267
|
"instance_id": instance_id,
|
|
274
268
|
"instance_key": instance_key,
|
|
275
269
|
"group": group,
|
|
@@ -779,13 +773,13 @@ class AuthorityNamespace:
|
|
|
779
773
|
)
|
|
780
774
|
|
|
781
775
|
# ==================================================================
|
|
782
|
-
#
|
|
776
|
+
# Provisioning Targets
|
|
783
777
|
# ==================================================================
|
|
784
778
|
|
|
785
|
-
async def
|
|
779
|
+
async def create_provisioning_target(
|
|
786
780
|
self,
|
|
787
781
|
*,
|
|
788
|
-
|
|
782
|
+
provisioning_target_slug: str,
|
|
789
783
|
display_name: Optional[str] = None,
|
|
790
784
|
description: Optional[str] = None,
|
|
791
785
|
bootstrap_status: Optional[str] = None,
|
|
@@ -794,34 +788,43 @@ class AuthorityNamespace:
|
|
|
794
788
|
app_slug: Optional[str] = None,
|
|
795
789
|
env: Optional[str] = None,
|
|
796
790
|
target_org_id: Optional[str] = None,
|
|
791
|
+
target_app_slug: Optional[str] = None,
|
|
797
792
|
target_env: Optional[str] = None,
|
|
793
|
+
shared_app_slug: Optional[str] = None,
|
|
798
794
|
initiator_type: Optional[str] = None,
|
|
799
795
|
initiator_id: Optional[str] = None,
|
|
800
796
|
idempotency_key: Optional[str] = None,
|
|
801
797
|
timeout: Optional[float] = None,
|
|
802
798
|
) -> Dict[str, Any]:
|
|
803
|
-
"""Create a new
|
|
804
|
-
if not
|
|
805
|
-
raise ValueError("
|
|
799
|
+
"""Create a new provisioning target. ``POST /api/authority/provisioning-targets``."""
|
|
800
|
+
if not provisioning_target_slug:
|
|
801
|
+
raise ValueError("create_provisioning_target requires provisioning_target_slug")
|
|
806
802
|
body = _compact({
|
|
807
|
-
"
|
|
803
|
+
"provisioning_target_slug": provisioning_target_slug,
|
|
808
804
|
"display_name": display_name,
|
|
809
805
|
"description": description,
|
|
810
806
|
"bootstrap_status": bootstrap_status,
|
|
811
807
|
"bootstrap_run_id": bootstrap_run_id,
|
|
812
808
|
"metadata": metadata,
|
|
813
809
|
**self._initiator(initiator_type, initiator_id, idempotency_key),
|
|
814
|
-
**self._scope(
|
|
810
|
+
**self._scope(
|
|
811
|
+
app_slug,
|
|
812
|
+
env,
|
|
813
|
+
target_org_id,
|
|
814
|
+
target_env,
|
|
815
|
+
target_app_slug=target_app_slug,
|
|
816
|
+
shared_app_slug=shared_app_slug,
|
|
817
|
+
),
|
|
815
818
|
})
|
|
816
819
|
return await self._post(
|
|
817
|
-
"/api/authority/
|
|
820
|
+
"/api/authority/provisioning-targets",
|
|
818
821
|
body,
|
|
819
822
|
timeout=self._http_timeout(timeout, 30.0),
|
|
820
823
|
)
|
|
821
824
|
|
|
822
|
-
async def
|
|
825
|
+
async def get_provisioning_target(
|
|
823
826
|
self,
|
|
824
|
-
|
|
827
|
+
provisioning_target_slug: str,
|
|
825
828
|
*,
|
|
826
829
|
app_slug: Optional[str] = None,
|
|
827
830
|
env: Optional[str] = None,
|
|
@@ -829,9 +832,9 @@ class AuthorityNamespace:
|
|
|
829
832
|
target_env: Optional[str] = None,
|
|
830
833
|
timeout: Optional[float] = None,
|
|
831
834
|
) -> Dict[str, Any]:
|
|
832
|
-
"""Get an Authority
|
|
833
|
-
if not
|
|
834
|
-
raise ValueError("
|
|
835
|
+
"""Get an Authority provisioning target. ``GET /api/authority/provisioning-targets/{provisioning_target_slug}``."""
|
|
836
|
+
if not provisioning_target_slug:
|
|
837
|
+
raise ValueError("provisioning_target_slug is required")
|
|
835
838
|
tid, tev = self._target_query_params(target_org_id, target_env)
|
|
836
839
|
qs = _query_string({
|
|
837
840
|
"app_slug": app_slug,
|
|
@@ -840,11 +843,11 @@ class AuthorityNamespace:
|
|
|
840
843
|
"target_env": tev,
|
|
841
844
|
})
|
|
842
845
|
return await self._get(
|
|
843
|
-
f"/api/authority/
|
|
846
|
+
f"/api/authority/provisioning-targets/{quote(provisioning_target_slug, safe='')}{qs}",
|
|
844
847
|
timeout=self._http_timeout(timeout, 30.0),
|
|
845
848
|
)
|
|
846
849
|
|
|
847
|
-
async def
|
|
850
|
+
async def list_provisioning_targets(
|
|
848
851
|
self,
|
|
849
852
|
*,
|
|
850
853
|
status: Optional[str] = None,
|
|
@@ -856,7 +859,7 @@ class AuthorityNamespace:
|
|
|
856
859
|
offset: int = 0,
|
|
857
860
|
timeout: Optional[float] = None,
|
|
858
861
|
) -> Dict[str, Any]:
|
|
859
|
-
"""List Authority
|
|
862
|
+
"""List Authority provisioning targets. ``GET /api/authority/provisioning-targets``."""
|
|
860
863
|
tid, tev = self._target_query_params(target_org_id, target_env)
|
|
861
864
|
qs = _query_string({
|
|
862
865
|
"app_slug": app_slug,
|
|
@@ -868,18 +871,18 @@ class AuthorityNamespace:
|
|
|
868
871
|
"offset": offset,
|
|
869
872
|
})
|
|
870
873
|
return await self._get(
|
|
871
|
-
f"/api/authority/
|
|
874
|
+
f"/api/authority/provisioning-targets{qs}",
|
|
872
875
|
timeout=self._http_timeout(timeout, 30.0),
|
|
873
876
|
)
|
|
874
877
|
|
|
875
|
-
async def
|
|
878
|
+
async def bootstrap_provisioning_target(
|
|
876
879
|
self,
|
|
877
|
-
|
|
880
|
+
provisioning_target_slug: str,
|
|
878
881
|
*,
|
|
879
882
|
action: Optional[str] = None,
|
|
880
883
|
run_id: Optional[str] = None,
|
|
881
884
|
reason: Optional[str] = None,
|
|
882
|
-
|
|
885
|
+
bootstrap_profile_ref: Optional[str] = None,
|
|
883
886
|
shared_app_slug: Optional[str] = None,
|
|
884
887
|
region: Optional[str] = None,
|
|
885
888
|
system: Optional[str] = None,
|
|
@@ -902,14 +905,14 @@ class AuthorityNamespace:
|
|
|
902
905
|
idempotency_key: Optional[str] = None,
|
|
903
906
|
timeout: Optional[float] = None,
|
|
904
907
|
) -> Dict[str, Any]:
|
|
905
|
-
"""Trigger or replay
|
|
906
|
-
if not
|
|
907
|
-
raise ValueError("
|
|
908
|
+
"""Trigger or replay provisioning target bootstrap. ``POST /api/authority/provisioning-targets/{provisioning_target_slug}/bootstrap``."""
|
|
909
|
+
if not provisioning_target_slug:
|
|
910
|
+
raise ValueError("provisioning_target_slug is required")
|
|
908
911
|
body = _compact({
|
|
909
912
|
"action": action,
|
|
910
913
|
"run_id": run_id,
|
|
911
914
|
"reason": reason,
|
|
912
|
-
"
|
|
915
|
+
"bootstrap_profile_ref": bootstrap_profile_ref,
|
|
913
916
|
"shared_app_slug": shared_app_slug,
|
|
914
917
|
"region": region,
|
|
915
918
|
"system": system,
|
|
@@ -933,36 +936,36 @@ class AuthorityNamespace:
|
|
|
933
936
|
),
|
|
934
937
|
})
|
|
935
938
|
return await self._post(
|
|
936
|
-
f"/api/authority/
|
|
939
|
+
f"/api/authority/provisioning-targets/{quote(provisioning_target_slug, safe='')}/bootstrap",
|
|
937
940
|
body,
|
|
938
941
|
timeout=self._http_timeout(timeout, 60.0),
|
|
939
942
|
)
|
|
940
943
|
|
|
941
|
-
async def
|
|
944
|
+
async def get_provisioning_target_bootstrap(
|
|
942
945
|
self,
|
|
943
|
-
|
|
946
|
+
provisioning_target_slug: str,
|
|
944
947
|
*,
|
|
945
948
|
run_id: Optional[str] = None,
|
|
946
949
|
app_slug: Optional[str] = None,
|
|
947
950
|
env: Optional[str] = None,
|
|
948
951
|
timeout: Optional[float] = None,
|
|
949
952
|
) -> Dict[str, Any]:
|
|
950
|
-
"""Get
|
|
951
|
-
if not
|
|
952
|
-
raise ValueError("
|
|
953
|
+
"""Get provisioning target bootstrap state. ``GET /api/authority/provisioning-targets/{provisioning_target_slug}/bootstrap``."""
|
|
954
|
+
if not provisioning_target_slug:
|
|
955
|
+
raise ValueError("provisioning_target_slug is required")
|
|
953
956
|
qs = _query_string({
|
|
954
957
|
"app_slug": app_slug,
|
|
955
958
|
"env": env,
|
|
956
959
|
"run_id": run_id,
|
|
957
960
|
})
|
|
958
961
|
return await self._get(
|
|
959
|
-
f"/api/authority/
|
|
962
|
+
f"/api/authority/provisioning-targets/{quote(provisioning_target_slug, safe='')}/bootstrap{qs}",
|
|
960
963
|
timeout=self._http_timeout(timeout, 30.0),
|
|
961
964
|
)
|
|
962
965
|
|
|
963
|
-
async def
|
|
966
|
+
async def get_provisioning_target_dossier(
|
|
964
967
|
self,
|
|
965
|
-
|
|
968
|
+
provisioning_target_slug: str,
|
|
966
969
|
*,
|
|
967
970
|
app_slug: Optional[str] = None,
|
|
968
971
|
env: Optional[str] = None,
|
|
@@ -974,9 +977,9 @@ class AuthorityNamespace:
|
|
|
974
977
|
limit: Optional[int] = None,
|
|
975
978
|
timeout: Optional[float] = None,
|
|
976
979
|
) -> Dict[str, Any]:
|
|
977
|
-
"""Get full Authority dossier for a
|
|
978
|
-
if not
|
|
979
|
-
raise ValueError("
|
|
980
|
+
"""Get full Authority dossier for a provisioning target. ``GET /api/authority/dossiers/provisioning-target/{provisioning_target_slug}``."""
|
|
981
|
+
if not provisioning_target_slug:
|
|
982
|
+
raise ValueError("provisioning_target_slug is required")
|
|
980
983
|
tid, tev = self._target_query_params(target_org_id, target_env)
|
|
981
984
|
qs = _query_string({
|
|
982
985
|
"app_slug": app_slug,
|
|
@@ -989,7 +992,7 @@ class AuthorityNamespace:
|
|
|
989
992
|
"limit": limit,
|
|
990
993
|
})
|
|
991
994
|
return await self._get(
|
|
992
|
-
f"/api/authority/dossiers/
|
|
995
|
+
f"/api/authority/dossiers/provisioning-target/{quote(provisioning_target_slug, safe='')}{qs}",
|
|
993
996
|
timeout=self._http_timeout(timeout, 30.0),
|
|
994
997
|
)
|
|
995
998
|
|
|
@@ -104,6 +104,29 @@ class RecipesNamespace:
|
|
|
104
104
|
timeout=timeout,
|
|
105
105
|
)
|
|
106
106
|
|
|
107
|
+
async def deprecate(
|
|
108
|
+
self,
|
|
109
|
+
*,
|
|
110
|
+
type: str,
|
|
111
|
+
tier: str,
|
|
112
|
+
name: str,
|
|
113
|
+
version: int,
|
|
114
|
+
reason: Optional[str] = None,
|
|
115
|
+
timeout: float = 30.0,
|
|
116
|
+
) -> Dict[str, Any]:
|
|
117
|
+
"""Mark the current head recipe version deprecated. ``POST /api/recipe/recipes/deprecate``."""
|
|
118
|
+
return await self._post(
|
|
119
|
+
"/api/recipe/recipes/deprecate",
|
|
120
|
+
_compact({
|
|
121
|
+
"type": type,
|
|
122
|
+
"tier": tier,
|
|
123
|
+
"name": name,
|
|
124
|
+
"version": version,
|
|
125
|
+
"reason": reason,
|
|
126
|
+
}),
|
|
127
|
+
timeout=timeout,
|
|
128
|
+
)
|
|
129
|
+
|
|
107
130
|
async def list(
|
|
108
131
|
self,
|
|
109
132
|
*,
|
|
@@ -168,7 +168,7 @@ class Dominus:
|
|
|
168
168
|
from .namespaces.sync import SyncNamespace
|
|
169
169
|
self.sync = SyncNamespace(self)
|
|
170
170
|
|
|
171
|
-
# Authority service (runs,
|
|
171
|
+
# Authority service (runs, provisioning targets, deploys, managed clients, dossiers)
|
|
172
172
|
from .namespaces.authority import AuthorityNamespace
|
|
173
173
|
self.authority = AuthorityNamespace(self)
|
|
174
174
|
|
|
@@ -186,7 +186,7 @@ class Dominus:
|
|
|
186
186
|
from .namespaces.stash import StashNamespace
|
|
187
187
|
self.stash = StashNamespace(self)
|
|
188
188
|
|
|
189
|
-
# Recipe worker (kernel-tier; hosts browser-recipe
|
|
189
|
+
# Recipe worker (kernel-tier; hosts browser-recipe today, workflow + envoy + others later)
|
|
190
190
|
from .namespaces.recipes import RecipesNamespace
|
|
191
191
|
self.recipes = RecipesNamespace(self)
|
|
192
192
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dominus-sdk-python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.0
|
|
4
4
|
Summary: Python SDK for the Dominus gateway-first platform
|
|
5
5
|
Author-email: CareBridge Systems <dev@carebridge.io>
|
|
6
6
|
License: Proprietary
|
|
@@ -198,7 +198,7 @@ JWT and selected scope headers directly through Gateway.
|
|
|
198
198
|
| `jobs` | Job Worker | Enqueue, poll, dead-letter management |
|
|
199
199
|
| `processor` | Processor | Batch and single-job processing |
|
|
200
200
|
| `sync` | Sync Worker | KV synchronization |
|
|
201
|
-
| `authority` | Dominus Authority | Runs,
|
|
201
|
+
| `authority` | Dominus Authority | Runs, provisioning targets, deploys, managed clients, context |
|
|
202
202
|
| `browser` | Browser Worker | Browser run health, ensure/start/status/result/retry/nudge/cancel/timeline/dossier |
|
|
203
203
|
| `deployer` | Deployer | Thin operator control-plane request surface |
|
|
204
204
|
| `warden` | Warden | Thin operator control-plane request surface |
|
{dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_authority_public_vocabulary.py
RENAMED
|
@@ -73,7 +73,7 @@ class FakeMintClient:
|
|
|
73
73
|
|
|
74
74
|
def test_authority_scope_signatures_use_new_public_vocabulary():
|
|
75
75
|
ensure_sig = inspect.signature(AuthorityNamespace.ensure_run)
|
|
76
|
-
bootstrap_sig = inspect.signature(AuthorityNamespace.
|
|
76
|
+
bootstrap_sig = inspect.signature(AuthorityNamespace.bootstrap_provisioning_target)
|
|
77
77
|
release_sig = inspect.signature(AuthorityNamespace.publish_client_release)
|
|
78
78
|
context_sig = inspect.signature(AuthorityNamespace.context_resolve)
|
|
79
79
|
timeline_sig = inspect.signature(AuthorityNamespace.get_run_timeline)
|
|
@@ -86,14 +86,17 @@ def test_authority_scope_signatures_use_new_public_vocabulary():
|
|
|
86
86
|
schedule_create_sig = inspect.signature(AuthorityNamespace.create_schedule)
|
|
87
87
|
mint_sig = inspect.signature(core_helpers.mint_selected_scope_jwt)
|
|
88
88
|
|
|
89
|
-
for name in ("app_slug", "env", "target_org_id", "target_env", "run_kind", "target_app_slug", "
|
|
89
|
+
for name in ("app_slug", "env", "target_org_id", "target_env", "run_kind", "target_app_slug", "bootstrap_profile_ref", "provisioning_target_slug"):
|
|
90
90
|
assert name in ensure_sig.parameters
|
|
91
|
-
|
|
91
|
+
old_profile_key = "bootstrap" + "_profile"
|
|
92
|
+
for legacy in ("project_slug", "environment", "target_project_id", "target_environment", old_profile_key):
|
|
92
93
|
assert legacy not in ensure_sig.parameters
|
|
93
94
|
|
|
94
|
-
for name in ("shared_app_slug", "target_app_slug", "target_env", "
|
|
95
|
+
for name in ("shared_app_slug", "target_app_slug", "target_env", "bootstrap_profile_ref"):
|
|
95
96
|
assert name in bootstrap_sig.parameters
|
|
96
|
-
|
|
97
|
+
old_target_key = "company" + "_slug"
|
|
98
|
+
for legacy in ("shared_project_slug", old_profile_key, old_target_key):
|
|
99
|
+
assert legacy not in bootstrap_sig.parameters
|
|
97
100
|
|
|
98
101
|
for name in ("storage_app_slug", "storage_env", "app_slug", "env"):
|
|
99
102
|
assert name in release_sig.parameters
|
|
@@ -137,16 +140,15 @@ async def test_authority_scope_methods_use_canonical_context_wire_names():
|
|
|
137
140
|
env="production",
|
|
138
141
|
target_org_id="org-123",
|
|
139
142
|
target_env="production",
|
|
140
|
-
bootstrap_profile="carebridge_company_v1",
|
|
141
143
|
)
|
|
142
|
-
await namespace.
|
|
144
|
+
await namespace.bootstrap_provisioning_target(
|
|
143
145
|
"summit-radiology",
|
|
144
146
|
shared_app_slug="shared-core",
|
|
145
147
|
app_slug="carebridge",
|
|
146
148
|
env="production",
|
|
147
149
|
target_app_slug="carebridge",
|
|
148
150
|
target_env="production",
|
|
149
|
-
|
|
151
|
+
bootstrap_profile_ref="recipe://bootstrap-profile-v1/default@head",
|
|
150
152
|
)
|
|
151
153
|
await namespace.publish_client_release(
|
|
152
154
|
variant_slug="desktop",
|
|
@@ -179,7 +181,7 @@ async def test_authority_scope_methods_use_canonical_context_wire_names():
|
|
|
179
181
|
window_hours=24,
|
|
180
182
|
limit=150,
|
|
181
183
|
)
|
|
182
|
-
await namespace.
|
|
184
|
+
await namespace.get_provisioning_target_dossier(
|
|
183
185
|
"summit-radiology",
|
|
184
186
|
app_slug="carebridge",
|
|
185
187
|
env="production",
|
|
@@ -253,14 +255,14 @@ async def test_authority_scope_methods_use_canonical_context_wire_names():
|
|
|
253
255
|
assert ensure_body["env"] == "production"
|
|
254
256
|
assert ensure_body["target_org_id"] == "org-123"
|
|
255
257
|
assert ensure_body["target_env"] == "production"
|
|
256
|
-
assert
|
|
258
|
+
assert "bootstrap_profile_ref" not in ensure_body
|
|
257
259
|
|
|
258
260
|
bootstrap_body = client.calls[1]["body"]
|
|
259
261
|
assert bootstrap_body["shared_app_slug"] == "shared-core"
|
|
260
262
|
assert bootstrap_body["app_slug"] == "carebridge"
|
|
261
263
|
assert bootstrap_body["target_app_slug"] == "carebridge"
|
|
262
264
|
assert bootstrap_body["target_env"] == "production"
|
|
263
|
-
assert bootstrap_body["
|
|
265
|
+
assert bootstrap_body["bootstrap_profile_ref"] == "recipe://bootstrap-profile-v1/default@head"
|
|
264
266
|
|
|
265
267
|
release_body = client.calls[2]["body"]
|
|
266
268
|
assert release_body["storage_app_slug"] == "storage-core"
|
|
@@ -284,7 +286,7 @@ async def test_authority_scope_methods_use_canonical_context_wire_names():
|
|
|
284
286
|
"since=2026-04-11T08%3A33%3A00Z&until=2026-04-11T09%3A33%3A00Z&window_hours=24&limit=150"
|
|
285
287
|
)
|
|
286
288
|
assert client.calls[6]["endpoint"] == (
|
|
287
|
-
"/api/authority/dossiers/
|
|
289
|
+
"/api/authority/dossiers/provisioning-target/summit-radiology?"
|
|
288
290
|
"app_slug=carebridge&env=production&target_org_id=target-org-1&target_env=production"
|
|
289
291
|
"&since=2026-04-11T08%3A33%3A00Z&until=2026-04-11T09%3A33%3A00Z&window_hours=24&limit=150"
|
|
290
292
|
)
|
|
@@ -351,6 +353,46 @@ async def test_authority_scope_methods_use_canonical_context_wire_names():
|
|
|
351
353
|
assert client.calls[18]["endpoint"] == "/api/authority/schedules/demo.hourly/runs/run-2/fail"
|
|
352
354
|
|
|
353
355
|
|
|
356
|
+
@pytest.mark.asyncio
|
|
357
|
+
async def test_authority_provisioning_target_helpers_use_final_routes_and_payload_keys():
|
|
358
|
+
client = FakeClient()
|
|
359
|
+
namespace = AuthorityNamespace(client)
|
|
360
|
+
|
|
361
|
+
await namespace.create_provisioning_target(
|
|
362
|
+
provisioning_target_slug="summit-radiology",
|
|
363
|
+
app_slug="carebridge",
|
|
364
|
+
env="production",
|
|
365
|
+
target_app_slug="carebridge",
|
|
366
|
+
target_env="production",
|
|
367
|
+
shared_app_slug="carebridge-platform",
|
|
368
|
+
)
|
|
369
|
+
await namespace.get_provisioning_target(
|
|
370
|
+
"summit-radiology",
|
|
371
|
+
app_slug="carebridge",
|
|
372
|
+
env="production",
|
|
373
|
+
)
|
|
374
|
+
await namespace.list_provisioning_targets(app_slug="carebridge", env="production", limit=25)
|
|
375
|
+
await namespace.bootstrap_provisioning_target(
|
|
376
|
+
"summit-radiology",
|
|
377
|
+
action="start",
|
|
378
|
+
bootstrap_profile_ref="recipe://bootstrap-profile-v1/default@head",
|
|
379
|
+
execution_mode="async",
|
|
380
|
+
)
|
|
381
|
+
await namespace.get_provisioning_target_bootstrap(
|
|
382
|
+
"summit-radiology",
|
|
383
|
+
run_id="provisioning-run::run-1",
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
assert client.calls[0]["endpoint"] == "/api/authority/provisioning-targets"
|
|
387
|
+
assert client.calls[0]["body"]["provisioning_target_slug"] == "summit-radiology"
|
|
388
|
+
assert client.calls[0]["body"]["target_app_slug"] == "carebridge"
|
|
389
|
+
assert client.calls[1]["endpoint"] == "/api/authority/provisioning-targets/summit-radiology?app_slug=carebridge&env=production"
|
|
390
|
+
assert client.calls[2]["endpoint"] == "/api/authority/provisioning-targets?app_slug=carebridge&env=production&limit=25&offset=0"
|
|
391
|
+
assert client.calls[3]["endpoint"] == "/api/authority/provisioning-targets/summit-radiology/bootstrap"
|
|
392
|
+
assert client.calls[3]["body"]["bootstrap_profile_ref"] == "recipe://bootstrap-profile-v1/default@head"
|
|
393
|
+
assert client.calls[4]["endpoint"] == "/api/authority/provisioning-targets/summit-radiology/bootstrap?run_id=provisioning-run%3A%3Arun-1"
|
|
394
|
+
|
|
395
|
+
|
|
354
396
|
@pytest.mark.asyncio
|
|
355
397
|
async def test_selected_scope_mint_helper_uses_new_public_names_and_route_canonical_mint_payload(monkeypatch):
|
|
356
398
|
FakeMintClient.instances.clear()
|
|
@@ -414,35 +456,35 @@ async def test_list_runs_keeps_target_query_when_org_differs_from_gateway():
|
|
|
414
456
|
|
|
415
457
|
|
|
416
458
|
@pytest.mark.asyncio
|
|
417
|
-
async def
|
|
459
|
+
async def test_authority_ensure_run_provisioning_bootstrap_omits_workflow_mode():
|
|
418
460
|
client = FakeClient()
|
|
419
461
|
namespace = AuthorityNamespace(client)
|
|
420
462
|
await namespace.ensure_run(
|
|
421
|
-
run_kind="
|
|
422
|
-
|
|
463
|
+
run_kind="provisioning.bootstrap",
|
|
464
|
+
provisioning_target_slug="acme-corp",
|
|
423
465
|
app_slug="carebridge",
|
|
424
466
|
env="production",
|
|
425
467
|
target_org_id="org-1",
|
|
426
468
|
execution_mode="async",
|
|
427
469
|
shared_app_slug="shared-core",
|
|
428
|
-
|
|
470
|
+
bootstrap_profile_ref="recipe://bootstrap-profile-v1/default@head",
|
|
429
471
|
)
|
|
430
472
|
body = client.calls[0]["body"]
|
|
431
|
-
assert body["run_kind"] == "
|
|
432
|
-
assert body["
|
|
473
|
+
assert body["run_kind"] == "provisioning.bootstrap"
|
|
474
|
+
assert body["provisioning_target_slug"] == "acme-corp"
|
|
433
475
|
assert body["execution_mode"] == "async"
|
|
434
476
|
assert body["shared_app_slug"] == "shared-core"
|
|
435
|
-
assert body["
|
|
477
|
+
assert body["bootstrap_profile_ref"] == "recipe://bootstrap-profile-v1/default@head"
|
|
436
478
|
assert "mode" not in body
|
|
437
479
|
|
|
438
480
|
|
|
439
481
|
@pytest.mark.asyncio
|
|
440
|
-
async def
|
|
482
|
+
async def test_authority_ensure_run_bootstrap_requires_provisioning_target_slug():
|
|
441
483
|
client = FakeClient()
|
|
442
484
|
namespace = AuthorityNamespace(client)
|
|
443
|
-
with pytest.raises(ValueError, match="
|
|
485
|
+
with pytest.raises(ValueError, match="provisioning_target_slug"):
|
|
444
486
|
await namespace.ensure_run(
|
|
445
|
-
run_kind="
|
|
487
|
+
run_kind="provisioning.bootstrap",
|
|
446
488
|
app_slug="carebridge",
|
|
447
489
|
env="production",
|
|
448
490
|
)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
import dominus.start as start_module
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@pytest.fixture()
|
|
7
|
+
def sdk(monkeypatch):
|
|
8
|
+
monkeypatch.setattr(start_module, "_VALIDATION_ERROR", None)
|
|
9
|
+
monkeypatch.setattr(start_module, "_TOKEN", "a" * 64)
|
|
10
|
+
monkeypatch.setattr(start_module, "_VALIDATED", False)
|
|
11
|
+
monkeypatch.setattr(start_module, "_BASE_URL", "https://gateway.example")
|
|
12
|
+
monkeypatch.setattr(start_module, "_GATEWAY_URL", "https://gateway.example")
|
|
13
|
+
return start_module.Dominus()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@pytest.mark.asyncio
|
|
17
|
+
async def test_recipes_namespace_maps_deprecate_to_gateway_route(monkeypatch, sdk):
|
|
18
|
+
calls = []
|
|
19
|
+
|
|
20
|
+
async def fake_request(**kwargs):
|
|
21
|
+
calls.append(kwargs)
|
|
22
|
+
return {"ok": True, "recipe": {"deprecated": True}}
|
|
23
|
+
|
|
24
|
+
monkeypatch.setattr(sdk, "_request", fake_request)
|
|
25
|
+
|
|
26
|
+
result = await sdk.recipes.deprecate(
|
|
27
|
+
type="browser-recipe",
|
|
28
|
+
tier="project",
|
|
29
|
+
name="cms-login",
|
|
30
|
+
version=3,
|
|
31
|
+
reason="superseded",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
assert result["recipe"]["deprecated"] is True
|
|
35
|
+
assert calls == [
|
|
36
|
+
{
|
|
37
|
+
"endpoint": "/api/recipe/recipes/deprecate",
|
|
38
|
+
"method": "POST",
|
|
39
|
+
"body": {
|
|
40
|
+
"type": "browser-recipe",
|
|
41
|
+
"tier": "project",
|
|
42
|
+
"name": "cms-login",
|
|
43
|
+
"version": 3,
|
|
44
|
+
"reason": "superseded",
|
|
45
|
+
},
|
|
46
|
+
"use_gateway": True,
|
|
47
|
+
"timeout": 30.0,
|
|
48
|
+
}
|
|
49
|
+
]
|
|
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
|
{dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus_sdk_python.egg-info/requires.txt
RENAMED
|
File without changes
|
{dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/dominus_sdk_python.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-4.6.1 → dominus_sdk_python-5.0.0}/tests/test_control_plane_namespaces.py
RENAMED
|
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
|