dominus-sdk-python 5.0.0__tar.gz → 5.1.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-5.0.0 → dominus_sdk_python-5.1.0}/PKG-INFO +8 -2
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/README.md +7 -1
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/__init__.py +1 -7
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/artifacts.py +10 -27
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/workflow.py +40 -8
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus_sdk_python.egg-info/PKG-INFO +8 -2
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/pyproject.toml +1 -1
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_workflow_lifecycle.py +17 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_workflow_refs.py +42 -1
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/config/__init__.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/config/endpoints.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/errors.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/helpers/__init__.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/helpers/auth.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/helpers/cache.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/helpers/console_capture.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/helpers/core.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/helpers/crypto.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/helpers/sse.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/helpers/trace.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/__init__.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/admin.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/ai.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/auth.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/authority.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/browser.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/courier.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/db.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/ddl.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/deployer.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/fastapi.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/files.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/health.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/jobs.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/logs.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/portal.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/processor.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/recipes.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/redis.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/secrets.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/secure.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/stash.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/sync.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/namespaces/warden.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/services/__init__.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus/start.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus_sdk_python.egg-info/SOURCES.txt +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus_sdk_python.egg-info/dependency_links.txt +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus_sdk_python.egg-info/requires.txt +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus_sdk_python.egg-info/top_level.txt +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/setup.cfg +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_auth.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_authority_public_vocabulary.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_browser_namespace.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_control_plane_namespaces.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_errors.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_flat_commands.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_health.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_logs.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_provisioning_parity.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_public_exports.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_recipes_namespace.py +0 -0
- {dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_transport_compat.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dominus-sdk-python
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.1.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
|
|
@@ -43,7 +43,7 @@ Async Python SDK for the Dominus gateway-first service plane.
|
|
|
43
43
|
- Gateway-scoped client mode for MCP and other user-JWT sessions
|
|
44
44
|
- Transport compatibility for wrapped `{success,data}` responses and unwrapped Warden/control-plane success objects
|
|
45
45
|
- Local helpers for JWT verification, trace propagation, retries, and console capture
|
|
46
|
-
- Current package version: `
|
|
46
|
+
- Current package version: `5.1.0`
|
|
47
47
|
|
|
48
48
|
## Install
|
|
49
49
|
|
|
@@ -71,6 +71,12 @@ run = await dominus.workflow.ensure(
|
|
|
71
71
|
company="summit-radiology",
|
|
72
72
|
)
|
|
73
73
|
|
|
74
|
+
recipe_run = await dominus.workflow.ensure(
|
|
75
|
+
workflow_recipe_ref="recipe://workflow-recipe-v1/report-cycle@v3",
|
|
76
|
+
subject="PCM47474562",
|
|
77
|
+
company="summit-radiology",
|
|
78
|
+
)
|
|
79
|
+
|
|
74
80
|
timeline = await dominus.authority.get_run_timeline(
|
|
75
81
|
run["run_id"],
|
|
76
82
|
since="2026-04-11T08:33:00Z",
|
|
@@ -9,7 +9,7 @@ Async Python SDK for the Dominus gateway-first service plane.
|
|
|
9
9
|
- Gateway-scoped client mode for MCP and other user-JWT sessions
|
|
10
10
|
- Transport compatibility for wrapped `{success,data}` responses and unwrapped Warden/control-plane success objects
|
|
11
11
|
- Local helpers for JWT verification, trace propagation, retries, and console capture
|
|
12
|
-
- Current package version: `
|
|
12
|
+
- Current package version: `5.1.0`
|
|
13
13
|
|
|
14
14
|
## Install
|
|
15
15
|
|
|
@@ -37,6 +37,12 @@ run = await dominus.workflow.ensure(
|
|
|
37
37
|
company="summit-radiology",
|
|
38
38
|
)
|
|
39
39
|
|
|
40
|
+
recipe_run = await dominus.workflow.ensure(
|
|
41
|
+
workflow_recipe_ref="recipe://workflow-recipe-v1/report-cycle@v3",
|
|
42
|
+
subject="PCM47474562",
|
|
43
|
+
company="summit-radiology",
|
|
44
|
+
)
|
|
45
|
+
|
|
40
46
|
timeline = await dominus.authority.get_run_timeline(
|
|
41
47
|
run["run_id"],
|
|
42
48
|
since="2026-04-11T08:33:00Z",
|
|
@@ -90,14 +90,12 @@ from .namespaces.health import HealthNamespace
|
|
|
90
90
|
# Export new namespaces (Node.js SDK parity)
|
|
91
91
|
from .namespaces.artifacts import (
|
|
92
92
|
ARTIFACT_REF_PREFIX,
|
|
93
|
-
DISPLAY_REF_PREFIX,
|
|
94
93
|
ARTIFACT_ENVIRONMENTS,
|
|
95
94
|
ArtifactsNamespace,
|
|
96
95
|
build_artifact_ref,
|
|
97
96
|
build_v2_artifact_ref,
|
|
98
97
|
build_pinned_artifact_ref,
|
|
99
98
|
build_legacy_artifact_ref,
|
|
100
|
-
build_display_artifact_ref,
|
|
101
99
|
parse_artifact_ref,
|
|
102
100
|
try_parse_artifact_ref,
|
|
103
101
|
validate_artifact_address,
|
|
@@ -105,7 +103,6 @@ from .namespaces.artifacts import (
|
|
|
105
103
|
is_pinned_artifact_ref,
|
|
106
104
|
is_head_artifact_ref,
|
|
107
105
|
is_legacy_artifact_ref,
|
|
108
|
-
is_display_artifact_ref,
|
|
109
106
|
)
|
|
110
107
|
from .namespaces.jobs import JobsNamespace
|
|
111
108
|
from .namespaces.processor import ProcessorNamespace
|
|
@@ -165,7 +162,7 @@ from .errors import (
|
|
|
165
162
|
TimeoutError as DominusTimeoutError,
|
|
166
163
|
)
|
|
167
164
|
|
|
168
|
-
__version__ = "
|
|
165
|
+
__version__ = "5.1.0"
|
|
169
166
|
__all__ = [
|
|
170
167
|
# Main SDK instance
|
|
171
168
|
"dominus",
|
|
@@ -195,14 +192,12 @@ __all__ = [
|
|
|
195
192
|
"HealthNamespace",
|
|
196
193
|
# New namespaces (Node.js SDK parity)
|
|
197
194
|
"ARTIFACT_REF_PREFIX",
|
|
198
|
-
"DISPLAY_REF_PREFIX",
|
|
199
195
|
"ARTIFACT_ENVIRONMENTS",
|
|
200
196
|
"ArtifactsNamespace",
|
|
201
197
|
"build_artifact_ref",
|
|
202
198
|
"build_v2_artifact_ref",
|
|
203
199
|
"build_pinned_artifact_ref",
|
|
204
200
|
"build_legacy_artifact_ref",
|
|
205
|
-
"build_display_artifact_ref",
|
|
206
201
|
"parse_artifact_ref",
|
|
207
202
|
"try_parse_artifact_ref",
|
|
208
203
|
"validate_artifact_address",
|
|
@@ -210,7 +205,6 @@ __all__ = [
|
|
|
210
205
|
"is_pinned_artifact_ref",
|
|
211
206
|
"is_head_artifact_ref",
|
|
212
207
|
"is_legacy_artifact_ref",
|
|
213
|
-
"is_display_artifact_ref",
|
|
214
208
|
"JobsNamespace",
|
|
215
209
|
"ProcessorNamespace",
|
|
216
210
|
"SyncNamespace",
|
|
@@ -35,10 +35,13 @@ def _safe_string(value: Any) -> str:
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
ARTIFACT_REF_PREFIX = "ar://"
|
|
38
|
-
DISPLAY_REF_PREFIX = "art:r:"
|
|
39
38
|
ARTIFACT_ENVIRONMENTS = ("development", "staging", "production")
|
|
40
39
|
|
|
41
40
|
|
|
41
|
+
def _legacy_project_head_ref(project_id: str, environment: str, key: str) -> str:
|
|
42
|
+
return f"{ARTIFACT_REF_PREFIX}dominus/project:{project_id}/{environment}/legacy/{quote(key, safe='')}"
|
|
43
|
+
|
|
44
|
+
|
|
42
45
|
def build_artifact_ref(
|
|
43
46
|
*,
|
|
44
47
|
project_slug: Optional[str] = None,
|
|
@@ -109,13 +112,6 @@ def build_pinned_artifact_ref(
|
|
|
109
112
|
return f"{ref}@v{version}"
|
|
110
113
|
|
|
111
114
|
|
|
112
|
-
def build_display_artifact_ref(artifact_key: str) -> Optional[str]:
|
|
113
|
-
normalized_key = _safe_string(artifact_key)
|
|
114
|
-
if not normalized_key:
|
|
115
|
-
return None
|
|
116
|
-
return f"{DISPLAY_REF_PREFIX}{normalized_key}"
|
|
117
|
-
|
|
118
|
-
|
|
119
115
|
def build_legacy_artifact_ref(
|
|
120
116
|
*,
|
|
121
117
|
project_slug: str,
|
|
@@ -146,15 +142,6 @@ def parse_artifact_ref(artifact_ref: str) -> Optional[Dict[str, Any]]:
|
|
|
146
142
|
normalized = _safe_string(artifact_ref)
|
|
147
143
|
if not normalized:
|
|
148
144
|
return None
|
|
149
|
-
if normalized.startswith(DISPLAY_REF_PREFIX):
|
|
150
|
-
artifact_key = normalized[len(DISPLAY_REF_PREFIX):]
|
|
151
|
-
if not artifact_key:
|
|
152
|
-
return None
|
|
153
|
-
return {
|
|
154
|
-
"format": "display",
|
|
155
|
-
"raw": normalized,
|
|
156
|
-
"artifact_key": artifact_key,
|
|
157
|
-
}
|
|
158
145
|
if not normalized.startswith(ARTIFACT_REF_PREFIX):
|
|
159
146
|
return None
|
|
160
147
|
|
|
@@ -245,10 +232,6 @@ def is_legacy_artifact_ref(artifact_ref: Dict[str, Any]) -> bool:
|
|
|
245
232
|
return artifact_ref.get("format") == "v1"
|
|
246
233
|
|
|
247
234
|
|
|
248
|
-
def is_display_artifact_ref(artifact_ref: Dict[str, Any]) -> bool:
|
|
249
|
-
return artifact_ref.get("format") == "display"
|
|
250
|
-
|
|
251
|
-
|
|
252
235
|
def _split_version_suffix(value: str) -> tuple[str, Optional[str]]:
|
|
253
236
|
if "@" not in value:
|
|
254
237
|
return value, None
|
|
@@ -366,10 +349,10 @@ class ArtifactsNamespace:
|
|
|
366
349
|
category=category,
|
|
367
350
|
content_type=content_type,
|
|
368
351
|
)
|
|
369
|
-
|
|
352
|
+
fallback_ref = _legacy_project_head_ref(project_id, environment, use_key)
|
|
370
353
|
return {
|
|
371
354
|
"key": use_key,
|
|
372
|
-
"ref": v2.get("
|
|
355
|
+
"ref": v2.get("head_ref") or fallback_ref,
|
|
373
356
|
"storage_type": v2.get("storage_type") or "redis",
|
|
374
357
|
"size_bytes": v2.get("size_bytes", 0),
|
|
375
358
|
"expires_at": v2.get("expires_at") or "",
|
|
@@ -377,14 +360,14 @@ class ArtifactsNamespace:
|
|
|
377
360
|
|
|
378
361
|
async def retrieve(self, key: str) -> Dict[str, Any]:
|
|
379
362
|
"""
|
|
380
|
-
Retrieve by key via
|
|
363
|
+
Retrieve by key via the addressed V2 compatibility head.
|
|
381
364
|
"""
|
|
382
|
-
project_id,
|
|
365
|
+
project_id, environment = await self._legacy_project_context()
|
|
366
|
+
ref = _legacy_project_head_ref(project_id, environment, key)
|
|
383
367
|
return await self._api(
|
|
384
368
|
"/api/artifact/v2/retrieve",
|
|
385
369
|
body={
|
|
386
|
-
"ref":
|
|
387
|
-
"target_project_id": project_id,
|
|
370
|
+
"ref": ref,
|
|
388
371
|
},
|
|
389
372
|
)
|
|
390
373
|
|
|
@@ -104,6 +104,14 @@ class WorkflowNamespace:
|
|
|
104
104
|
return {"workflow_id": str(workflow_id).strip()}
|
|
105
105
|
raise ValueError("workflow_id or workflow_ref is required")
|
|
106
106
|
|
|
107
|
+
@staticmethod
|
|
108
|
+
def _is_workflow_recipe_ref(value: Optional[str]) -> bool:
|
|
109
|
+
return str(value or "").strip().startswith("recipe://workflow-recipe-v1/")
|
|
110
|
+
|
|
111
|
+
@staticmethod
|
|
112
|
+
def _is_pipeline_recipe_ref(value: Optional[str]) -> bool:
|
|
113
|
+
return str(value or "").strip().startswith("recipe://pipeline-recipe-v1/")
|
|
114
|
+
|
|
107
115
|
@staticmethod
|
|
108
116
|
def _instance_base_endpoint(workflow_id: str) -> str:
|
|
109
117
|
from urllib.parse import quote
|
|
@@ -210,9 +218,11 @@ class WorkflowNamespace:
|
|
|
210
218
|
|
|
211
219
|
def _build_authority_ensure_body(
|
|
212
220
|
self,
|
|
213
|
-
workflow_id: str,
|
|
221
|
+
workflow_id: Optional[str] = None,
|
|
214
222
|
*,
|
|
215
223
|
workflow_ref: Optional[str] = None,
|
|
224
|
+
workflow_recipe_ref: Optional[str] = None,
|
|
225
|
+
pipeline_recipe_ref: Optional[str] = None,
|
|
216
226
|
subject: Optional[str] = None,
|
|
217
227
|
company: Optional[str] = None,
|
|
218
228
|
inputs: Optional[Dict[str, Any]] = None,
|
|
@@ -227,12 +237,30 @@ class WorkflowNamespace:
|
|
|
227
237
|
idempotency_key: Optional[str] = None,
|
|
228
238
|
) -> Dict[str, Any]:
|
|
229
239
|
body: Dict[str, Any] = {"mode": mode}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
240
|
+
launch_sources: List[tuple[str, str]] = []
|
|
241
|
+
normalized_workflow_id = str(workflow_id or "").strip()
|
|
242
|
+
if workflow_ref and str(workflow_ref).strip():
|
|
243
|
+
launch_sources.append(("workflow_ref", str(workflow_ref).strip()))
|
|
244
|
+
if workflow_recipe_ref and str(workflow_recipe_ref).strip():
|
|
245
|
+
launch_sources.append(("workflow_recipe_ref", str(workflow_recipe_ref).strip()))
|
|
246
|
+
if pipeline_recipe_ref and str(pipeline_recipe_ref).strip():
|
|
247
|
+
launch_sources.append(("pipeline_recipe_ref", str(pipeline_recipe_ref).strip()))
|
|
248
|
+
if normalized_workflow_id:
|
|
249
|
+
if self._is_workflow_ref(normalized_workflow_id):
|
|
250
|
+
launch_sources.append(("workflow_ref", normalized_workflow_id))
|
|
251
|
+
elif self._is_workflow_recipe_ref(normalized_workflow_id):
|
|
252
|
+
launch_sources.append(("workflow_recipe_ref", normalized_workflow_id))
|
|
253
|
+
elif self._is_pipeline_recipe_ref(normalized_workflow_id):
|
|
254
|
+
launch_sources.append(("pipeline_recipe_ref", normalized_workflow_id))
|
|
255
|
+
else:
|
|
256
|
+
launch_sources.append(("workflow_id", normalized_workflow_id))
|
|
257
|
+
if len(launch_sources) != 1:
|
|
258
|
+
raise ValueError(
|
|
259
|
+
"ensure requires exactly one of workflow_id, workflow_ref, "
|
|
260
|
+
"workflow_recipe_ref, or pipeline_recipe_ref"
|
|
261
|
+
)
|
|
262
|
+
field, value = launch_sources[0]
|
|
263
|
+
body[field] = value
|
|
236
264
|
if subject is not None:
|
|
237
265
|
body["subject"] = subject
|
|
238
266
|
if company is not None:
|
|
@@ -855,7 +883,7 @@ class WorkflowNamespace:
|
|
|
855
883
|
|
|
856
884
|
async def ensure(
|
|
857
885
|
self,
|
|
858
|
-
workflow_id: str,
|
|
886
|
+
workflow_id: Optional[str] = None,
|
|
859
887
|
*,
|
|
860
888
|
instance_id: Optional[str] = None,
|
|
861
889
|
group: Optional[str] = None,
|
|
@@ -866,6 +894,8 @@ class WorkflowNamespace:
|
|
|
866
894
|
mode: str = "blocking",
|
|
867
895
|
context: Optional[Dict[str, Any]] = None,
|
|
868
896
|
workflow_ref: Optional[str] = None,
|
|
897
|
+
workflow_recipe_ref: Optional[str] = None,
|
|
898
|
+
pipeline_recipe_ref: Optional[str] = None,
|
|
869
899
|
subject: Optional[str] = None,
|
|
870
900
|
company: Optional[str] = None,
|
|
871
901
|
inputs: Optional[Dict[str, Any]] = None,
|
|
@@ -886,6 +916,8 @@ class WorkflowNamespace:
|
|
|
886
916
|
body=self._build_authority_ensure_body(
|
|
887
917
|
workflow_id,
|
|
888
918
|
workflow_ref=workflow_ref,
|
|
919
|
+
workflow_recipe_ref=workflow_recipe_ref,
|
|
920
|
+
pipeline_recipe_ref=pipeline_recipe_ref,
|
|
889
921
|
subject=subject,
|
|
890
922
|
company=company,
|
|
891
923
|
inputs=inputs,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dominus-sdk-python
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.1.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
|
|
@@ -43,7 +43,7 @@ Async Python SDK for the Dominus gateway-first service plane.
|
|
|
43
43
|
- Gateway-scoped client mode for MCP and other user-JWT sessions
|
|
44
44
|
- Transport compatibility for wrapped `{success,data}` responses and unwrapped Warden/control-plane success objects
|
|
45
45
|
- Local helpers for JWT verification, trace propagation, retries, and console capture
|
|
46
|
-
- Current package version: `
|
|
46
|
+
- Current package version: `5.1.0`
|
|
47
47
|
|
|
48
48
|
## Install
|
|
49
49
|
|
|
@@ -71,6 +71,12 @@ run = await dominus.workflow.ensure(
|
|
|
71
71
|
company="summit-radiology",
|
|
72
72
|
)
|
|
73
73
|
|
|
74
|
+
recipe_run = await dominus.workflow.ensure(
|
|
75
|
+
workflow_recipe_ref="recipe://workflow-recipe-v1/report-cycle@v3",
|
|
76
|
+
subject="PCM47474562",
|
|
77
|
+
company="summit-radiology",
|
|
78
|
+
)
|
|
79
|
+
|
|
74
80
|
timeline = await dominus.authority.get_run_timeline(
|
|
75
81
|
run["run_id"],
|
|
76
82
|
since="2026-04-11T08:33:00Z",
|
|
@@ -274,6 +274,23 @@ async def test_workflow_ensure_supports_authority_one_call_lifecycle():
|
|
|
274
274
|
assert isinstance(body["idempotency_key"], str) and body["idempotency_key"]
|
|
275
275
|
|
|
276
276
|
|
|
277
|
+
@pytest.mark.asyncio
|
|
278
|
+
async def test_workflow_ensure_can_infer_recipe_ref_from_first_argument():
|
|
279
|
+
client = FakeClient()
|
|
280
|
+
namespace = WorkflowNamespace(client)
|
|
281
|
+
|
|
282
|
+
await namespace.ensure(
|
|
283
|
+
"recipe://workflow-recipe-v1/report-cycle@v3",
|
|
284
|
+
company="summit-radiology",
|
|
285
|
+
mode="async",
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
body = client.calls[0]["body"]
|
|
289
|
+
assert body["workflow_recipe_ref"] == "recipe://workflow-recipe-v1/report-cycle@v3"
|
|
290
|
+
assert body["company"] == "summit-radiology"
|
|
291
|
+
assert "workflow_id" not in body
|
|
292
|
+
|
|
293
|
+
|
|
277
294
|
@pytest.mark.asyncio
|
|
278
295
|
async def test_workflow_get_detects_authority_run_ids():
|
|
279
296
|
client = FakeClient()
|
|
@@ -76,6 +76,47 @@ async def test_workflow_ensure_accepts_workflow_ref():
|
|
|
76
76
|
assert body["context"] == {"report_ref": {"report_id": "r-1"}}
|
|
77
77
|
|
|
78
78
|
|
|
79
|
+
@pytest.mark.asyncio
|
|
80
|
+
async def test_workflow_ensure_accepts_recipe_refs():
|
|
81
|
+
client = FakeClient()
|
|
82
|
+
namespace = WorkflowNamespace(client)
|
|
83
|
+
|
|
84
|
+
await namespace.ensure(
|
|
85
|
+
workflow_recipe_ref="recipe://workflow-recipe-v1/patient-intake@v4",
|
|
86
|
+
subject="sub-1",
|
|
87
|
+
company="co-1",
|
|
88
|
+
mode="async",
|
|
89
|
+
)
|
|
90
|
+
await namespace.ensure(
|
|
91
|
+
pipeline_recipe_ref="recipe://pipeline-recipe-v1/intake-pipeline@v2",
|
|
92
|
+
context={"report_ref": {"report_id": "r-1"}},
|
|
93
|
+
mode="async",
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
first = client.calls[0]["body"]
|
|
97
|
+
assert first["workflow_recipe_ref"] == "recipe://workflow-recipe-v1/patient-intake@v4"
|
|
98
|
+
assert first["subject"] == "sub-1"
|
|
99
|
+
assert "workflow_id" not in first
|
|
100
|
+
second = client.calls[1]["body"]
|
|
101
|
+
assert second["pipeline_recipe_ref"] == "recipe://pipeline-recipe-v1/intake-pipeline@v2"
|
|
102
|
+
assert second["context"] == {"report_ref": {"report_id": "r-1"}}
|
|
103
|
+
assert "workflow_ref" not in second
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@pytest.mark.asyncio
|
|
107
|
+
async def test_workflow_ensure_rejects_mixed_legacy_and_recipe_refs():
|
|
108
|
+
client = FakeClient()
|
|
109
|
+
namespace = WorkflowNamespace(client)
|
|
110
|
+
|
|
111
|
+
with pytest.raises(ValueError, match="exactly one"):
|
|
112
|
+
await namespace.ensure(
|
|
113
|
+
"wf-123",
|
|
114
|
+
workflow_recipe_ref="recipe://workflow-recipe-v1/patient-intake@v4",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
assert client.calls == []
|
|
118
|
+
|
|
119
|
+
|
|
79
120
|
@pytest.mark.asyncio
|
|
80
121
|
async def test_workflow_save_forwards_builder_metadata():
|
|
81
122
|
client = FakeClient()
|
|
@@ -125,7 +166,7 @@ def test_artifact_ref_helpers_round_trip():
|
|
|
125
166
|
}
|
|
126
167
|
|
|
127
168
|
|
|
128
|
-
def
|
|
169
|
+
def test_artifact_ref_helpers_support_v2_refs():
|
|
129
170
|
v2_ref = build_artifact_ref(
|
|
130
171
|
group="carebridge",
|
|
131
172
|
owner="carebridge-summit",
|
|
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-5.0.0 → dominus_sdk_python-5.1.0}/dominus_sdk_python.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus_sdk_python.egg-info/requires.txt
RENAMED
|
File without changes
|
{dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/dominus_sdk_python.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.0}/tests/test_authority_public_vocabulary.py
RENAMED
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-5.0.0 → dominus_sdk_python-5.1.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
|