dominus-sdk-python 6.1.3__tar.gz → 6.2.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-6.1.3 → dominus_sdk_python-6.2.0}/PKG-INFO +1 -1
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/__init__.py +1 -1
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/authority.py +2 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/recipes.py +109 -3
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus_sdk_python.egg-info/PKG-INFO +1 -1
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus_sdk_python.egg-info/SOURCES.txt +1 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/pyproject.toml +1 -1
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_authority_public_vocabulary.py +2 -1
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_recipes_namespace.py +2 -2
- dominus_sdk_python-6.2.0/tests/test_recipes_stash_routing.py +229 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/README.md +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/config/__init__.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/config/endpoints.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/errors.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/helpers/__init__.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/helpers/auth.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/helpers/cache.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/helpers/console_capture.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/helpers/core.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/helpers/crypto.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/helpers/sse.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/helpers/trace.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/__init__.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/admin.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/ai.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/artifacts.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/auth.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/browser.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/coder.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/courier.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/db.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/ddl.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/deployer.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/fastapi.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/files.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/health.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/jobs.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/logs.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/platform.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/portal.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/processor.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/publisher.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/redis.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/secrets.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/secure.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/stash.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/sync.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/warden.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/namespaces/workflow.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/services/__init__.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus/start.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus_sdk_python.egg-info/dependency_links.txt +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus_sdk_python.egg-info/requires.txt +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus_sdk_python.egg-info/top_level.txt +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/setup.cfg +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_auth.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_browser_namespace.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_control_plane_namespaces.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_errors.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_flat_commands.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_health.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_logs.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_platform_coder_namespaces.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_provisioning_parity.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_public_exports.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_publisher_namespace.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_transport_compat.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_workflow_lifecycle.py +0 -0
- {dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_workflow_refs.py +0 -0
|
@@ -1155,6 +1155,7 @@ class AuthorityNamespace:
|
|
|
1155
1155
|
until: Optional[str] = None,
|
|
1156
1156
|
window_hours: Optional[int] = None,
|
|
1157
1157
|
limit: Optional[int] = None,
|
|
1158
|
+
full: bool = False,
|
|
1158
1159
|
timeout: Optional[float] = None,
|
|
1159
1160
|
) -> Dict[str, Any]:
|
|
1160
1161
|
"""
|
|
@@ -1172,6 +1173,7 @@ class AuthorityNamespace:
|
|
|
1172
1173
|
"until": until,
|
|
1173
1174
|
"window_hours": window_hours,
|
|
1174
1175
|
"limit": limit,
|
|
1176
|
+
"full": 1 if full else None,
|
|
1175
1177
|
})
|
|
1176
1178
|
return await self._get(
|
|
1177
1179
|
f"/api/authority/dossiers/deploy/{quote(deploy_id, safe='')}{qs}",
|
|
@@ -12,16 +12,76 @@ Refs follow ``recipe://{type}/{name}[@v{N}][?tier={tier}]``.
|
|
|
12
12
|
"""
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
|
+
import json
|
|
15
16
|
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
|
16
17
|
|
|
17
18
|
if TYPE_CHECKING:
|
|
18
19
|
from ..start import Dominus
|
|
19
20
|
|
|
20
21
|
|
|
22
|
+
STASH_BACKED_RECIPE_TYPES = frozenset({
|
|
23
|
+
"envoy-bootstrap-v1",
|
|
24
|
+
"envoy-release-publish-v1",
|
|
25
|
+
"envoy-policy-v1",
|
|
26
|
+
"pacs-extraction-recipe-v1",
|
|
27
|
+
"pacs-vendor-probe-v1",
|
|
28
|
+
"browser-recipe",
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
|
|
21
32
|
def _compact(payload: Dict[str, Any]) -> Dict[str, Any]:
|
|
22
33
|
return {k: v for k, v in payload.items() if v is not None and v != ""}
|
|
23
34
|
|
|
24
35
|
|
|
36
|
+
def _recipe_tier_to_stash_scope(tier: Optional[str]) -> str:
|
|
37
|
+
if tier == "platform":
|
|
38
|
+
return "platform"
|
|
39
|
+
if tier == "group":
|
|
40
|
+
return "group"
|
|
41
|
+
return "self"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _resolve_recipe_stash_env(client: "Dominus", env: Optional[str]) -> str:
|
|
45
|
+
return env or getattr(client, "_gateway_env", None) or "production"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _recipe_body_to_text(value: Any) -> str:
|
|
49
|
+
if isinstance(value, str):
|
|
50
|
+
return value
|
|
51
|
+
if value is None:
|
|
52
|
+
raise ValueError("body is required")
|
|
53
|
+
return json.dumps(value, separators=(",", ":"))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _build_recipe_payload_from_stash(
|
|
57
|
+
*,
|
|
58
|
+
type: str,
|
|
59
|
+
name: str,
|
|
60
|
+
tier: Optional[str],
|
|
61
|
+
data: Dict[str, Any],
|
|
62
|
+
) -> Dict[str, Any]:
|
|
63
|
+
version = data.get("version")
|
|
64
|
+
try:
|
|
65
|
+
version_int = int(version) if version is not None else None
|
|
66
|
+
except (TypeError, ValueError):
|
|
67
|
+
version_int = None
|
|
68
|
+
return {
|
|
69
|
+
"recipe": {
|
|
70
|
+
"metadata": {
|
|
71
|
+
"type": type,
|
|
72
|
+
"name": name,
|
|
73
|
+
"tier": data.get("resolved_tier") or tier,
|
|
74
|
+
"version": version_int,
|
|
75
|
+
"schema_version": 1,
|
|
76
|
+
"sha256": data.get("value_hash"),
|
|
77
|
+
"head_ref": data.get("head_ref"),
|
|
78
|
+
"snapshot_ref": data.get("snapshot_ref"),
|
|
79
|
+
},
|
|
80
|
+
"body": data.get("value"),
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
25
85
|
class RecipesNamespace:
|
|
26
86
|
"""
|
|
27
87
|
Recipe worker namespace.
|
|
@@ -86,16 +146,41 @@ class RecipesNamespace:
|
|
|
86
146
|
body: str,
|
|
87
147
|
description: Optional[str] = None,
|
|
88
148
|
actor_context: Optional[Dict[str, str]] = None,
|
|
149
|
+
env: Optional[str] = None,
|
|
89
150
|
timeout: float = 30.0,
|
|
90
151
|
) -> Dict[str, Any]:
|
|
91
|
-
"""Publish a recipe.
|
|
152
|
+
"""Publish a recipe. Stash-backed recipe types accept optional ``env``."""
|
|
153
|
+
body_text = _recipe_body_to_text(body)
|
|
154
|
+
if type in STASH_BACKED_RECIPE_TYPES:
|
|
155
|
+
result = await self._client._request(
|
|
156
|
+
endpoint="/svc/stash/put",
|
|
157
|
+
method="POST",
|
|
158
|
+
body={
|
|
159
|
+
"env": _resolve_recipe_stash_env(self._client, env),
|
|
160
|
+
"kind": type,
|
|
161
|
+
"scope": _recipe_tier_to_stash_scope(tier),
|
|
162
|
+
"key": name,
|
|
163
|
+
"value": body_text,
|
|
164
|
+
"versioned": True,
|
|
165
|
+
"purpose": description or "sdk-recipe-publish",
|
|
166
|
+
},
|
|
167
|
+
use_gateway=True,
|
|
168
|
+
actor=actor_context,
|
|
169
|
+
timeout=timeout,
|
|
170
|
+
)
|
|
171
|
+
return _build_recipe_payload_from_stash(
|
|
172
|
+
type=type,
|
|
173
|
+
name=name,
|
|
174
|
+
tier=tier,
|
|
175
|
+
data=result,
|
|
176
|
+
)
|
|
92
177
|
return await self._post(
|
|
93
178
|
"/api/recipe/recipes/publish",
|
|
94
179
|
_compact({
|
|
95
180
|
"type": type,
|
|
96
181
|
"tier": tier,
|
|
97
182
|
"name": name,
|
|
98
|
-
"body":
|
|
183
|
+
"body": body_text,
|
|
99
184
|
"description": description,
|
|
100
185
|
}),
|
|
101
186
|
actor_context=actor_context,
|
|
@@ -167,9 +252,30 @@ class RecipesNamespace:
|
|
|
167
252
|
name: str,
|
|
168
253
|
version: Optional[int] = None,
|
|
169
254
|
tier: Optional[str] = None,
|
|
255
|
+
env: Optional[str] = None,
|
|
170
256
|
timeout: float = 15.0,
|
|
171
257
|
) -> Dict[str, Any]:
|
|
172
|
-
"""Resolve a recipe
|
|
258
|
+
"""Resolve a recipe. Stash-backed recipe types accept optional ``env``."""
|
|
259
|
+
if type in STASH_BACKED_RECIPE_TYPES:
|
|
260
|
+
result = await self._client._request(
|
|
261
|
+
endpoint="/svc/stash/get",
|
|
262
|
+
method="POST",
|
|
263
|
+
body={
|
|
264
|
+
"env": _resolve_recipe_stash_env(self._client, env),
|
|
265
|
+
"kind": type,
|
|
266
|
+
"scope": _recipe_tier_to_stash_scope(tier),
|
|
267
|
+
"key": name,
|
|
268
|
+
"version": version if version is not None else "head",
|
|
269
|
+
},
|
|
270
|
+
use_gateway=True,
|
|
271
|
+
timeout=timeout,
|
|
272
|
+
)
|
|
273
|
+
return _build_recipe_payload_from_stash(
|
|
274
|
+
type=type,
|
|
275
|
+
name=name,
|
|
276
|
+
tier=tier,
|
|
277
|
+
data=result,
|
|
278
|
+
)
|
|
173
279
|
path = f"/api/recipe/recipes/{type}/{name}"
|
|
174
280
|
if version is not None:
|
|
175
281
|
path += f"@v{version}"
|
{dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus_sdk_python.egg-info/SOURCES.txt
RENAMED
|
@@ -61,6 +61,7 @@ tests/test_provisioning_parity.py
|
|
|
61
61
|
tests/test_public_exports.py
|
|
62
62
|
tests/test_publisher_namespace.py
|
|
63
63
|
tests/test_recipes_namespace.py
|
|
64
|
+
tests/test_recipes_stash_routing.py
|
|
64
65
|
tests/test_transport_compat.py
|
|
65
66
|
tests/test_workflow_lifecycle.py
|
|
66
67
|
tests/test_workflow_refs.py
|
{dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_authority_public_vocabulary.py
RENAMED
|
@@ -217,6 +217,7 @@ async def test_authority_scope_methods_use_canonical_context_wire_names():
|
|
|
217
217
|
until="2026-04-11T09:33:00Z",
|
|
218
218
|
window_hours=24,
|
|
219
219
|
limit=150,
|
|
220
|
+
full=True,
|
|
220
221
|
)
|
|
221
222
|
await namespace.query_timelines(
|
|
222
223
|
subject="PCM47474562",
|
|
@@ -314,7 +315,7 @@ async def test_authority_scope_methods_use_canonical_context_wire_names():
|
|
|
314
315
|
)
|
|
315
316
|
assert client.calls[7]["endpoint"] == (
|
|
316
317
|
"/api/authority/dossiers/deploy/deploy-1?"
|
|
317
|
-
"since=2026-04-11T08%3A33%3A00Z&until=2026-04-11T09%3A33%3A00Z&window_hours=24&limit=150"
|
|
318
|
+
"since=2026-04-11T08%3A33%3A00Z&until=2026-04-11T09%3A33%3A00Z&window_hours=24&limit=150&full=1"
|
|
318
319
|
)
|
|
319
320
|
assert client.calls[8]["body"] == {
|
|
320
321
|
"subject": "PCM47474562",
|
|
@@ -61,7 +61,7 @@ async def test_recipes_namespace_passes_actor_context_on_publish(monkeypatch, sd
|
|
|
61
61
|
|
|
62
62
|
actor = {"type": "user", "id": "user-1"}
|
|
63
63
|
await sdk.recipes.publish(
|
|
64
|
-
type="
|
|
64
|
+
type="legacy-recipe-type",
|
|
65
65
|
tier="project",
|
|
66
66
|
name="cms-login",
|
|
67
67
|
body="version: browser-recipe-v1\nsteps: []\n",
|
|
@@ -73,7 +73,7 @@ async def test_recipes_namespace_passes_actor_context_on_publish(monkeypatch, sd
|
|
|
73
73
|
"endpoint": "/api/recipe/recipes/publish",
|
|
74
74
|
"method": "POST",
|
|
75
75
|
"body": {
|
|
76
|
-
"type": "
|
|
76
|
+
"type": "legacy-recipe-type",
|
|
77
77
|
"tier": "project",
|
|
78
78
|
"name": "cms-login",
|
|
79
79
|
"body": "version: browser-recipe-v1\nsteps: []\n",
|
|
@@ -0,0 +1,229 @@
|
|
|
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_publish_stash_backed_type_routes_to_stash(monkeypatch, sdk):
|
|
18
|
+
calls = []
|
|
19
|
+
|
|
20
|
+
async def fake_request(**kwargs):
|
|
21
|
+
calls.append(kwargs)
|
|
22
|
+
return {
|
|
23
|
+
"version": 1,
|
|
24
|
+
"value": "channel: prod\n",
|
|
25
|
+
"value_hash": "abc123",
|
|
26
|
+
"resolved_tier": "platform",
|
|
27
|
+
"head_ref": "stash://envoy-bootstrap-v1/envoy-prod@head",
|
|
28
|
+
"snapshot_ref": "stash://envoy-bootstrap-v1/envoy-prod@v1",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
monkeypatch.setattr(sdk, "_request", fake_request)
|
|
32
|
+
|
|
33
|
+
result = await sdk.recipes.publish(
|
|
34
|
+
type="envoy-bootstrap-v1",
|
|
35
|
+
tier="platform",
|
|
36
|
+
name="envoy-prod",
|
|
37
|
+
body="channel: prod\n",
|
|
38
|
+
description="publish bootstrap",
|
|
39
|
+
env="staging",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
assert len(calls) == 1
|
|
43
|
+
assert calls[0]["endpoint"] == "/svc/stash/put"
|
|
44
|
+
assert calls[0]["method"] == "POST"
|
|
45
|
+
assert calls[0]["use_gateway"] is True
|
|
46
|
+
assert calls[0]["timeout"] == 30.0
|
|
47
|
+
assert calls[0]["body"] == {
|
|
48
|
+
"env": "staging",
|
|
49
|
+
"kind": "envoy-bootstrap-v1",
|
|
50
|
+
"scope": "platform",
|
|
51
|
+
"key": "envoy-prod",
|
|
52
|
+
"value": "channel: prod\n",
|
|
53
|
+
"versioned": True,
|
|
54
|
+
"purpose": "publish bootstrap",
|
|
55
|
+
}
|
|
56
|
+
assert result == {
|
|
57
|
+
"recipe": {
|
|
58
|
+
"metadata": {
|
|
59
|
+
"type": "envoy-bootstrap-v1",
|
|
60
|
+
"name": "envoy-prod",
|
|
61
|
+
"tier": "platform",
|
|
62
|
+
"version": 1,
|
|
63
|
+
"schema_version": 1,
|
|
64
|
+
"sha256": "abc123",
|
|
65
|
+
"head_ref": "stash://envoy-bootstrap-v1/envoy-prod@head",
|
|
66
|
+
"snapshot_ref": "stash://envoy-bootstrap-v1/envoy-prod@v1",
|
|
67
|
+
},
|
|
68
|
+
"body": "channel: prod\n",
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@pytest.mark.asyncio
|
|
74
|
+
async def test_publish_non_stash_backed_type_keeps_legacy_path(monkeypatch, sdk):
|
|
75
|
+
calls = []
|
|
76
|
+
|
|
77
|
+
async def fake_request(**kwargs):
|
|
78
|
+
calls.append(kwargs)
|
|
79
|
+
return {"ok": True, "recipe": {"version": 7}}
|
|
80
|
+
|
|
81
|
+
monkeypatch.setattr(sdk, "_request", fake_request)
|
|
82
|
+
|
|
83
|
+
result = await sdk.recipes.publish(
|
|
84
|
+
type="some-unmigrated-type",
|
|
85
|
+
tier="group",
|
|
86
|
+
name="legacy-recipe",
|
|
87
|
+
body="steps: []\n",
|
|
88
|
+
env="staging",
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
assert result["recipe"]["version"] == 7
|
|
92
|
+
assert calls == [
|
|
93
|
+
{
|
|
94
|
+
"endpoint": "/api/recipe/recipes/publish",
|
|
95
|
+
"method": "POST",
|
|
96
|
+
"body": {
|
|
97
|
+
"type": "some-unmigrated-type",
|
|
98
|
+
"tier": "group",
|
|
99
|
+
"name": "legacy-recipe",
|
|
100
|
+
"body": "steps: []\n",
|
|
101
|
+
},
|
|
102
|
+
"use_gateway": True,
|
|
103
|
+
"timeout": 30.0,
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@pytest.mark.asyncio
|
|
109
|
+
async def test_get_stash_backed_type_routes_to_stash(monkeypatch, sdk):
|
|
110
|
+
calls = []
|
|
111
|
+
|
|
112
|
+
async def fake_request(**kwargs):
|
|
113
|
+
calls.append(kwargs)
|
|
114
|
+
return {
|
|
115
|
+
"version": "2",
|
|
116
|
+
"value": "operation: fetch\n",
|
|
117
|
+
"value_hash": "def456",
|
|
118
|
+
"resolved_tier": "group",
|
|
119
|
+
"head_ref": "stash://pacs-extraction-recipe-v1/fuji-x@head",
|
|
120
|
+
"snapshot_ref": "stash://pacs-extraction-recipe-v1/fuji-x@v2",
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
monkeypatch.setattr(sdk, "_request", fake_request)
|
|
124
|
+
|
|
125
|
+
result = await sdk.recipes.get(
|
|
126
|
+
type="pacs-extraction-recipe-v1",
|
|
127
|
+
name="fuji-x",
|
|
128
|
+
version=2,
|
|
129
|
+
tier="group",
|
|
130
|
+
env="development",
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
assert len(calls) == 1
|
|
134
|
+
assert calls[0] == {
|
|
135
|
+
"endpoint": "/svc/stash/get",
|
|
136
|
+
"method": "POST",
|
|
137
|
+
"body": {
|
|
138
|
+
"env": "development",
|
|
139
|
+
"kind": "pacs-extraction-recipe-v1",
|
|
140
|
+
"scope": "group",
|
|
141
|
+
"key": "fuji-x",
|
|
142
|
+
"version": 2,
|
|
143
|
+
},
|
|
144
|
+
"use_gateway": True,
|
|
145
|
+
"timeout": 15.0,
|
|
146
|
+
}
|
|
147
|
+
assert result == {
|
|
148
|
+
"recipe": {
|
|
149
|
+
"metadata": {
|
|
150
|
+
"type": "pacs-extraction-recipe-v1",
|
|
151
|
+
"name": "fuji-x",
|
|
152
|
+
"tier": "group",
|
|
153
|
+
"version": 2,
|
|
154
|
+
"schema_version": 1,
|
|
155
|
+
"sha256": "def456",
|
|
156
|
+
"head_ref": "stash://pacs-extraction-recipe-v1/fuji-x@head",
|
|
157
|
+
"snapshot_ref": "stash://pacs-extraction-recipe-v1/fuji-x@v2",
|
|
158
|
+
},
|
|
159
|
+
"body": "operation: fetch\n",
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@pytest.mark.asyncio
|
|
165
|
+
async def test_get_non_stash_backed_type_keeps_legacy_path(monkeypatch, sdk):
|
|
166
|
+
calls = []
|
|
167
|
+
|
|
168
|
+
async def fake_request(**kwargs):
|
|
169
|
+
calls.append(kwargs)
|
|
170
|
+
return {"recipe": {"metadata": {"name": "y"}}}
|
|
171
|
+
|
|
172
|
+
monkeypatch.setattr(sdk, "_request", fake_request)
|
|
173
|
+
|
|
174
|
+
result = await sdk.recipes.get(type="other", name="y", env="staging")
|
|
175
|
+
|
|
176
|
+
assert result["recipe"]["metadata"]["name"] == "y"
|
|
177
|
+
assert calls == [
|
|
178
|
+
{
|
|
179
|
+
"endpoint": "/api/recipe/recipes/other/y",
|
|
180
|
+
"method": "GET",
|
|
181
|
+
"use_gateway": True,
|
|
182
|
+
"timeout": 15.0,
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@pytest.mark.asyncio
|
|
188
|
+
async def test_recipe_body_to_text_validation(monkeypatch, sdk):
|
|
189
|
+
calls = []
|
|
190
|
+
|
|
191
|
+
async def fake_request(**kwargs):
|
|
192
|
+
calls.append(kwargs)
|
|
193
|
+
return {
|
|
194
|
+
"version": len(calls),
|
|
195
|
+
"value": kwargs["body"]["value"],
|
|
196
|
+
"value_hash": f"hash-{len(calls)}",
|
|
197
|
+
"resolved_tier": "self",
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
monkeypatch.setattr(sdk, "_request", fake_request)
|
|
201
|
+
|
|
202
|
+
string_result = await sdk.recipes.publish(
|
|
203
|
+
type="browser-recipe",
|
|
204
|
+
tier="project",
|
|
205
|
+
name="string-body",
|
|
206
|
+
body="steps: []\n",
|
|
207
|
+
)
|
|
208
|
+
dict_result = await sdk.recipes.publish(
|
|
209
|
+
type="browser-recipe",
|
|
210
|
+
tier="project",
|
|
211
|
+
name="dict-body",
|
|
212
|
+
body={"steps": []},
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
assert calls[0]["body"]["env"] == "production"
|
|
216
|
+
assert calls[0]["body"]["value"] == "steps: []\n"
|
|
217
|
+
assert string_result["recipe"]["body"] == "steps: []\n"
|
|
218
|
+
assert calls[1]["body"]["value"] == '{"steps":[]}'
|
|
219
|
+
assert dict_result["recipe"]["body"] == '{"steps":[]}'
|
|
220
|
+
|
|
221
|
+
with pytest.raises(ValueError, match="body is required"):
|
|
222
|
+
await sdk.recipes.publish(
|
|
223
|
+
type="browser-recipe",
|
|
224
|
+
tier="project",
|
|
225
|
+
name="missing-body",
|
|
226
|
+
body=None,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
assert len(calls) == 2
|
|
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
|
{dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/dominus_sdk_python.egg-info/requires.txt
RENAMED
|
File without changes
|
{dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.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-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_control_plane_namespaces.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-6.1.3 → dominus_sdk_python-6.2.0}/tests/test_platform_coder_namespaces.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|