dominus-sdk-python 3.0.2__py3-none-any.whl → 3.0.4__py3-none-any.whl

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/__init__.py CHANGED
@@ -111,6 +111,8 @@ from .namespaces.jobs import JobsNamespace
111
111
  from .namespaces.processor import ProcessorNamespace
112
112
  from .namespaces.sync import SyncNamespace
113
113
  from .namespaces.authority import AuthorityNamespace
114
+ from .namespaces.deployer import DeployerNamespace
115
+ from .namespaces.warden import WardenNamespace
114
116
 
115
117
  # Export AI namespace for agent-runtime operations
116
118
  from .namespaces.ai import (
@@ -211,6 +213,8 @@ __all__ = [
211
213
  "ProcessorNamespace",
212
214
  "SyncNamespace",
213
215
  "AuthorityNamespace",
216
+ "DeployerNamespace",
217
+ "WardenNamespace",
214
218
  # AI namespace for agent-runtime operations
215
219
  "AiNamespace",
216
220
  "RagSubNamespace",
@@ -2,13 +2,17 @@
2
2
  Dominus SDK Endpoints
3
3
 
4
4
  Gateway URL for service routing and health checks.
5
- JWT URL for authentication (JWT minting).
5
+ JWT URL for authentication (JWT minting) — defaults to the same host as the gateway.
6
6
  Logs URL for log ingestion.
7
7
  Base URL for SDK requests (defaults to gateway).
8
8
 
9
+ Defaults always target the production gateway. They do not depend on the caller’s
10
+ git branch, PyPI package variant, or deployment environment. Override only with
11
+ DOMINUS_* env vars for local or advanced routing.
12
+
9
13
  Configuration:
10
14
  Set DOMINUS_GATEWAY_URL to override the gateway URL.
11
- Set DOMINUS_JWT_URL to override the JWT minting URL.
15
+ Set DOMINUS_JWT_URL to override the JWT minting URL (defaults to gateway URL).
12
16
  Set DOMINUS_LOGS_URL to override the logs URL.
13
17
  Set DOMINUS_BASE_URL to override the SDK request base URL.
14
18
  Example: export DOMINUS_BASE_URL=http://localhost:5000
@@ -18,23 +22,21 @@ Usage:
18
22
  """
19
23
  import os
20
24
 
21
- # Default URLs - Cloudflare Workers
25
+ # Production gateway (Cloudflare Worker). Canonical default for all SDK HTTP traffic.
22
26
  _DEFAULT_GATEWAY_URL = "https://gateway.getdominus.app"
23
- _DEFAULT_JWT_URL = "https://jwt.getdominus.app"
24
27
  _DEFAULT_LOGS_URL = "https://logs.getdominus.app"
25
- _DEFAULT_BASE_URL = _DEFAULT_GATEWAY_URL
26
28
 
27
29
  # Gateway URL for service routing (can be overridden via DOMINUS_GATEWAY_URL)
28
30
  GATEWAY_URL = os.environ.get("DOMINUS_GATEWAY_URL", _DEFAULT_GATEWAY_URL)
29
31
 
30
- # JWT URL for authentication (can be overridden via DOMINUS_JWT_URL)
31
- JWT_URL = os.environ.get("DOMINUS_JWT_URL", _DEFAULT_JWT_URL)
32
+ # JWT mint/JWKS: same host as gateway by default (matches Node SDK).
33
+ JWT_URL = os.environ.get("DOMINUS_JWT_URL", GATEWAY_URL)
32
34
 
33
35
  # Logs URL for log ingestion (can be overridden via DOMINUS_LOGS_URL)
34
36
  LOGS_URL = os.environ.get("DOMINUS_LOGS_URL", _DEFAULT_LOGS_URL)
35
37
 
36
- # Base URL for SDK requests (can be overridden via DOMINUS_BASE_URL environment variable)
37
- BASE_URL = os.environ.get("DOMINUS_BASE_URL", _DEFAULT_BASE_URL)
38
+ # Base URL for non-gateway SDK paths defaults to the same resolved gateway URL.
39
+ BASE_URL = os.environ.get("DOMINUS_BASE_URL", GATEWAY_URL)
38
40
 
39
41
  # Legacy aliases retained as gateway-first aliases.
40
42
  SOVEREIGN_URL = BASE_URL
@@ -77,12 +79,11 @@ def get_gateway_url() -> str:
77
79
 
78
80
  def get_jwt_url() -> str:
79
81
  """
80
- Get the JWT worker URL for authentication (JWT minting/validation).
82
+ Get the base URL for JWT mint/JWKS (defaults to the same host as the gateway).
81
83
 
82
- Returns the value of DOMINUS_JWT_URL environment variable if set,
83
- otherwise returns the default Cloudflare Worker URL.
84
+ Returns DOMINUS_JWT_URL if set, otherwise the same resolution as get_gateway_url().
84
85
  """
85
- return os.environ.get("DOMINUS_JWT_URL", _DEFAULT_JWT_URL)
86
+ return os.environ.get("DOMINUS_JWT_URL", get_gateway_url())
86
87
 
87
88
 
88
89
  def get_logs_url() -> str:
@@ -99,10 +100,9 @@ def get_base_url() -> str:
99
100
  """
100
101
  Get the SDK request base URL.
101
102
 
102
- Returns the value of DOMINUS_BASE_URL environment variable if set,
103
- otherwise returns the default gateway URL.
103
+ Returns DOMINUS_BASE_URL if set, otherwise the same resolution as get_gateway_url().
104
104
  """
105
- return os.environ.get("DOMINUS_BASE_URL", _DEFAULT_BASE_URL)
105
+ return os.environ.get("DOMINUS_BASE_URL", get_gateway_url())
106
106
 
107
107
 
108
108
  # DEPRECATED - use get_base_url()
@@ -15,6 +15,8 @@ from .jobs import JobsNamespace
15
15
  from .processor import ProcessorNamespace
16
16
  from .sync import SyncNamespace
17
17
  from .authority import AuthorityNamespace
18
+ from .deployer import DeployerNamespace
19
+ from .warden import WardenNamespace
18
20
  from .ai import (
19
21
  AiNamespace,
20
22
  RagSubNamespace,
@@ -40,6 +42,8 @@ __all__ = [
40
42
  "ProcessorNamespace",
41
43
  "SyncNamespace",
42
44
  "AuthorityNamespace",
45
+ "DeployerNamespace",
46
+ "WardenNamespace",
43
47
  "AiNamespace",
44
48
  "RagSubNamespace",
45
49
  "ArtifactsSubNamespace",
@@ -37,6 +37,17 @@ def _compact(payload: Mapping[str, Any]) -> Dict[str, Any]:
37
37
  return out
38
38
 
39
39
 
40
+ def _normalize_run_kind_token(raw: Optional[str]) -> str:
41
+ if not raw:
42
+ return ""
43
+ s = str(raw).strip().lower().replace(".", "_").replace("-", "_")
44
+ return s
45
+
46
+
47
+ def _is_company_bootstrap_run_kind(run_kind: Optional[str]) -> bool:
48
+ return _normalize_run_kind_token(run_kind) == "company_bootstrap"
49
+
50
+
40
51
  def _query_string(params: Mapping[str, Any]) -> str:
41
52
  cleaned = {k: v for k, v in params.items() if v is not None and v != ""}
42
53
  if not cleaned:
@@ -110,17 +121,37 @@ class AuthorityNamespace:
110
121
  ) -> Dict[str, Any]:
111
122
  out: Dict[str, Any] = {}
112
123
  if app_slug:
113
- out["project_slug"] = app_slug
124
+ out["app_slug"] = app_slug
114
125
  if env:
115
- out["environment"] = env
126
+ out["env"] = env
116
127
  if target_org_id:
117
- out["target_project_id"] = target_org_id
128
+ out["target_org_id"] = target_org_id
118
129
  if target_app_slug:
119
- out["target_project_slug"] = target_app_slug
130
+ out["target_app_slug"] = target_app_slug
120
131
  if target_env:
121
- out["target_environment"] = target_env
132
+ out["target_env"] = target_env
122
133
  return out
123
134
 
135
+ def _target_query_params(
136
+ self,
137
+ target_org_id: Optional[str],
138
+ target_env: Optional[str],
139
+ ) -> tuple[Optional[str], Optional[str]]:
140
+ """
141
+ Omit target_org_id / target_env from GET query strings when they
142
+ duplicate the JWT gateway org/env (selected-scope MCP and operators).
143
+ """
144
+ client = self._client
145
+ gw_org = getattr(client, "_gateway_org_id", None)
146
+ gw_env = getattr(client, "_gateway_env", None)
147
+ tid = target_org_id
148
+ tev = target_env
149
+ if tid is not None and gw_org is not None and str(tid) == str(gw_org):
150
+ tid = None
151
+ if tev is not None and gw_env is not None and str(tev) == str(gw_env):
152
+ tev = None
153
+ return tid, tev
154
+
124
155
  @staticmethod
125
156
  def _http_timeout(explicit: Optional[float], default: float) -> float:
126
157
  """Use explicit client timeout when provided; otherwise the historical SDK default."""
@@ -135,6 +166,9 @@ class AuthorityNamespace:
135
166
  *,
136
167
  workflow_id: Optional[str] = None,
137
168
  workflow_ref: Optional[str] = None,
169
+ run_kind: Optional[str] = None,
170
+ company_slug: Optional[str] = None,
171
+ slug: Optional[str] = None,
138
172
  instance_id: Optional[str] = None,
139
173
  instance_key: Optional[str] = None,
140
174
  group: Optional[str] = None,
@@ -149,6 +183,18 @@ class AuthorityNamespace:
149
183
  env: Optional[str] = None,
150
184
  target_org_id: Optional[str] = None,
151
185
  target_env: Optional[str] = None,
186
+ target_app_slug: Optional[str] = None,
187
+ shared_app_slug: Optional[str] = None,
188
+ execution_mode: Optional[str] = None,
189
+ region: Optional[str] = None,
190
+ system: Optional[str] = None,
191
+ github_mode: Optional[str] = None,
192
+ overwrite_existing: Optional[bool] = None,
193
+ owner_email: Optional[str] = None,
194
+ include: Optional[Dict[str, Any]] = None,
195
+ metadata: Optional[Dict[str, Any]] = None,
196
+ display_name: Optional[str] = None,
197
+ description: Optional[str] = None,
152
198
  initiator_type: Optional[str] = None,
153
199
  initiator_id: Optional[str] = None,
154
200
  idempotency_key: Optional[str] = None,
@@ -158,30 +204,79 @@ class AuthorityNamespace:
158
204
  Ensure (and optionally launch) an Authority-backed workflow run.
159
205
 
160
206
  Calls ``POST /api/authority/runs/ensure``.
207
+
208
+ For company bootstrap, pass ``run_kind="company.bootstrap"`` (or ``company_bootstrap``) plus
209
+ ``company``, ``company_slug``, or ``slug``. Optional bootstrap fields mirror
210
+ ``bootstrap_company`` (``execution_mode``, ``region``, …).
161
211
  """
162
- if not workflow_id and not workflow_ref:
163
- raise ValueError("ensure_run requires workflow_id or workflow_ref")
212
+ bootstrap = _is_company_bootstrap_run_kind(run_kind)
213
+ if not bootstrap and not workflow_id and not workflow_ref:
214
+ raise ValueError(
215
+ "ensure_run requires workflow_id or workflow_ref unless run_kind is "
216
+ "company.bootstrap / company_bootstrap"
217
+ )
218
+ if bootstrap:
219
+ co = (company_slug or slug or company or "").strip()
220
+ if not co:
221
+ raise ValueError(
222
+ "ensure_run with run_kind company.bootstrap requires company, company_slug, or slug"
223
+ )
164
224
  if mode == "streaming":
165
225
  raise ValueError(
166
226
  "Authority runs do not support streaming mode; "
167
227
  "use blocking, async, or ensure_only"
168
228
  )
169
- body = _compact({
170
- "workflow_id": workflow_id,
171
- "workflow_ref": workflow_ref,
172
- "instance_id": instance_id,
173
- "instance_key": instance_key,
174
- "group": group,
175
- "owner": owner,
176
- "subject": subject,
177
- "company": company,
178
- "mode": mode,
179
- "bindings": bindings,
180
- "inputs": inputs,
181
- "context": context,
182
- **self._initiator(initiator_type, initiator_id, idempotency_key),
183
- **self._scope(app_slug, env, target_org_id, target_env),
184
- })
229
+
230
+ initiator = self._initiator(initiator_type, initiator_id, idempotency_key)
231
+ scope = self._scope(app_slug, env, target_org_id, target_env, target_app_slug=target_app_slug)
232
+
233
+ if bootstrap:
234
+ body = _compact({
235
+ "run_kind": run_kind,
236
+ "workflow_id": workflow_id,
237
+ "workflow_ref": workflow_ref,
238
+ "instance_id": instance_id,
239
+ "instance_key": instance_key,
240
+ "group": group,
241
+ "owner": owner,
242
+ "subject": subject,
243
+ "company": company,
244
+ "company_slug": company_slug,
245
+ "slug": slug,
246
+ "bindings": bindings,
247
+ "inputs": inputs,
248
+ "context": context,
249
+ "execution_mode": execution_mode,
250
+ "region": region,
251
+ "system": system,
252
+ "github_mode": github_mode,
253
+ "overwrite_existing": overwrite_existing,
254
+ "owner_email": owner_email,
255
+ "include": include,
256
+ "metadata": metadata,
257
+ "display_name": display_name,
258
+ "description": description,
259
+ "shared_app_slug": shared_app_slug,
260
+ **initiator,
261
+ **scope,
262
+ })
263
+ else:
264
+ body = _compact({
265
+ "workflow_id": workflow_id,
266
+ "workflow_ref": workflow_ref,
267
+ "instance_id": instance_id,
268
+ "instance_key": instance_key,
269
+ "group": group,
270
+ "owner": owner,
271
+ "subject": subject,
272
+ "company": company,
273
+ "mode": mode,
274
+ "bindings": bindings,
275
+ "inputs": inputs,
276
+ "context": context,
277
+ **initiator,
278
+ **scope,
279
+ })
185
280
  return await self._post(
186
281
  "/api/authority/runs/ensure",
187
282
  body,
@@ -213,15 +308,16 @@ class AuthorityNamespace:
213
308
  timeout: Optional[float] = None,
214
309
  ) -> Dict[str, Any]:
215
310
  """List Authority-backed runs. ``GET /api/authority/runs``."""
311
+ tid, tev = self._target_query_params(target_org_id, target_env)
216
312
  qs = _query_string({
217
313
  "workflow_id": workflow_id,
218
314
  "status": status,
219
315
  "group": group,
220
316
  "owner": owner,
221
- "project_slug": app_slug,
222
- "environment": env,
223
- "target_project_id": target_org_id,
224
- "target_environment": target_env,
317
+ "app_slug": app_slug,
318
+ "env": env,
319
+ "target_org_id": tid,
320
+ "target_env": tev,
225
321
  "limit": limit,
226
322
  "offset": offset,
227
323
  })
@@ -418,14 +514,15 @@ class AuthorityNamespace:
418
514
  offset: int = 0,
419
515
  ) -> Dict[str, Any]:
420
516
  """List Authority workflow bindings. ``GET /api/authority/workflow-bindings``."""
517
+ tid, tev = self._target_query_params(target_org_id, target_env)
421
518
  qs = _query_string({
422
519
  "workflow_ref": workflow_ref,
423
520
  "workflow_id": workflow_id,
424
521
  "status": status,
425
- "project_slug": app_slug,
426
- "environment": env,
427
- "target_project_id": target_org_id,
428
- "target_environment": target_env,
522
+ "app_slug": app_slug,
523
+ "env": env,
524
+ "target_org_id": tid,
525
+ "target_env": tev,
429
526
  "limit": limit,
430
527
  "offset": offset,
431
528
  })
@@ -444,13 +541,14 @@ class AuthorityNamespace:
444
541
  offset: int = 0,
445
542
  ) -> Dict[str, Any]:
