dominus-sdk-python 2.12.0__tar.gz → 2.13.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-2.13.0/PKG-INFO +179 -0
- dominus_sdk_python-2.13.0/README.md +137 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/__init__.py +12 -1
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/helpers/core.py +14 -29
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/__init__.py +9 -1
- dominus_sdk_python-2.13.0/dominus/namespaces/artifacts.py +150 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/auth.py +65 -1
- dominus_sdk_python-2.13.0/dominus/namespaces/jobs.py +190 -0
- dominus_sdk_python-2.13.0/dominus/namespaces/processor.py +99 -0
- dominus_sdk_python-2.13.0/dominus/namespaces/sync.py +72 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/workflow.py +74 -69
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/start.py +20 -5
- dominus_sdk_python-2.13.0/dominus_sdk_python.egg-info/PKG-INFO +179 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus_sdk_python.egg-info/SOURCES.txt +4 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/pyproject.toml +1 -1
- dominus_sdk_python-2.12.0/PKG-INFO +0 -92
- dominus_sdk_python-2.12.0/README.md +0 -50
- dominus_sdk_python-2.12.0/dominus_sdk_python.egg-info/PKG-INFO +0 -92
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/config/__init__.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/config/endpoints.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/errors.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/helpers/__init__.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/helpers/auth.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/helpers/cache.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/helpers/console_capture.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/helpers/crypto.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/helpers/sse.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/admin.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/ai.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/courier.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/db.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/ddl.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/fastapi.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/files.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/health.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/logs.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/open.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/oracle/__init__.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/oracle/audio_capture.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/oracle/oracle_websocket.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/oracle/session.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/oracle/types.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/oracle/vad_gate.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/portal.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/redis.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/secrets.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/namespaces/secure.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus/services/__init__.py +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus_sdk_python.egg-info/dependency_links.txt +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus_sdk_python.egg-info/requires.txt +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/dominus_sdk_python.egg-info/top_level.txt +0 -0
- {dominus_sdk_python-2.12.0 → dominus_sdk_python-2.13.0}/setup.cfg +0 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dominus-sdk-python
|
|
3
|
+
Version: 2.13.0
|
|
4
|
+
Summary: Python SDK for the Dominus Orchestrator Platform
|
|
5
|
+
Author-email: CareBridge Systems <dev@carebridge.io>
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Project-URL: Homepage, https://github.com/carebridgesystems/dominus-sdk-python
|
|
8
|
+
Project-URL: Repository, https://github.com/carebridgesystems/dominus-sdk-python
|
|
9
|
+
Keywords: dominus,carebridge,sdk,orchestrator,api,async
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: Other/Proprietary License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Framework :: AsyncIO
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: httpx>=0.24.0
|
|
24
|
+
Requires-Dist: bcrypt>=4.0.0
|
|
25
|
+
Requires-Dist: cryptography>=41.0.0
|
|
26
|
+
Provides-Extra: jwt
|
|
27
|
+
Requires-Dist: PyJWT>=2.8.0; extra == "jwt"
|
|
28
|
+
Provides-Extra: oracle
|
|
29
|
+
Requires-Dist: websockets>=12.0; extra == "oracle"
|
|
30
|
+
Requires-Dist: sounddevice>=0.4.6; extra == "oracle"
|
|
31
|
+
Requires-Dist: numpy>=1.24.0; extra == "oracle"
|
|
32
|
+
Requires-Dist: webrtcvad>=2.0.10; extra == "oracle"
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
36
|
+
Provides-Extra: all
|
|
37
|
+
Requires-Dist: PyJWT>=2.8.0; extra == "all"
|
|
38
|
+
Requires-Dist: websockets>=12.0; extra == "all"
|
|
39
|
+
Requires-Dist: sounddevice>=0.4.6; extra == "all"
|
|
40
|
+
Requires-Dist: numpy>=1.24.0; extra == "all"
|
|
41
|
+
Requires-Dist: webrtcvad>=2.0.10; extra == "all"
|
|
42
|
+
|
|
43
|
+
# Dominus SDK for Python
|
|
44
|
+
|
|
45
|
+
Async Python SDK for CareBridge Dominus platform services. Routes calls through the Dominus Gateway with JWT-based authentication, base64 wire encoding, retries, and circuit breaking.
|
|
46
|
+
|
|
47
|
+
## What This Is
|
|
48
|
+
|
|
49
|
+
- Server-side, asyncio-first Python SDK (3.9+)
|
|
50
|
+
- Namespace API with root-level shortcuts for common operations
|
|
51
|
+
- Targets production Cloudflare Workers (gateway, JWT, logs) and Cloud Run (orchestrator)
|
|
52
|
+
- Version: 2.12.0
|
|
53
|
+
|
|
54
|
+
## Quick Start
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
import os
|
|
58
|
+
from dominus import dominus
|
|
59
|
+
|
|
60
|
+
os.environ["DOMINUS_TOKEN"] = "your-psk-token"
|
|
61
|
+
|
|
62
|
+
# Secrets
|
|
63
|
+
value = await dominus.secrets.get("DB_URL")
|
|
64
|
+
await dominus.secrets.upsert("API_KEY", "secret_value")
|
|
65
|
+
|
|
66
|
+
# Database CRUD
|
|
67
|
+
users = await dominus.db.query("users", filters={"status": "active"})
|
|
68
|
+
await dominus.db.insert("users", {"name": "John", "email": "john@example.com"})
|
|
69
|
+
|
|
70
|
+
# Redis caching
|
|
71
|
+
await dominus.redis.set("session:123", {"user": "john"}, ttl=3600)
|
|
72
|
+
value = await dominus.redis.get("session:123")
|
|
73
|
+
|
|
74
|
+
# File storage
|
|
75
|
+
result = await dominus.files.upload(data=buf, filename="report.pdf", category="reports")
|
|
76
|
+
|
|
77
|
+
# AI agent execution
|
|
78
|
+
result = await dominus.ai.run_agent(
|
|
79
|
+
conversation_id="conv-123",
|
|
80
|
+
system_prompt="You are helpful.",
|
|
81
|
+
user_prompt="Hello!"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Streaming AI
|
|
85
|
+
async for chunk in dominus.ai.stream_agent(
|
|
86
|
+
conversation_id="conv-123",
|
|
87
|
+
system_prompt="You are helpful.",
|
|
88
|
+
user_prompt="Tell me a story"
|
|
89
|
+
):
|
|
90
|
+
print(chunk.get("content", ""), end="", flush=True)
|
|
91
|
+
|
|
92
|
+
# Workflow execution
|
|
93
|
+
result = await dominus.workflow.execute(workflow_id, context={"key": "value"})
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Architecture (SDK View)
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
DOMINUS_TOKEN (PSK) --> Gateway /jwt/mint --> JWT cached (14min TTL)
|
|
100
|
+
|
|
|
101
|
+
v
|
|
102
|
+
Gateway /svc/* (AI, workflow, logs)
|
|
103
|
+
or
|
|
104
|
+
Orchestrator /api/* (all other services)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- JSON requests/responses are base64-encoded for auth-required routes
|
|
108
|
+
- GET requests send no body; parameters go in the path or query string
|
|
109
|
+
- Gateway routing (`/api/*` -> `/svc/*`) is used by AI, workflow, and logs namespaces
|
|
110
|
+
- Orchestrator handles secrets, db, auth, ddl, files, redis, portal, courier, open, health, admin
|
|
111
|
+
|
|
112
|
+
## Namespaces
|
|
113
|
+
|
|
114
|
+
| Namespace | Service | Description |
|
|
115
|
+
|-----------|---------|-------------|
|
|
116
|
+
| `secrets` | Warden | Secrets CRUD |
|
|
117
|
+
| `db` | Scribe | Database CRUD with optional secure-table audit |
|
|
118
|
+
| `secure` / `db_secure` | Scribe | Audit-logged data access (requires reason/actor) |
|
|
119
|
+
| `redis` | Whisperer | Cache, locks, counters, hashes |
|
|
120
|
+
| `files` | Archivist | Object storage with compliance mode |
|
|
121
|
+
| `auth` | Guardian | Users, roles, scopes, tenants, clients, pages, nav, subtypes, secure tables (147 methods) |
|
|
122
|
+
| `ddl` | Smith | Schema DDL, migrations, tenant provisioning, schema builder |
|
|
123
|
+
| `logs` | Logs Worker | Structured logging with callsite capture |
|
|
124
|
+
| `portal` | Portal | Login, sessions, profile, preferences, navigation, registration |
|
|
125
|
+
| `courier` | Courier | Postmark email delivery |
|
|
126
|
+
| `open` | Scribe Open | Raw SQL / DSN retrieval |
|
|
127
|
+
| `health` | Orchestrator | Health/ping/warmup |
|
|
128
|
+
| `admin` | Admin | Reseed/reset admin category |
|
|
129
|
+
| `ai` | Agent Runtime | Agent execution, LLM completions, RAG, artifacts, results, orchestration, STT/TTS |
|
|
130
|
+
| `workflow` | Workflow Manager | Workflow CRUD, categories/pipelines, templates, execution |
|
|
131
|
+
| `oracle` / `stt` | Oracle | Real-time streaming STT with VAD (WebSocket, requires `oracle` extras) |
|
|
132
|
+
| `fastapi` | Local | FastAPI route auth decorators (`@jwt`, `@psk`, `@scopes`) |
|
|
133
|
+
|
|
134
|
+
## Configuration
|
|
135
|
+
|
|
136
|
+
**Required:**
|
|
137
|
+
- `DOMINUS_TOKEN` -- PSK token for gateway authentication
|
|
138
|
+
|
|
139
|
+
**Optional:**
|
|
140
|
+
- `DOMINUS_GATEWAY_URL` -- Override gateway URL (default: `https://gateway.getdominus.app`)
|
|
141
|
+
- `DOMINUS_JWT_URL` -- Override JWT worker URL (default: `https://jwt.getdominus.app`)
|
|
142
|
+
- `DOMINUS_LOGS_URL` -- Override logs worker URL (default: `https://logs.getdominus.app`)
|
|
143
|
+
- `DOMINUS_BASE_URL` -- Override orchestrator URL (default: production Cloud Run)
|
|
144
|
+
- `DOMINUS_HTTP_PROXY` / `DOMINUS_HTTPS_PROXY` -- httpx proxy configuration
|
|
145
|
+
- `DOMINUS_CAPTURE_CONSOLE` -- Set to `"true"` to auto-forward `print()` and `logging.*` to Logs Worker
|
|
146
|
+
|
|
147
|
+
## Installation
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pip install dominus-sdk-python
|
|
151
|
+
|
|
152
|
+
# With optional extras
|
|
153
|
+
pip install dominus-sdk-python[jwt] # Local JWT verification
|
|
154
|
+
pip install dominus-sdk-python[oracle] # WebSocket STT (websockets, numpy, sounddevice, webrtcvad)
|
|
155
|
+
pip install dominus-sdk-python[all] # Everything
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Console Capture
|
|
159
|
+
|
|
160
|
+
Forward `print()` and `logging.*` to the Dominus Logs Worker:
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
# Automatic (via env var, before importing SDK):
|
|
164
|
+
os.environ["DOMINUS_CAPTURE_CONSOLE"] = "true"
|
|
165
|
+
|
|
166
|
+
# Manual:
|
|
167
|
+
dominus.capture_console() # start capturing
|
|
168
|
+
dominus.release_console() # stop capturing
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Documentation
|
|
172
|
+
|
|
173
|
+
- [Architecture](docs/architecture.md) -- Request flow, resilience, JWT verification
|
|
174
|
+
- [Services Reference](docs/services.md) -- Complete namespace and method inventory
|
|
175
|
+
- [Development](docs/development.md) -- Setup, testing, adding APIs
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
Proprietary - CareBridge Systems
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Dominus SDK for Python
|
|
2
|
+
|
|
3
|
+
Async Python SDK for CareBridge Dominus platform services. Routes calls through the Dominus Gateway with JWT-based authentication, base64 wire encoding, retries, and circuit breaking.
|
|
4
|
+
|
|
5
|
+
## What This Is
|
|
6
|
+
|
|
7
|
+
- Server-side, asyncio-first Python SDK (3.9+)
|
|
8
|
+
- Namespace API with root-level shortcuts for common operations
|
|
9
|
+
- Targets production Cloudflare Workers (gateway, JWT, logs) and Cloud Run (orchestrator)
|
|
10
|
+
- Version: 2.12.0
|
|
11
|
+
|
|
12
|
+
## Quick Start
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
import os
|
|
16
|
+
from dominus import dominus
|
|
17
|
+
|
|
18
|
+
os.environ["DOMINUS_TOKEN"] = "your-psk-token"
|
|
19
|
+
|
|
20
|
+
# Secrets
|
|
21
|
+
value = await dominus.secrets.get("DB_URL")
|
|
22
|
+
await dominus.secrets.upsert("API_KEY", "secret_value")
|
|
23
|
+
|
|
24
|
+
# Database CRUD
|
|
25
|
+
users = await dominus.db.query("users", filters={"status": "active"})
|
|
26
|
+
await dominus.db.insert("users", {"name": "John", "email": "john@example.com"})
|
|
27
|
+
|
|
28
|
+
# Redis caching
|
|
29
|
+
await dominus.redis.set("session:123", {"user": "john"}, ttl=3600)
|
|
30
|
+
value = await dominus.redis.get("session:123")
|
|
31
|
+
|
|
32
|
+
# File storage
|
|
33
|
+
result = await dominus.files.upload(data=buf, filename="report.pdf", category="reports")
|
|
34
|
+
|
|
35
|
+
# AI agent execution
|
|
36
|
+
result = await dominus.ai.run_agent(
|
|
37
|
+
conversation_id="conv-123",
|
|
38
|
+
system_prompt="You are helpful.",
|
|
39
|
+
user_prompt="Hello!"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Streaming AI
|
|
43
|
+
async for chunk in dominus.ai.stream_agent(
|
|
44
|
+
conversation_id="conv-123",
|
|
45
|
+
system_prompt="You are helpful.",
|
|
46
|
+
user_prompt="Tell me a story"
|
|
47
|
+
):
|
|
48
|
+
print(chunk.get("content", ""), end="", flush=True)
|
|
49
|
+
|
|
50
|
+
# Workflow execution
|
|
51
|
+
result = await dominus.workflow.execute(workflow_id, context={"key": "value"})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Architecture (SDK View)
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
DOMINUS_TOKEN (PSK) --> Gateway /jwt/mint --> JWT cached (14min TTL)
|
|
58
|
+
|
|
|
59
|
+
v
|
|
60
|
+
Gateway /svc/* (AI, workflow, logs)
|
|
61
|
+
or
|
|
62
|
+
Orchestrator /api/* (all other services)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- JSON requests/responses are base64-encoded for auth-required routes
|
|
66
|
+
- GET requests send no body; parameters go in the path or query string
|
|
67
|
+
- Gateway routing (`/api/*` -> `/svc/*`) is used by AI, workflow, and logs namespaces
|
|
68
|
+
- Orchestrator handles secrets, db, auth, ddl, files, redis, portal, courier, open, health, admin
|
|
69
|
+
|
|
70
|
+
## Namespaces
|
|
71
|
+
|
|
72
|
+
| Namespace | Service | Description |
|
|
73
|
+
|-----------|---------|-------------|
|
|
74
|
+
| `secrets` | Warden | Secrets CRUD |
|
|
75
|
+
| `db` | Scribe | Database CRUD with optional secure-table audit |
|
|
76
|
+
| `secure` / `db_secure` | Scribe | Audit-logged data access (requires reason/actor) |
|
|
77
|
+
| `redis` | Whisperer | Cache, locks, counters, hashes |
|
|
78
|
+
| `files` | Archivist | Object storage with compliance mode |
|
|
79
|
+
| `auth` | Guardian | Users, roles, scopes, tenants, clients, pages, nav, subtypes, secure tables (147 methods) |
|
|
80
|
+
| `ddl` | Smith | Schema DDL, migrations, tenant provisioning, schema builder |
|
|
81
|
+
| `logs` | Logs Worker | Structured logging with callsite capture |
|
|
82
|
+
| `portal` | Portal | Login, sessions, profile, preferences, navigation, registration |
|
|
83
|
+
| `courier` | Courier | Postmark email delivery |
|
|
84
|
+
| `open` | Scribe Open | Raw SQL / DSN retrieval |
|
|
85
|
+
| `health` | Orchestrator | Health/ping/warmup |
|
|
86
|
+
| `admin` | Admin | Reseed/reset admin category |
|
|
87
|
+
| `ai` | Agent Runtime | Agent execution, LLM completions, RAG, artifacts, results, orchestration, STT/TTS |
|
|
88
|
+
| `workflow` | Workflow Manager | Workflow CRUD, categories/pipelines, templates, execution |
|
|
89
|
+
| `oracle` / `stt` | Oracle | Real-time streaming STT with VAD (WebSocket, requires `oracle` extras) |
|
|
90
|
+
| `fastapi` | Local | FastAPI route auth decorators (`@jwt`, `@psk`, `@scopes`) |
|
|
91
|
+
|
|
92
|
+
## Configuration
|
|
93
|
+
|
|
94
|
+
**Required:**
|
|
95
|
+
- `DOMINUS_TOKEN` -- PSK token for gateway authentication
|
|
96
|
+
|
|
97
|
+
**Optional:**
|
|
98
|
+
- `DOMINUS_GATEWAY_URL` -- Override gateway URL (default: `https://gateway.getdominus.app`)
|
|
99
|
+
- `DOMINUS_JWT_URL` -- Override JWT worker URL (default: `https://jwt.getdominus.app`)
|
|
100
|
+
- `DOMINUS_LOGS_URL` -- Override logs worker URL (default: `https://logs.getdominus.app`)
|
|
101
|
+
- `DOMINUS_BASE_URL` -- Override orchestrator URL (default: production Cloud Run)
|
|
102
|
+
- `DOMINUS_HTTP_PROXY` / `DOMINUS_HTTPS_PROXY` -- httpx proxy configuration
|
|
103
|
+
- `DOMINUS_CAPTURE_CONSOLE` -- Set to `"true"` to auto-forward `print()` and `logging.*` to Logs Worker
|
|
104
|
+
|
|
105
|
+
## Installation
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
pip install dominus-sdk-python
|
|
109
|
+
|
|
110
|
+
# With optional extras
|
|
111
|
+
pip install dominus-sdk-python[jwt] # Local JWT verification
|
|
112
|
+
pip install dominus-sdk-python[oracle] # WebSocket STT (websockets, numpy, sounddevice, webrtcvad)
|
|
113
|
+
pip install dominus-sdk-python[all] # Everything
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Console Capture
|
|
117
|
+
|
|
118
|
+
Forward `print()` and `logging.*` to the Dominus Logs Worker:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
# Automatic (via env var, before importing SDK):
|
|
122
|
+
os.environ["DOMINUS_CAPTURE_CONSOLE"] = "true"
|
|
123
|
+
|
|
124
|
+
# Manual:
|
|
125
|
+
dominus.capture_console() # start capturing
|
|
126
|
+
dominus.release_console() # stop capturing
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Documentation
|
|
130
|
+
|
|
131
|
+
- [Architecture](docs/architecture.md) -- Request flow, resilience, JWT verification
|
|
132
|
+
- [Services Reference](docs/services.md) -- Complete namespace and method inventory
|
|
133
|
+
- [Development](docs/development.md) -- Setup, testing, adding APIs
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
Proprietary - CareBridge Systems
|
|
@@ -100,6 +100,12 @@ from .namespaces.courier import CourierNamespace
|
|
|
100
100
|
from .namespaces.health import HealthNamespace
|
|
101
101
|
from .namespaces.open import OpenNamespace
|
|
102
102
|
|
|
103
|
+
# Export new namespaces (Node.js SDK parity)
|
|
104
|
+
from .namespaces.artifacts import ArtifactsNamespace
|
|
105
|
+
from .namespaces.jobs import JobsNamespace
|
|
106
|
+
from .namespaces.processor import ProcessorNamespace
|
|
107
|
+
from .namespaces.sync import SyncNamespace
|
|
108
|
+
|
|
103
109
|
# Export Oracle namespace for speech-to-text
|
|
104
110
|
from .namespaces.oracle import (
|
|
105
111
|
OracleNamespace,
|
|
@@ -146,7 +152,7 @@ from .errors import (
|
|
|
146
152
|
TimeoutError as DominusTimeoutError,
|
|
147
153
|
)
|
|
148
154
|
|
|
149
|
-
__version__ = "2.
|
|
155
|
+
__version__ = "2.13.0"
|
|
150
156
|
__all__ = [
|
|
151
157
|
# Main SDK instance
|
|
152
158
|
"dominus",
|
|
@@ -175,6 +181,11 @@ __all__ = [
|
|
|
175
181
|
"CourierNamespace",
|
|
176
182
|
"HealthNamespace",
|
|
177
183
|
"OpenNamespace",
|
|
184
|
+
# New namespaces (Node.js SDK parity)
|
|
185
|
+
"ArtifactsNamespace",
|
|
186
|
+
"JobsNamespace",
|
|
187
|
+
"ProcessorNamespace",
|
|
188
|
+
"SyncNamespace",
|
|
178
189
|
# Oracle namespace for speech-to-text
|
|
179
190
|
"OracleNamespace",
|
|
180
191
|
"OracleSession",
|
|
@@ -611,41 +611,26 @@ def verify_token_format(token: str) -> bool:
|
|
|
611
611
|
|
|
612
612
|
async def health_check_all(base_url: str) -> dict:
|
|
613
613
|
"""
|
|
614
|
-
|
|
614
|
+
Validate SDK readiness.
|
|
615
|
+
|
|
616
|
+
Previously checked orchestrator health via /api/health, but orchestrator
|
|
617
|
+
health is no longer a gate for SDK operations. Services route through
|
|
618
|
+
the gateway, and each service handles its own health independently.
|
|
619
|
+
|
|
620
|
+
Now just validates the base URL is set and returns healthy.
|
|
621
|
+
Orchestrator health checks are only relevant for courier/oracle
|
|
622
|
+
which will be refactored separately.
|
|
615
623
|
|
|
616
624
|
Args:
|
|
617
|
-
base_url:
|
|
625
|
+
base_url: Gateway/orchestrator base URL
|
|
618
626
|
|
|
619
627
|
Returns:
|
|
620
|
-
Health status dict
|
|
628
|
+
Health status dict (always healthy if base_url is set)
|
|
621
629
|
"""
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
results = {}
|
|
626
|
-
|
|
627
|
-
# Check orchestrator via /api/health
|
|
628
|
-
# Timeout: 15s to handle cold starts on Cloud Run
|
|
629
|
-
try:
|
|
630
|
-
start = time.time()
|
|
631
|
-
async with httpx.AsyncClient(base_url=base_url, timeout=15.0, proxies=proxy_config) as client:
|
|
632
|
-
response = await client.get("/api/health")
|
|
633
|
-
response.raise_for_status()
|
|
634
|
-
|
|
635
|
-
# Parse response (may be JSON string or dict)
|
|
636
|
-
health_data = response.json() if response.headers.get("content-type", "").startswith("application/json") else {"status": "ok"}
|
|
637
|
-
|
|
638
|
-
latency = int((time.time() - start) * 1000)
|
|
639
|
-
results["orchestrator"] = {
|
|
640
|
-
"status": health_data.get("status", "healthy"),
|
|
641
|
-
"latency_ms": latency,
|
|
642
|
-
**health_data
|
|
643
|
-
}
|
|
644
|
-
except Exception as e:
|
|
645
|
-
results["orchestrator"] = {"status": "unhealthy", "error": str(e)}
|
|
646
|
-
return {"status": "unhealthy", "services": results, "message": "Orchestrator unhealthy"}
|
|
630
|
+
if not base_url:
|
|
631
|
+
return {"status": "unhealthy", "services": {}, "message": "No base URL configured"}
|
|
647
632
|
|
|
648
|
-
return {"status": "healthy", "services":
|
|
633
|
+
return {"status": "healthy", "services": {}, "message": "SDK ready"}
|
|
649
634
|
|
|
650
635
|
|
|
651
636
|
async def get_service_url(service_name: str, token: str, sovereign_url: str) -> str:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Dominus SDK Namespaces v2.
|
|
1
|
+
"""Dominus SDK Namespaces v2.9"""
|
|
2
2
|
from .secrets import SecretsNamespace
|
|
3
3
|
from .db import DbNamespace
|
|
4
4
|
from .redis import RedisNamespace
|
|
@@ -11,6 +11,10 @@ from .health import HealthNamespace
|
|
|
11
11
|
from .portal import PortalNamespace
|
|
12
12
|
from .courier import CourierNamespace
|
|
13
13
|
from .workflow import WorkflowNamespace
|
|
14
|
+
from .artifacts import ArtifactsNamespace
|
|
15
|
+
from .jobs import JobsNamespace
|
|
16
|
+
from .processor import ProcessorNamespace
|
|
17
|
+
from .sync import SyncNamespace
|
|
14
18
|
from .ai import (
|
|
15
19
|
AiNamespace,
|
|
16
20
|
RagSubNamespace,
|
|
@@ -32,6 +36,10 @@ __all__ = [
|
|
|
32
36
|
"PortalNamespace",
|
|
33
37
|
"CourierNamespace",
|
|
34
38
|
"WorkflowNamespace",
|
|
39
|
+
"ArtifactsNamespace",
|
|
40
|
+
"JobsNamespace",
|
|
41
|
+
"ProcessorNamespace",
|
|
42
|
+
"SyncNamespace",
|
|
35
43
|
"AiNamespace",
|
|
36
44
|
"RagSubNamespace",
|
|
37
45
|
"ArtifactsSubNamespace",
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Artifacts Namespace - Temporary artifact storage.
|
|
3
|
+
|
|
4
|
+
Provides auto-tiered artifact storage (Redis < 1MB, B2 >= 1MB)
|
|
5
|
+
with TTL-based expiration. Routes through gateway to artifact-worker.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
from dominus import dominus
|
|
9
|
+
|
|
10
|
+
# Store
|
|
11
|
+
result = await dominus.artifacts.store(data="base64data...", ttl_seconds=7200)
|
|
12
|
+
|
|
13
|
+
# Retrieve
|
|
14
|
+
artifact = await dominus.artifacts.retrieve(result["key"])
|
|
15
|
+
|
|
16
|
+
# List
|
|
17
|
+
items = await dominus.artifacts.list(category="reports")
|
|
18
|
+
|
|
19
|
+
# Delete
|
|
20
|
+
await dominus.artifacts.delete(result["key"])
|
|
21
|
+
"""
|
|
22
|
+
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from ..start import Dominus
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ArtifactsNamespace:
|
|
29
|
+
"""
|
|
30
|
+
Artifact storage namespace.
|
|
31
|
+
|
|
32
|
+
Auto-tiered: data < 1MB stored in Redis, >= 1MB in Backblaze B2.
|
|
33
|
+
All operations route through gateway to artifact-worker.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(self, client: "Dominus"):
|
|
37
|
+
self._client = client
|
|
38
|
+
|
|
39
|
+
async def _api(
|
|
40
|
+
self,
|
|
41
|
+
endpoint: str,
|
|
42
|
+
method: str = "POST",
|
|
43
|
+
body: Optional[Dict[str, Any]] = None,
|
|
44
|
+
timeout: float = 30.0,
|
|
45
|
+
) -> Dict[str, Any]:
|
|
46
|
+
"""Make gateway-routed request to artifact-worker."""
|
|
47
|
+
return await self._client._request(
|
|
48
|
+
endpoint=endpoint,
|
|
49
|
+
method=method,
|
|
50
|
+
body=body,
|
|
51
|
+
use_gateway=True,
|
|
52
|
+
timeout=timeout,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
async def list(
|
|
56
|
+
self,
|
|
57
|
+
limit: int = 100,
|
|
58
|
+
category: Optional[str] = None,
|
|
59
|
+
) -> Dict[str, Any]:
|
|
60
|
+
"""
|
|
61
|
+
List artifacts for the current project/environment.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
limit: Max items to return (default 100, max 500)
|
|
65
|
+
category: Optional category filter
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
{artifacts: [...], count: int, total_size_bytes: int}
|
|
69
|
+
"""
|
|
70
|
+
body: Dict[str, Any] = {"limit": limit}
|
|
71
|
+
if category:
|
|
72
|
+
body["category"] = category
|
|
73
|
+
return await self._api("/api/artifact/list", body=body)
|
|
74
|
+
|
|
75
|
+
async def get_health(self) -> Dict[str, Any]:
|
|
76
|
+
"""Check artifact worker health."""
|
|
77
|
+
return await self._api("/api/artifact/health", method="GET")
|
|
78
|
+
|
|
79
|
+
async def store(
|
|
80
|
+
self,
|
|
81
|
+
data: str,
|
|
82
|
+
key: Optional[str] = None,
|
|
83
|
+
ttl_seconds: int = 3600,
|
|
84
|
+
category: Optional[str] = None,
|
|
85
|
+
) -> Dict[str, Any]:
|
|
86
|
+
"""
|
|
87
|
+
Store an artifact.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
data: Base64-encoded data
|
|
91
|
+
key: Optional caller-provided key (UUID generated if not provided)
|
|
92
|
+
ttl_seconds: Time-to-live in seconds (default 3600)
|
|
93
|
+
category: Optional category for organization
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
{key, ref, storage_type, size_bytes, expires_at}
|
|
97
|
+
"""
|
|
98
|
+
body: Dict[str, Any] = {
|
|
99
|
+
"data": data,
|
|
100
|
+
"ttl_seconds": ttl_seconds,
|
|
101
|
+
}
|
|
102
|
+
if key:
|
|
103
|
+
body["key"] = key
|
|
104
|
+
if category:
|
|
105
|
+
body["category"] = category
|
|
106
|
+
return await self._api("/api/artifact/store", body=body)
|
|
107
|
+
|
|
108
|
+
async def retrieve(self, key: str) -> Dict[str, Any]:
|
|
109
|
+
"""
|
|
110
|
+
Retrieve an artifact by key.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
key: Artifact key
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
{key, data, storage_type, size_bytes, expires_at}
|
|
117
|
+
"""
|
|
118
|
+
return await self._api("/api/artifact/retrieve", body={"key": key})
|
|
119
|
+
|
|
120
|
+
async def delete(self, key: str) -> Dict[str, Any]:
|
|
121
|
+
"""
|
|
122
|
+
Delete an artifact by key.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
key: Artifact key
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
{deleted: bool, key: str}
|
|
129
|
+
"""
|
|
130
|
+
return await self._api("/api/artifact/delete", body={"key": key})
|
|
131
|
+
|
|
132
|
+
async def cleanup(
|
|
133
|
+
self,
|
|
134
|
+
force: bool = False,
|
|
135
|
+
limit: int = 100,
|
|
136
|
+
) -> Dict[str, Any]:
|
|
137
|
+
"""
|
|
138
|
+
Cleanup expired artifacts (admin only).
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
force: Skip throttle check
|
|
142
|
+
limit: Max items to clean (default 100)
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
{cleaned: int, skipped: bool}
|
|
146
|
+
"""
|
|
147
|
+
body: Dict[str, Any] = {"limit": limit}
|
|
148
|
+
if force:
|
|
149
|
+
body["force"] = True
|
|
150
|
+
return await self._api("/api/artifact/cleanup", body=body)
|
|
@@ -153,6 +153,63 @@ class AuthNamespace:
|
|
|
153
153
|
body={"password": password}
|
|
154
154
|
)
|
|
155
155
|
|
|
156
|
+
# User profiles
|
|
157
|
+
async def get_user_profile(self, user_id: str) -> Optional[Dict[str, Any]]:
|
|
158
|
+
"""Get user profile by user_id. Returns None if no profile exists."""
|
|
159
|
+
result = await self._client._request(
|
|
160
|
+
endpoint=f"/api/guardian/user-profiles?user_id={user_id}&limit=1",
|
|
161
|
+
method="GET"
|
|
162
|
+
)
|
|
163
|
+
items = result if isinstance(result, list) else (result.get("data", []) if isinstance(result, dict) else [])
|
|
164
|
+
return items[0] if items else None
|
|
165
|
+
|
|
166
|
+
async def create_user_profile(
|
|
167
|
+
self,
|
|
168
|
+
user_id: str,
|
|
169
|
+
first_name: Optional[str] = None,
|
|
170
|
+
last_name: Optional[str] = None,
|
|
171
|
+
display_name: Optional[str] = None,
|
|
172
|
+
avatar_url: Optional[str] = None,
|
|
173
|
+
) -> Dict[str, Any]:
|
|
174
|
+
"""Create a user profile."""
|
|
175
|
+
body: Dict[str, Any] = {"user_id": user_id}
|
|
176
|
+
if first_name is not None:
|
|
177
|
+
body["first_name"] = first_name
|
|
178
|
+
if last_name is not None:
|
|
179
|
+
body["last_name"] = last_name
|
|
180
|
+
if display_name is not None:
|
|
181
|
+
body["display_name"] = display_name
|
|
182
|
+
if avatar_url is not None:
|
|
183
|
+
body["avatar_url"] = avatar_url
|
|
184
|
+
return await self._client._request(
|
|
185
|
+
endpoint="/api/guardian/user-profiles",
|
|
186
|
+
body=body
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
async def update_user_profile(
|
|
190
|
+
self,
|
|
191
|
+
profile_id: str,
|
|
192
|
+
first_name: Optional[str] = None,
|
|
193
|
+
last_name: Optional[str] = None,
|
|
194
|
+
display_name: Optional[str] = None,
|
|
195
|
+
avatar_url: Optional[str] = None,
|
|
196
|
+
) -> Dict[str, Any]:
|
|
197
|
+
"""Update a user profile."""
|
|
198
|
+
body: Dict[str, Any] = {}
|
|
199
|
+
if first_name is not None:
|
|
200
|
+
body["first_name"] = first_name
|
|
201
|
+
if last_name is not None:
|
|
202
|
+
body["last_name"] = last_name
|
|
203
|
+
if display_name is not None:
|
|
204
|
+
body["display_name"] = display_name
|
|
205
|
+
if avatar_url is not None:
|
|
206
|
+
body["avatar_url"] = avatar_url
|
|
207
|
+
return await self._client._request(
|
|
208
|
+
endpoint=f"/api/guardian/user-profiles/{profile_id}",
|
|
209
|
+
method="PUT",
|
|
210
|
+
body=body
|
|
211
|
+
)
|
|
212
|
+
|
|
156
213
|
# User junction tables
|
|
157
214
|
async def get_user_roles(self, user_id: str) -> List[Dict[str, Any]]:
|
|
158
215
|
"""Get roles assigned to user."""
|
|
@@ -722,6 +779,7 @@ class AuthNamespace:
|
|
|
722
779
|
self,
|
|
723
780
|
status: Optional[str] = None,
|
|
724
781
|
category_id: Optional[str] = None,
|
|
782
|
+
include_system: bool = False,
|
|
725
783
|
limit: int = 100,
|
|
726
784
|
offset: int = 0
|
|
727
785
|
) -> Dict[str, Any]:
|
|
@@ -731,6 +789,8 @@ class AuthNamespace:
|
|
|
731
789
|
params += f"&status={status}"
|
|
732
790
|
if category_id:
|
|
733
791
|
params += f"&category_id={category_id}"
|
|
792
|
+
if include_system:
|
|
793
|
+
params += "&include_system=true"
|
|
734
794
|
|
|
735
795
|
return await self._client._request(
|
|
736
796
|
endpoint=f"/api/guardian/tenants{params}",
|
|
@@ -796,12 +856,16 @@ class AuthNamespace:
|
|
|
796
856
|
|
|
797
857
|
async def list_tenant_categories(
|
|
798
858
|
self,
|
|
859
|
+
include_system: bool = False,
|
|
799
860
|
limit: int = 100,
|
|
800
861
|
offset: int = 0
|
|
801
862
|
) -> Dict[str, Any]:
|
|
802
863
|
"""List all tenant categories."""
|
|
864
|
+
params = f"?limit={limit}&offset={offset}"
|
|
865
|
+
if include_system:
|
|
866
|
+
params += "&include_system=true"
|
|
803
867
|
return await self._client._request(
|
|
804
|
-
endpoint=f"/api/guardian/tenant-categories
|
|
868
|
+
endpoint=f"/api/guardian/tenant-categories{params}",
|
|
805
869
|
method="GET"
|
|
806
870
|
)
|
|
807
871
|
|