446
543
  """List Authority workflow publications. ``GET /api/authority/workflow-publications``."""
544
+ tid, tev = self._target_query_params(target_org_id, target_env)
447
545
  qs = _query_string({
448
546
  "workflow_ref": workflow_ref,
449
547
  "status": status,
450
- "project_slug": app_slug,
451
- "environment": env,
452
- "target_project_id": target_org_id,
453
- "target_environment": target_env,
548
+ "app_slug": app_slug,
549
+ "env": env,
550
+ "target_org_id": tid,
551
+ "target_env": tev,
454
552
  "limit": limit,
455
553
  "offset": offset,
456
554
  })
@@ -510,11 +608,12 @@ class AuthorityNamespace:
510
608
  """Get an Authority company. ``GET /api/authority/companies/{company}``."""
511
609
  if not company_slug:
512
610
  raise ValueError("company_slug is required")
611
+ tid, tev = self._target_query_params(target_org_id, target_env)
513
612
  qs = _query_string({
514
- "project_slug": app_slug,
515
- "environment": env,
516
- "target_project_id": target_org_id,
517
- "target_environment": target_env,
613
+ "app_slug": app_slug,
614
+ "env": env,
615
+ "target_org_id": tid,
616
+ "target_env": tev,
518
617
  })
519
618
  return await self._get(
520
619
  f"/api/authority/companies/{quote(company_slug, safe='')}{qs}",
@@ -534,11 +633,12 @@ class AuthorityNamespace:
534
633
  timeout: Optional[float] = None,
535
634
  ) -> Dict[str, Any]:
536
635
  """List Authority companies. ``GET /api/authority/companies``."""
636
+ tid, tev = self._target_query_params(target_org_id, target_env)
537
637
  qs = _query_string({
538
- "project_slug": app_slug,
539
- "environment": env,
540
- "target_project_id": target_org_id,
541
- "target_environment": target_env,
638
+ "app_slug": app_slug,
639
+ "env": env,
640
+ "target_org_id": tid,
641
+ "target_env": tev,
542
642
  "status": status,
543
643
  "limit": limit,
544
644
  "offset": offset,
@@ -584,7 +684,7 @@ class AuthorityNamespace:
584
684
  "action": action,
585
685
  "run_id": run_id,
586
686
  "reason": reason,
587
- "shared_project_slug": shared_app_slug,
687
+ "shared_app_slug": shared_app_slug,
588
688
  "region": region,
589
689
  "system": system,
590
690
  "github_mode": github_mode,
@@ -625,8 +725,8 @@ class AuthorityNamespace:
625
725
  if not company_slug:
626
726
  raise ValueError("company_slug is required")
627
727
  qs = _query_string({
628
- "project_slug": app_slug,
629
- "environment": env,
728
+ "app_slug": app_slug,
729
+ "env": env,
630
730
  "run_id": run_id,
631
731
  })
632
732
  return await self._get(
@@ -647,11 +747,12 @@ class AuthorityNamespace:
647
747
  """Get full Authority dossier for a company. ``GET /api/authority/dossiers/company/{company}``."""
648
748
  if not company_slug:
649
749
  raise ValueError("company_slug is required")
750
+ tid, tev = self._target_query_params(target_org_id, target_env)
650
751
  qs = _query_string({
651
- "project_slug": app_slug,
652
- "environment": env,
653
- "target_project_id": target_org_id,
654
- "target_environment": target_env,
752
+ "app_slug": app_slug,
753
+ "env": env,
754
+ "target_org_id": tid,
755
+ "target_env": tev,
655
756
  })
656
757
  return await self._get(
657
758
  f"/api/authority/dossiers/company/{quote(company_slug, safe='')}{qs}",
@@ -726,11 +827,12 @@ class AuthorityNamespace:
726
827
  timeout: Optional[float] = None,
727
828
  ) -> Dict[str, Any]:
728
829
  """List deploys. ``GET /api/authority/deploys``."""
830
+ tid, tev = self._target_query_params(target_org_id, target_env)
729
831
  qs = _query_string({
730
- "project_slug": app_slug,
731
- "environment": env,
732
- "target_project_id": target_org_id,
733
- "target_environment": target_env,
832
+ "app_slug": app_slug,
833
+ "env": env,
834
+ "target_org_id": tid,
835
+ "target_env": tev,
734
836
  "repo_full_name": repo_full_name,
735
837
  "status": status,
736
838
  "limit": limit,
@@ -753,6 +855,8 @@ class AuthorityNamespace:
753
855
  company: Optional[str] = None,
754
856
  subject: Optional[str] = None,
755
857
  metadata: Optional[Dict[str, Any]] = None,
858
+ force: Optional[bool] = None,
859
+ allow_duplicate_sha: Optional[bool] = None,
756
860
  app_slug: Optional[str] = None,
757
861
  env: Optional[str] = None,
758
862
  target_org_id: Optional[str] = None,
@@ -774,6 +878,8 @@ class AuthorityNamespace:
774
878
  "company": company,
775
879
  "subject": subject,
776
880
  "metadata": metadata,
881
+ "force": force,
882
+ "allow_duplicate_sha": allow_duplicate_sha,
777
883
  **self._initiator(initiator_type, initiator_id, idempotency_key),
778
884
  **self._scope(app_slug, env, target_org_id, target_env),
779
885
  })
@@ -882,7 +988,7 @@ class AuthorityNamespace:
882
988
  *,
883
989
  variant_slug: str,
884
990
  version: str,
885
- manifest_path: str,
991
+ manifest_path: Optional[str] = None,
886
992
  status: str = "published",
887
993
  storage_app_slug: Optional[str] = None,
888
994
  storage_env: Optional[str] = None,
@@ -898,19 +1004,29 @@ class AuthorityNamespace:
898
1004
  idempotency_key: Optional[str] = None,
899
1005
  timeout: Optional[float] = None,
900
1006
  ) -> Dict[str, Any]:
901
- """Publish a managed-client release. ``POST /api/authority/clients/releases``."""
1007
+ """
1008
+ Create or upsert a managed-client release.
1009
+
1010
+ ``POST /api/authority/clients/releases``.
1011
+
1012
+ Use ``status="proposed"`` to start the release FSM without publishing;
1013
+ ``manifest_path`` may be omitted for proposed releases. Use
1014
+ ``approve_client_release`` → ``publish_approved_client_release`` →
1015
+ ``distribute_client_release`` for staged rollout.
1016
+ """
902
1017
  if not variant_slug:
903
1018
  raise ValueError("publish_client_release requires variant_slug")
904
1019
  if not version:
905
1020
  raise ValueError("publish_client_release requires version")
906
- if not manifest_path:
907
- raise ValueError("publish_client_release requires manifest_path")
1021
+ status_eff = str(status or "published").strip().lower()
1022
+ if not manifest_path and status_eff != "proposed":
1023
+ raise ValueError("publish_client_release requires manifest_path unless status is proposed")
908
1024
  body = _compact({
909
1025
  "variant_slug": variant_slug,
910
1026
  "version": version,
911
1027
  "status": status,
912
- "storage_project_slug": storage_app_slug,
913
- "storage_environment": storage_env,
1028
+ "storage_app_slug": storage_app_slug,
1029
+ "storage_env": storage_env,
914
1030
  "storage_category": storage_category,
915
1031
  "manifest_path": manifest_path,
916
1032
  "bootstrapper_path": bootstrapper_path,
@@ -926,6 +1042,95 @@ class AuthorityNamespace:
926
1042
  timeout=self._http_timeout(timeout, 30.0),
927
1043
  )
928
1044
 
1045
+ async def get_client_release(
1046
+ self,
1047
+ release_id: str,
1048
+ *,
1049
+ app_slug: Optional[str] = None,
1050
+ env: Optional[str] = None,
1051
+ timeout: Optional[float] = None,
1052
+ ) -> Dict[str, Any]:
1053
+ """Fetch one release by id. ``GET /api/authority/clients/releases/{release_id}``."""
1054
+ if not release_id:
1055
+ raise ValueError("get_client_release requires release_id")
1056
+ qs = _query_string({"app_slug": app_slug, "env": env})
1057
+ return await self._get(
1058
+ f"/api/authority/clients/releases/{quote(release_id, safe='')}{qs}",
1059
+ timeout=self._http_timeout(timeout, 30.0),
1060
+ )
1061
+
1062
+ async def approve_client_release(
1063
+ self,
1064
+ release_id: str,
1065
+ *,
1066
+ app_slug: Optional[str] = None,
1067
+ env: Optional[str] = None,
1068
+ initiator_type: Optional[str] = None,
1069
+ initiator_id: Optional[str] = None,
1070
+ idempotency_key: Optional[str] = None,
1071
+ timeout: Optional[float] = None,
1072
+ ) -> Dict[str, Any]:
1073
+ """Approve a proposed release. ``POST /api/authority/clients/releases/{id}/approve``."""
1074
+ if not release_id:
1075
+ raise ValueError("approve_client_release requires release_id")
1076
+ body = _compact({
1077
+ **self._initiator(initiator_type, initiator_id, idempotency_key),
1078
+ **self._scope(app_slug, env, None, None),
1079
+ })
1080
+ return await self._post(
1081
+ f"/api/authority/clients/releases/{quote(release_id, safe='')}/approve",
1082
+ body,
1083
+ timeout=self._http_timeout(timeout, 30.0),
1084
+ )
1085
+
1086
+ async def publish_approved_client_release(
1087
+ self,
1088
+ release_id: str,
1089
+ *,
1090
+ app_slug: Optional[str] = None,
1091
+ env: Optional[str] = None,
1092
+ initiator_type: Optional[str] = None,
1093
+ initiator_id: Optional[str] = None,
1094
+ idempotency_key: Optional[str] = None,
1095
+ timeout: Optional[float] = None,
1096
+ ) -> Dict[str, Any]:
1097
+ """Publish an approved release (gateway health handshake). ``POST .../publish``."""
1098
+ if not release_id:
1099
+ raise ValueError("publish_approved_client_release requires release_id")
1100
+ body = _compact({
1101
+ **self._initiator(initiator_type, initiator_id, idempotency_key),
1102
+ **self._scope(app_slug, env, None, None),
1103
+ })
1104
+ return await self._post(
1105
+ f"/api/authority/clients/releases/{quote(release_id, safe='')}/publish",
1106
+ body,
1107
+ timeout=self._http_timeout(timeout, 30.0),
1108
+ )
1109
+
1110
+ async def distribute_client_release(
1111
+ self,
1112
+ release_id: str,
1113
+ *,
1114
+ app_slug: Optional[str] = None,
1115
+ env: Optional[str] = None,
1116
+ initiator_type: Optional[str] = None,
1117
+ initiator_id: Optional[str] = None,
1118
+ idempotency_key: Optional[str] = None,
1119
+ timeout: Optional[float] = None,
1120
+ ) -> Dict[str, Any]:
1121
+ """Mark a published release as distributed. ``POST .../distribute``."""
1122
+ if not release_id:
1123
+ raise ValueError("distribute_client_release requires release_id")
1124
+ body = _compact({
1125
+ **self._initiator(initiator_type, initiator_id, idempotency_key),
1126
+ **self._scope(app_slug, env, None, None),
1127
+ })
1128
+ return await self._post(
1129
+ f"/api/authority/clients/releases/{quote(release_id, safe='')}/distribute",
1130
+ body,
1131
+ timeout=self._http_timeout(timeout, 30.0),
1132
+ )
1133
+
929
1134
  async def create_client_bootstrap_session(
930
1135
  self,
931
1136
  *,
@@ -987,8 +1192,8 @@ class AuthorityNamespace:
987
1192
  ) -> Dict[str, Any]:
988
1193
  """List managed client installations. ``GET /api/authority/clients/installations``."""
989
1194
  qs = _query_string({
990
- "project_slug": app_slug,
991
- "environment": env,
1195
+ "app_slug": app_slug,
1196
+ "env": env,
992
1197
  "status": status,
993
1198
  "variant_slug": variant_slug,
994
1199
  "company": company,
dominus/namespaces/db.py CHANGED
@@ -449,7 +449,7 @@ class DbNamespace:
449
449
  async def provision_neon_complete(
450
450
  self,
451
451
  *,
452
- project_slug: str,
452
+ app_slug: str,
453
453
  region: Optional[str] = None,
454
454
  timeout: float = 300.0,
455
455
  ) -> Dict[str, Any]:
@@ -459,7 +459,7 @@ class DbNamespace:
459
459
  endpoint="/api/provision/complete",
460
460
  method="POST",
461
461
  body={
462
- "project_slug": project_slug,
462
+ "app_slug": app_slug,
463
463
  "region": region or "aws-us-east-1",
464
464
  },
465
465
  use_gateway=True,
@@ -469,7 +469,7 @@ class DbNamespace:
469
469
  async def provision_neon_delete(
470
470
  self,
471
471
  *,
472
- project_slug: str,
472
+ app_slug: str,
473
473
  timeout: float = 120.0,
474
474
  ) -> Dict[str, Any]:
475
475
  """Neon teardown via ``DELETE /api/provision/delete``."""
@@ -477,7 +477,7 @@ class DbNamespace:
477
477
  return await self._client._request(
478
478
  endpoint="/api/provision/delete",
479
479
  method="DELETE",
480
- body={"project_slug": project_slug},
480
+ body={"app_slug": app_slug},
481
481
  use_gateway=True,
482
482
  timeout=cap,
483
483
  )
@@ -0,0 +1,39 @@
1
+ """Thin Deployer control-plane namespace."""
2
+ from typing import Any, Dict, Optional, TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING:
5
+ from ..start import Dominus
6
+
7
+
8
+ def _normalize_deployer_path(path: str) -> str:
9
+ trimmed = path.strip()
10
+ normalized = trimmed if trimmed.startswith("/") else f"/{trimmed}"
11
+ if normalized == "/svc/deployer" or normalized.startswith("/svc/deployer/"):
12
+ return normalized
13
+ if normalized == "/api/deployer" or normalized.startswith("/api/deployer/"):
14
+ return normalized
15
+ return f"/svc/deployer{normalized}"
16
+
17
+
18
+ class DeployerNamespace:
19
+ """Deployer operator control-plane routes used by Mothership and MCP."""
20
+
21
+ def __init__(self, client: "Dominus"):
22
+ self._client = client
23
+
24
+ async def request(
25
+ self,
26
+ path: str,
27
+ *,
28
+ method: str = "GET",
29
+ body: Any = None,
30
+ headers: Optional[Dict[str, str]] = None,
31
+ timeout: float = 30.0,
32
+ ) -> Any:
33
+ return await self._client.gateway_fetch(
34
+ _normalize_deployer_path(path),
35
+ method=method,
36
+ body=body,
37
+ headers=headers,
38
+ timeout=timeout,
39
+ )
@@ -199,7 +199,7 @@ class SecretsNamespace:
199
199
  endpoint="/api/warden/secrets",
200
200
  body={
201
201
  "action": "list-all-environments",
202
- "project_id": infisical_project_id,
202
+ "infisical_project_id": infisical_project_id,
203
203
  },
204
204
  use_gateway=True,
205
205
  )
@@ -1,7 +1,7 @@
1
1
  """
2
2
  Sync Namespace - KV synchronization operations.
3
3
 
4
- Provides manual trigger for KV sync (token + project metadata)
4
+ Provides manual trigger for KV sync (token + app metadata)
5
5
  from database to Cloudflare KV. Routes through gateway to sync-worker.
6
6
 
7
7
  The sync worker also runs automatically at 4AM UTC via cron.
@@ -11,7 +11,7 @@ Usage:
11
11
 
12
12
  # Trigger manual sync (admin only)
13
13
  result = await dominus.sync.trigger_sync()
14
- print(f"Synced {result['tokens_synced']} tokens, {result['projects_synced']} projects")
14
+ print(f"Synced {result['tokens_synced']} tokens, {result['apps_synced']} apps")
15
15
 
16
16
  # Health check
17
17
  health = await dominus.sync.get_health()
@@ -26,7 +26,7 @@ class SyncNamespace:
26
26
  """
27
27
  KV sync namespace.
28
28
 
29
- Admin-only operations that synchronize token hashes and project
29
+ Admin-only operations that synchronize token hashes and app
30
30
  metadata from the database into Cloudflare KV. Purges stale
31
31
  entries and re-seeds current data.
32
32
  """
@@ -54,15 +54,15 @@ class SyncNamespace:
54
54
  """
55
55
  Trigger a manual KV sync. Requires admin system level.
56
56
 
57
- Synchronizes token hashes and project metadata from the database
57
+ Synchronizes token hashes and app metadata from the database
58
58
  into Cloudflare KV. Purges stale entries and re-seeds current data.
59
59
 
60
60
  Args:
61
61
  timeout: Request timeout in seconds (default 60; Mothership uses 180).
62
62
 
63
63
  Returns:
64
- {tokens_synced, projects_synced, tokens_deleted,
65
- projects_deleted, errors, duration_ms, triggered_at}
64
+ {tokens_synced, apps_synced, tokens_deleted,
65
+ apps_deleted, errors, duration_ms, triggered_at}
66
66
  """
67
67
  return await self._api(
68
68
  "/api/sync/",
@@ -0,0 +1,39 @@
1
+ """Thin Warden control-plane namespace."""
2
+ from typing import Any, Dict, Optional, TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING:
5
+ from ..start import Dominus
6
+
7
+
8
+ def _normalize_warden_path(path: str) -> str:
9
+ trimmed = path.strip()
10
+ normalized = trimmed if trimmed.startswith("/") else f"/{trimmed}"
11
+ if normalized == "/svc/warden" or normalized.startswith("/svc/warden/"):
12
+ return normalized
13
+ if normalized == "/api/warden" or normalized.startswith("/api/warden/"):
14
+ return normalized
15
+ return f"/svc/warden{normalized}"
16
+
17
+
18
+ class WardenNamespace:
19
+ """Warden operator control-plane routes used by Mothership and MCP."""
20
+
21
+ def __init__(self, client: "Dominus"):
22
+ self._client = client
23
+
24
+ async def request(
25
+ self,
26
+ path: str,
27
+ *,
28
+ method: str = "GET",
29
+ body: Any = None,
30
+ headers: Optional[Dict[str, str]] = None,
31
+ timeout: float = 30.0,
32
+ ) -> Any:
33
+ return await self._client.gateway_fetch(
34
+ _normalize_warden_path(path),
35
+ method=method,
36
+ body=body,
37
+ headers=headers,
38
+ timeout=timeout,
39
+ )
@@ -246,9 +246,9 @@ class WorkflowNamespace:
246
246
  if instance_id:
247
247
  body["instance_id"] = instance_id
248
248
  if target_project_id:
249
- body["target_project_id"] = target_project_id
249
+ body["target_org_id"] = target_project_id
250
250
  if target_environment:
251
- body["target_environment"] = target_environment
251
+ body["target_env"] = target_environment
252
252
  return self._authority_mutation_body(
253
253
  body,
254
254
  idempotency_key=idempotency_key,
@@ -1035,9 +1035,9 @@ class WorkflowNamespace:
1035
1035
  if status:
1036
1036
  params.append(f"status={status}")
1037
1037
  if target_project_id:
1038
- params.append(f"target_project_id={target_project_id}")
1038
+ params.append(f"target_org_id={target_project_id}")
1039
1039
  if target_environment:
1040
- params.append(f"target_environment={target_environment}")
1040
+ params.append(f"target_env={target_environment}")
1041
1041
 
1042
1042
  result = await self._api(
1043
1043
  endpoint=f"/api/authority/runs?{'&'.join(params)}",
@@ -1114,9 +1114,9 @@ class WorkflowNamespace:
1114
1114
  if trigger_artifact:
1115
1115
  body["trigger_artifact"] = trigger_artifact
1116
1116
  if target_project_id:
1117
- body["target_project_id"] = target_project_id
1117
+ body["target_org_id"] = target_project_id
1118
1118
  if target_environment:
1119
- body["target_environment"] = target_environment
1119
+ body["target_env"] = target_environment
1120
1120
  return await self._api(
1121
1121
  endpoint=f"/api/authority/runs/{workflow_id}/nudge",
1122
1122
  body=self._authority_mutation_body(
@@ -1202,9 +1202,9 @@ class WorkflowNamespace:
1202
1202
  if trigger_artifact:
1203
1203
  body["trigger_artifact"] = trigger_artifact
1204
1204
  if target_project_id:
1205
- body["target_project_id"] = target_project_id
1205
+ body["target_org_id"] = target_project_id
1206
1206
  if target_environment:
1207
- body["target_environment"] = target_environment
1207
+ body["target_env"] = target_environment
1208
1208
  return await self._api(
1209
1209
  endpoint=f"/api/authority/runs/{workflow_id}/retry",
1210
1210
  body=self._authority_mutation_body(
@@ -1385,9 +1385,9 @@ class WorkflowNamespace:
1385
1385
  if self._is_authority_run_id(execution_id):
1386
1386
  body: Dict[str, Any] = {}
1387
1387
  if target_project_id:
1388
- body["target_project_id"] = target_project_id
1388
+ body["target_org_id"] = target_project_id
1389
1389
  if target_environment:
1390
- body["target_environment"] = target_environment
1390
+ body["target_env"] = target_environment
1391
1391
  return await self._api(
1392
1392
  endpoint=f"/api/authority/runs/{execution_id}/cancel",
1393
1393
  body=self._authority_mutation_body(
dominus/start.py CHANGED
@@ -172,6 +172,12 @@ class Dominus:
172
172
  from .namespaces.authority import AuthorityNamespace
173
173
  self.authority = AuthorityNamespace(self)
174
174
 
175
+ # Thin operator control-plane namespaces (Mothership / MCP parity)
176
+ from .namespaces.deployer import DeployerNamespace
177
+ from .namespaces.warden import WardenNamespace
178
+ self.deployer = DeployerNamespace(self)
179
+ self.warden = WardenNamespace(self)
180
+
175
181
  # Cache for JWT public key
176
182
  self._public_key_cache = None
177
183
 
@@ -475,6 +481,131 @@ class Dominus:
475
481
 
476
482
  return result.get("data", {})
477
483
 
484
+ async def gateway_fetch(
485
+ self,
486
+ path: str,
487
+ *,
488
+ method: str = "GET",
489
+ body: Optional[Dict[str, Any]] = None,
490
+ headers: Optional[Dict[str, str]] = None,
491
+ timeout: float = 30.0,
492
+ ) -> Any:
493
+ """Gateway `/svc/*` fetch with mixed JSON/base64 wire handling.
494
+
495
+ Mirrors the Node SDK `DominusClient.gatewayFetch()` contract so Python
496
+ callers can use the same remaining operator control-plane surfaces.
497
+ """
498
+ await self._ensure_ready()
499
+ from .helpers.core import _ensure_valid_jwt
500
+ jwt = await _ensure_valid_jwt(_TOKEN, _BASE_URL)
501
+
502
+ path = path.strip()
503
+ if not path.startswith("/"):
504
+ path = f"/{path}"
505
+
506
+ is_base64 = (
507
+ "/svc/warden/secrets" in path
508
+ or "/svc/secrets/" in path
509
+ or "/svc/admin/" in path
510
+ )
511
+ decode_base64 = (
512
+ is_base64
513
+ or "/svc/database/" in path
514
+ or "/svc/sync/" in path
515
+ or "/svc/authority/" in path
516
+ )
517
+ is_get = method.upper() in {"GET", "HEAD"}
518
+
519
+ from .helpers.trace import get_current_trace_id, get_current_span_id
520
+
521
+ req_headers = {
522
+ "Authorization": f"Bearer {jwt}",
523
+ "X-Trace-Id": get_current_trace_id(),
524
+ "X-Parent-Span-Id": get_current_span_id(),
525
+ }
526
+ if headers:
527
+ req_headers.update(headers)
528
+
529
+ request_content = None
530
+ request_json = None
531
+ if not is_get and body is not None:
532
+ if is_base64:
533
+ req_headers["Content-Type"] = "text/plain"
534
+ request_content = base64.b64encode(json.dumps(body).encode()).decode()
535
+ else:
536
+ req_headers["Content-Type"] = "application/json"
537
+ request_json = body
538
+
539
+ try:
540
+ async with httpx.AsyncClient(base_url=_GATEWAY_URL, headers=req_headers, timeout=timeout) as client:
541
+ response = await client.request(
542
+ method.upper(),
543
+ path,
544
+ content=request_content,
545
+ json=request_json,
546
+ )
547
+ except httpx.TimeoutException as exc:
548
+ raise DominusTimeoutError("Request timed out", endpoint=path) from exc
549
+ except httpx.NetworkError as exc:
550
+ raise DominusConnectionError(f"Request failed: {exc}", endpoint=path) from exc
551
+
552
+ def _decode_error_payload(text: str) -> Dict[str, Any]:
553
+ if not text:
554
+ return {}
555
+ try:
556
+ from .helpers.core import _decode_json_or_b64_json
557
+
558
+ decoded = _decode_json_or_b64_json(text)
559
+ return decoded if isinstance(decoded, dict) else {"detail": decoded}
560
+ except Exception:
561
+ return {"detail": text}
562
+
563
+ if response.is_error:
564
+ error_payload = _decode_error_payload(response.text)
565
+ nested = error_payload.get("error")
566
+ nested_err: Dict[str, Any] = nested if isinstance(nested, dict) else {}
567
+ error_message = (
568
+ error_payload.get("message")
569
+ or (nested_err.get("message") if nested_err else None)
570
+ or (nested if isinstance(nested, str) else None)
571
+ or error_payload.get("error")
572
+ or error_payload.get("detail")
573
+ or f"HTTP {response.status_code}"
574
+ )
575
+ error_details = error_payload.get("details")
576
+ if not isinstance(error_details, dict):
577
+ error_details = {}
578
+ for src in (error_payload, nested_err):
579
+ for key in ("code", "category", "retryable", "trace_id", "request_id"):
580
+ if key in src and key not in error_details:
581
+ error_details[key] = src[key]
582
+ raise_for_status(response.status_code, str(error_message), error_details, path)
583
+
584
+ text = response.text.strip()
585
+ if not text:
586
+ return {}
587
+
588
+ if decode_base64:
589
+ decoded = base64.b64decode(text.encode("utf-8")).decode("utf-8")
590
+ result = json.loads(decoded)
591
+ else:
592
+ try:
593
+ result = json.loads(text)
594
+ except json.JSONDecodeError:
595
+ return text
596
+
597
+ if isinstance(result, dict) and result.get("success") is False:
598
+ error_msg = result.get("error") or result.get("message") or "Unknown error"
599
+ error_details = result.get("details")
600
+ if not isinstance(error_details, dict):
601
+ error_details = {}
602
+ for key in ("code", "category", "retryable", "trace_id", "request_id"):
603
+ if key in result:
604
+ error_details[key] = result[key]
605
+ raise DominusError(str(error_msg), details=error_details, endpoint=path)
606
+
607
+ return result
608
+
478
609
  async def _stream_request(
479
610
  self,
480
611
  endpoint: str,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dominus-sdk-python
3
- Version: 3.0.2
3
+ Version: 3.0.4
4
4
  Summary: Python SDK for the Dominus gateway-first platform
5
5
  Author-email: CareBridge Systems <dev@carebridge.io>
6
6
  License: Proprietary
@@ -41,7 +41,7 @@ Async Python SDK for the Dominus gateway-first service plane.
41
41
  - Namespace-first API with a small root shortcut surface
42
42
  - Gateway-scoped client mode for MCP and other user-JWT sessions
43
43
  - Local helpers for JWT verification, trace propagation, retries, and console capture
44
- - Current package version: `3.0.2`
44
+ - Current package version: `3.0.4`
45
45
 
46
46
  ## Install
47
47
 
@@ -95,6 +95,7 @@ JWT and selected scope headers directly through Gateway.
95
95
 
96
96
  ## Transport Model
97
97
 
98
+ - Default HTTP targets are the production gateway (`https://gateway.getdominus.app`); they do not change based on your app’s git branch or PyPI package variant. Set `DOMINUS_GATEWAY_URL` (or `DOMINUS_BASE_URL` / `DOMINUS_JWT_URL`) only for local or custom routing.
98
99
  - `DOMINUS_TOKEN` is exchanged for a JWT through `POST /jwt/mint`
99
100
  - Service JWTs are cached for 14 minutes with a 60-second refresh window
100
101
  - Auth-required worker routes still send base64-encoded JSON bodies as `text/plain`
@@ -125,6 +126,8 @@ JWT and selected scope headers directly through Gateway.
125
126
  | `processor` | Processor | Batch and single-job processing |
126
127
  | `sync` | Sync Worker | KV synchronization |
127
128
  | `authority` | Dominus Authority | Runs, companies, deploys, managed clients, context |
129
+ | `deployer` | Deployer | Thin operator control-plane request surface |
130
+ | `warden` | Warden | Thin operator control-plane request surface |
128
131
  | `fastapi` | Local decorators | `@jwt`, `@psk`, `@scopes(...)` |
129
132
 
130
133
  ## Root Shortcuts
@@ -1,8 +1,8 @@
1
- dominus/__init__.py,sha256=krEGWdgI_zBFT-v0wW_k-L7OfACx0bjnpLOzGpZZm9o,6778
1
+ dominus/__init__.py,sha256=iUwZcODXPT-6xyyB6izXFLvhfhZzlsKoLIbfVhpMhDE,6924
2
2
  dominus/errors.py,sha256=NthcR-o1Q1nQsE3ZSHStcW_RdZ8LQ06mPDSenY1txgM,8547
3
- dominus/start.py,sha256=wegzHQJKKLiKdNJ4t1TaY02X1h5Tw9L2PcN8TwHg-Bs,43541
3
+ dominus/start.py,sha256=bmnIXJEYw5uEQGkwEVV2iiR_B07GhbQEiLMLIlyjsZc,48694
4
4
  dominus/config/__init__.py,sha256=nvLLNh4dM_MCqcfF3XFS2NnVn44q0RYHEfAPP-2G5To,434
5
- dominus/config/endpoints.py,sha256=U9ry8yHobLHlQ_uq0hNIMiX9mlt2gghCAMzeLnWxeH4,3970
5
+ dominus/config/endpoints.py,sha256=IFioVY3jQ5Mqy65L6rNbEXyPUfYTaXRQkfyGdKv33A8,4140
6
6
  dominus/helpers/__init__.py,sha256=cyoBvw1QJugtGt0gYitIz1yxOaMmBa-wMXqbh-fi4PU,61
7
7
  dominus/helpers/auth.py,sha256=IVZLelikaGIAZvyc-q7EoPd8fBNVlGffGXQkTP4x5Fk,633
8
8
  dominus/helpers/cache.py,sha256=L8eW2JC_EHiO48eJ4SMcIF2SR22Xp9htK0PRZxamfKs,5947
@@ -11,15 +11,16 @@ dominus/helpers/core.py,sha256=l3pCXFIYo6LH3Ef6qY3LcZtqEI6DZ_bqc_0QebrVfSg,38115
11
11
  dominus/helpers/crypto.py,sha256=R1yZittVykTQzGVJdb_uMQuF3Y1uGuQRJHZ1BTWT9lU,3014
12
12
  dominus/helpers/sse.py,sha256=eZspL8CEIShU9hLzfT3tvRYDxBDkmtLP1RChnAfrvHY,3886
13
13
  dominus/helpers/trace.py,sha256=i0dRYR4Y46LAnQr0Cm5htbyZ0VA4UQCLMx-q2CQQXSc,2686
14
- dominus/namespaces/__init__.py,sha256=J7wc2LuUQwdbo464xRWlT66fzLo3vmaCbBQULoKmgVQ,1246
14
+ dominus/namespaces/__init__.py,sha256=Y26ac5kwZaJvZ3EqWPyZH5470Vei_kIYuTUWjZFYTlg,1370
15
15
  dominus/namespaces/admin.py,sha256=qkGoteAJ6cqdNub4zL1mtyxAQtsM3-nUplRSgw2fMZY,1640
16
16
  dominus/namespaces/ai.py,sha256=Kr_eY-SkEfC-b1fhVVv40pXn_GHkxRzMGD47WoTgu9M,48555
17
17
  dominus/namespaces/artifacts.py,sha256=MgjkjSmUP_5XGTAFU2UQ1VU3Vju3kVuvDqxChosP2J0,22246
18
18
  dominus/namespaces/auth.py,sha256=aCsdLxLTRlZPi8wy0HDxstYtXjbW6W1y-n5TxQ-mCDg,67510
19
- dominus/namespaces/authority.py,sha256=eicstU5TGC7VE2f0QTn-OU97OwIwQCVkaBsi_X_-V6Y,42950
19
+ dominus/namespaces/authority.py,sha256=P0FIG4SMoGHHdxO7gwejozLElublIvHlsa4suTSp4UQ,50954
20
20
  dominus/namespaces/courier.py,sha256=7ZuwTWzVGBPTnqPV1VqPdme6PkPyhQOddwaI1wxrlE8,8324
21
- dominus/namespaces/db.py,sha256=Nywnx7M8r8MC6bodbLuBL7E8msWaDmHjUxM-NcLNKGY,15181
21
+ dominus/namespaces/db.py,sha256=dv4IZACziub7OE8i_4q_Z31uVYJglE12TFkFIbFnYjw,15157
22
22
  dominus/namespaces/ddl.py,sha256=NTpd3V3595qcBheUZfFq4tQiAZsyYH9O8GR9OZ_czK8,25844
23
+ dominus/namespaces/deployer.py,sha256=HbaCgfB_uunHEZxKcjh-XKzIWiOS2F0Y_KMpgiaUu7w,1159
23
24
  dominus/namespaces/fastapi.py,sha256=AZOjUIJ5tznJVLkpctNa606XRTv5IEkjvrINEHgkeuE,8745
24
25
  dominus/namespaces/files.py,sha256=ueBMv7Wa8wCDUmF-A_JgXKdXHxIZx-sjUfYIUzWCEbI,13720
25
26
  dominus/namespaces/health.py,sha256=sa2A7JdCk0pEq9VqRiwEAXEBbtWUz7QXaA6zS531BUo,1377
@@ -28,12 +29,13 @@ dominus/namespaces/logs.py,sha256=8EtUBChdKii34wUYID9YUEtujUBJypPSVjKlYKZbv0A,14
28
29
  dominus/namespaces/portal.py,sha256=vf0Vu_12yS4_fto7sVCau5vQtghml7Wh7J2-XJnO2zA,15595
29
30
  dominus/namespaces/processor.py,sha256=gk-vvWfBTU9LkV34OaB4VdftArhTE67tfhlUtY0YglI,2678
30
31
  dominus/namespaces/redis.py,sha256=RWIaL9X9srVUJ1hxEX_i6SAJKeA0P2nLdohSMRlScZg,12335
31
- dominus/namespaces/secrets.py,sha256=55hqV-ioXfjHbnBFIA6U27Bu8YvPGgx9EKRXkBZWYD8,6243
32
+ dominus/namespaces/secrets.py,sha256=od8AKgENwW6U-kVfIX3DSphXKeJA6XC-SxbGqsxhhUk,6253
32
33
  dominus/namespaces/secure.py,sha256=9idGY5R6k7b-JM1SAF_1Gt-YV5OempyxFBflgLJieLo,7168
33
- dominus/namespaces/sync.py,sha256=4W11ehCfIaqH8PzkQEi_or6lCdr7CYLZAemmlUIYYEk,2226
34
- dominus/namespaces/workflow.py,sha256=QE7zy6IplEGOi4ztHtWOBCncYtXXRnWW8TsKc0j4rAE,47264
34
+ dominus/namespaces/sync.py,sha256=mGwMNwc_iWoKgS94n1staPdsKBHNvliMG7omokl7Qmk,2198
35
+ dominus/namespaces/warden.py,sha256=ebbCeBJJwK9uALEj2aDbvWJ5HTlOXOpXJOwzokH1cso,1139
36
+ dominus/namespaces/workflow.py,sha256=1LMzlYoVImtdpnuenJDtpx7dB2wdNVE3tSBFn-ZAyJA,47204
35
37
  dominus/services/__init__.py,sha256=LQl5sx6DHhX1xCN3MRoUgffxqwm3Mfm525hijyFods8,43
36
- dominus_sdk_python-3.0.2.dist-info/METADATA,sha256=_EhVtGqMyj7sSZMHSBL3SSv8TT-ucexOsj2bWGRHU2o,5560
37
- dominus_sdk_python-3.0.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
38
- dominus_sdk_python-3.0.2.dist-info/top_level.txt,sha256=515zxMIbX0DpheRbjvNqKIt_AFqdFjX41jtyp_SqLf4,8
39
- dominus_sdk_python-3.0.2.dist-info/RECORD,,
38
+ dominus_sdk_python-3.0.4.dist-info/METADATA,sha256=YqcpYKHa6yIDbVquZoaUlaILlULRMl_66UBBLuJ3jRc,5967
39
+ dominus_sdk_python-3.0.4.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
40
+ dominus_sdk_python-3.0.4.dist-info/top_level.txt,sha256=515zxMIbX0DpheRbjvNqKIt_AFqdFjX41jtyp_SqLf4,8
41
+ dominus_sdk_python-3.0.4.dist-info/RECORD,,