dominus-sdk-python 2.1.7__tar.gz → 2.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-2.1.7 → dominus_sdk_python-2.2.0}/PKG-INFO +215 -28
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/README.md +214 -27
- dominus_sdk_python-2.2.0/dominus/__init__.py +108 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/config/__init__.py +4 -4
- dominus_sdk_python-2.2.0/dominus/namespaces/admin.py +58 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/auth.py +539 -10
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/db.py +26 -1
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/ddl.py +206 -0
- dominus_sdk_python-2.2.0/dominus/namespaces/fastapi.py +252 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/files.py +180 -0
- dominus_sdk_python-2.2.0/dominus/namespaces/secure.py +256 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/start.py +22 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus_sdk_python.egg-info/PKG-INFO +215 -28
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus_sdk_python.egg-info/SOURCES.txt +3 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/pyproject.toml +1 -1
- dominus_sdk_python-2.1.7/dominus/__init__.py +0 -47
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/config/endpoints.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/errors.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/helpers/__init__.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/helpers/auth.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/helpers/cache.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/helpers/core.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/helpers/crypto.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/__init__.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/_deprecated_crossover.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/_deprecated_sql.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/courier.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/health.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/logs.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/open.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/portal.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/redis.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/namespaces/secrets.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/services/__init__.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/services/_deprecated_architect.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus/services/_deprecated_sovereign.py +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus_sdk_python.egg-info/dependency_links.txt +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus_sdk_python.egg-info/requires.txt +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/dominus_sdk_python.egg-info/top_level.txt +0 -0
- {dominus_sdk_python-2.1.7 → dominus_sdk_python-2.2.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dominus-sdk-python
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Python SDK for the Dominus Orchestrator Platform
|
|
5
5
|
Author-email: CareBridge Systems <dev@carebridge.io>
|
|
6
6
|
License: Proprietary
|
|
@@ -29,31 +29,31 @@ Provides-Extra: dev
|
|
|
29
29
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
30
30
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
31
31
|
|
|
32
|
-
# CB Dominus SDK
|
|
32
|
+
# CB Dominus SDK for Python
|
|
33
33
|
|
|
34
|
-
**Python SDK for the Dominus Orchestrator Platform**
|
|
34
|
+
**Async Python SDK for the Dominus Orchestrator Platform**
|
|
35
35
|
|
|
36
36
|
A unified, async-first Python SDK providing seamless access to all Dominus backend services including secrets management, database operations, caching, file storage, authentication, schema management, and structured logging.
|
|
37
37
|
|
|
38
38
|
## Features
|
|
39
39
|
|
|
40
40
|
- **Namespace-based API** - Intuitive access via `dominus.db`, `dominus.redis`, `dominus.files`, etc.
|
|
41
|
-
- **Async/Await** - Built for modern async Python applications
|
|
41
|
+
- **Async/Await** - Built for modern async Python applications (asyncio)
|
|
42
42
|
- **Automatic JWT Management** - Token minting, caching, and refresh handled transparently
|
|
43
43
|
- **Resilience Built-in** - Circuit breaker, exponential backoff, and retry logic
|
|
44
|
-
- **
|
|
44
|
+
- **Cold Start Handling** - Special retry logic for orchestrator cold starts
|
|
45
|
+
- **Typed Errors** - 9 specific error classes for different failure modes
|
|
45
46
|
- **Secure by Default** - Client-side password hashing, encrypted cache, audit trail support
|
|
46
47
|
|
|
47
48
|
## Quick Start
|
|
48
49
|
|
|
49
50
|
```python
|
|
50
51
|
from dominus import dominus
|
|
52
|
+
import os
|
|
51
53
|
|
|
52
54
|
# Set your token (or use DOMINUS_TOKEN environment variable)
|
|
53
|
-
import os
|
|
54
55
|
os.environ["DOMINUS_TOKEN"] = "your-psk-token"
|
|
55
56
|
|
|
56
|
-
# Start using the SDK
|
|
57
57
|
async def main():
|
|
58
58
|
# Secrets
|
|
59
59
|
db_url = await dominus.get("DATABASE_URL")
|
|
@@ -81,18 +81,32 @@ git clone https://github.com/carebridgesystems/cb-dominus-sdk.git
|
|
|
81
81
|
pip install httpx bcrypt cryptography
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
Or install via pip (when published):
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pip install dominus-sdk-python
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Requirements
|
|
91
|
+
|
|
92
|
+
- Python 3.9+
|
|
93
|
+
- `httpx` - Async HTTP client
|
|
94
|
+
- `bcrypt` - Password hashing
|
|
95
|
+
- `cryptography` - Cache encryption
|
|
96
|
+
|
|
84
97
|
## Namespaces
|
|
85
98
|
|
|
86
99
|
| Namespace | Service | Purpose |
|
|
87
100
|
|-----------|---------|---------|
|
|
88
101
|
| `dominus.secrets` | Warden | Secrets management |
|
|
89
102
|
| `dominus.db` | Scribe | Database CRUD operations |
|
|
90
|
-
| `dominus.
|
|
91
|
-
| `dominus.
|
|
92
|
-
| `dominus.
|
|
103
|
+
| `dominus.secure` | Scribe | Secure table access with audit logging |
|
|
104
|
+
| `dominus.redis` | Whisperer | Redis caching & distributed locks |
|
|
105
|
+
| `dominus.files` | Archivist | Object storage (Backblaze B2) |
|
|
106
|
+
| `dominus.auth` | Guardian | Users, roles, scopes, tenants, pages, navigation |
|
|
93
107
|
| `dominus.ddl` | Smith | Schema DDL & migrations |
|
|
94
|
-
| `dominus.logs` | Herald | Structured logging |
|
|
95
|
-
| `dominus.portal` | Portal | User auth
|
|
108
|
+
| `dominus.logs` | Herald | Structured logging (BetterStack) |
|
|
109
|
+
| `dominus.portal` | Portal | User auth, sessions, profiles, navigation |
|
|
96
110
|
| `dominus.courier` | Courier | Email delivery (Postmark) |
|
|
97
111
|
| `dominus.open` | Scribe | Direct database access |
|
|
98
112
|
| `dominus.health` | Health | Service health checks |
|
|
@@ -114,6 +128,10 @@ await dominus.secrets.delete("OLD_KEY")
|
|
|
114
128
|
### Database Operations
|
|
115
129
|
|
|
116
130
|
```python
|
|
131
|
+
# List tables
|
|
132
|
+
tables = await dominus.db.tables()
|
|
133
|
+
tenant_tables = await dominus.db.tables(schema="tenant_acme")
|
|
134
|
+
|
|
117
135
|
# Query with filters and pagination
|
|
118
136
|
users = await dominus.db.query(
|
|
119
137
|
"users",
|
|
@@ -133,6 +151,15 @@ user = await dominus.db.insert("users", {
|
|
|
133
151
|
# Update
|
|
134
152
|
await dominus.db.update("users", {"status": "inactive"}, filters={"id": user_id})
|
|
135
153
|
|
|
154
|
+
# Delete
|
|
155
|
+
await dominus.db.delete("users", filters={"id": user_id})
|
|
156
|
+
|
|
157
|
+
# Bulk insert
|
|
158
|
+
await dominus.db.bulk_insert("events", [
|
|
159
|
+
{"type": "login", "user_id": "123"},
|
|
160
|
+
{"type": "login", "user_id": "456"}
|
|
161
|
+
])
|
|
162
|
+
|
|
136
163
|
# Secure table access (requires audit reason)
|
|
137
164
|
patients = await dominus.db.query(
|
|
138
165
|
"patients",
|
|
@@ -145,9 +172,10 @@ patients = await dominus.db.query(
|
|
|
145
172
|
### Redis Caching
|
|
146
173
|
|
|
147
174
|
```python
|
|
148
|
-
# Key-value operations
|
|
175
|
+
# Key-value operations (TTL: min 60s, max 24h)
|
|
149
176
|
await dominus.redis.set("user:123", {"name": "John"}, ttl=3600)
|
|
150
177
|
value = await dominus.redis.get("user:123")
|
|
178
|
+
await dominus.redis.delete("user:123")
|
|
151
179
|
|
|
152
180
|
# Distributed locks
|
|
153
181
|
if await dominus.redis.setnx("lock:job", "worker-1", ttl=60):
|
|
@@ -162,6 +190,7 @@ await dominus.redis.incr("page:views", delta=1)
|
|
|
162
190
|
|
|
163
191
|
# Hash operations
|
|
164
192
|
await dominus.redis.hset("user:123", "email", "john@example.com", ttl=3600)
|
|
193
|
+
email = await dominus.redis.hget("user:123", "email")
|
|
165
194
|
```
|
|
166
195
|
|
|
167
196
|
### File Storage
|
|
@@ -181,6 +210,9 @@ url = download["download_url"]
|
|
|
181
210
|
|
|
182
211
|
# List files
|
|
183
212
|
files = await dominus.files.list(category="reports", prefix="2025/")
|
|
213
|
+
|
|
214
|
+
# Delete file
|
|
215
|
+
await dominus.files.delete(file_id=result["id"])
|
|
184
216
|
```
|
|
185
217
|
|
|
186
218
|
### Structured Logging
|
|
@@ -190,38 +222,67 @@ files = await dominus.files.list(category="reports", prefix="2025/")
|
|
|
190
222
|
await dominus.logs.info("User logged in", {"user_id": "123"})
|
|
191
223
|
await dominus.logs.error("Payment failed", {"order_id": "456"})
|
|
192
224
|
|
|
225
|
+
# All log levels
|
|
226
|
+
await dominus.logs.debug("Debug message", {"data": "..."})
|
|
227
|
+
await dominus.logs.notice("Important notice", {})
|
|
228
|
+
await dominus.logs.warn("Warning message", {})
|
|
229
|
+
await dominus.logs.critical("Critical error", {})
|
|
230
|
+
|
|
231
|
+
# With category
|
|
232
|
+
await dominus.logs.info("Cache hit", {"key": "user:123"}, category="cache")
|
|
233
|
+
|
|
193
234
|
# With exception context
|
|
194
235
|
try:
|
|
195
236
|
risky_operation()
|
|
196
237
|
except Exception as e:
|
|
197
|
-
await dominus.logs.error("Operation failed", exception=e)
|
|
238
|
+
await dominus.logs.error("Operation failed", {}, exception=e)
|
|
239
|
+
|
|
240
|
+
# Batch logging
|
|
241
|
+
await dominus.logs.batch([
|
|
242
|
+
{"level": "info", "message": "Step 1 complete", "data": {}},
|
|
243
|
+
{"level": "info", "message": "Step 2 complete", "data": {}}
|
|
244
|
+
])
|
|
198
245
|
|
|
199
246
|
# Query logs
|
|
200
247
|
errors = await dominus.logs.query(level="error", limit=100)
|
|
201
248
|
```
|
|
202
249
|
|
|
203
|
-
### Authentication
|
|
250
|
+
### Authentication & Authorization (Guardian)
|
|
204
251
|
|
|
205
252
|
```python
|
|
206
253
|
# User management
|
|
207
|
-
|
|
254
|
+
users = await dominus.auth.list_users()
|
|
255
|
+
user = await dominus.auth.get_user(user_id="uuid")
|
|
256
|
+
|
|
257
|
+
new_user = await dominus.auth.add_user(
|
|
208
258
|
username="john",
|
|
209
259
|
password="secure-password",
|
|
210
260
|
email="john@example.com"
|
|
211
261
|
)
|
|
212
262
|
|
|
263
|
+
await dominus.auth.update_user("uuid", status="active")
|
|
264
|
+
await dominus.auth.delete_user("uuid")
|
|
265
|
+
|
|
213
266
|
# Role management
|
|
267
|
+
roles = await dominus.auth.list_roles()
|
|
214
268
|
role = await dominus.auth.add_role(
|
|
215
269
|
name="Editor",
|
|
216
270
|
scope_slugs=["read", "write", "publish"]
|
|
217
271
|
)
|
|
218
272
|
|
|
273
|
+
# Scope management
|
|
274
|
+
scopes = await dominus.auth.list_scopes()
|
|
275
|
+
|
|
276
|
+
# Tenant management
|
|
277
|
+
tenants = await dominus.auth.list_tenants()
|
|
278
|
+
categories = await dominus.auth.list_tenant_categories()
|
|
279
|
+
|
|
219
280
|
# JWT operations
|
|
220
281
|
jwt = await dominus.auth.mint_jwt(user_id=user["id"], expires_in=900)
|
|
221
282
|
claims = await dominus.auth.validate_jwt(token)
|
|
222
283
|
```
|
|
223
284
|
|
|
224
|
-
### Schema Management
|
|
285
|
+
### Schema Management (DDL)
|
|
225
286
|
|
|
226
287
|
```python
|
|
227
288
|
# Create table
|
|
@@ -232,29 +293,60 @@ await dominus.ddl.add_table("orders", [
|
|
|
232
293
|
{"name": "created_at", "type": "TIMESTAMPTZ", "default": "NOW()"}
|
|
233
294
|
])
|
|
234
295
|
|
|
235
|
-
#
|
|
296
|
+
# Add column
|
|
297
|
+
await dominus.ddl.add_column("orders", "status", "VARCHAR(50)", default="'pending'")
|
|
298
|
+
|
|
299
|
+
# Provision tenant schema from category template
|
|
236
300
|
await dominus.ddl.provision_tenant("customer_acme", category_slug="healthcare")
|
|
237
301
|
```
|
|
238
302
|
|
|
239
303
|
### User Authentication (Portal)
|
|
240
304
|
|
|
241
305
|
```python
|
|
242
|
-
# User login
|
|
306
|
+
# User login (tenant_id is optional)
|
|
243
307
|
session = await dominus.portal.login(
|
|
244
308
|
username="john@example.com",
|
|
245
309
|
password="secret123",
|
|
246
|
-
tenant_id="tenant-uuid"
|
|
310
|
+
tenant_id="tenant-uuid" # optional
|
|
247
311
|
)
|
|
248
312
|
|
|
313
|
+
# Client login with PSK (for service-to-service)
|
|
314
|
+
client_session = await dominus.portal.login_client(psk="psk-token")
|
|
315
|
+
|
|
249
316
|
# Get current user
|
|
250
317
|
me = await dominus.portal.me()
|
|
251
318
|
|
|
252
|
-
# Get navigation (access-filtered)
|
|
319
|
+
# Get navigation (access-filtered for current user)
|
|
253
320
|
nav = await dominus.portal.get_navigation()
|
|
254
321
|
|
|
322
|
+
# Check page access
|
|
323
|
+
has_access = await dominus.portal.check_page_access("/dashboard/admin/users")
|
|
324
|
+
|
|
325
|
+
# Switch tenant
|
|
326
|
+
await dominus.portal.switch_tenant("other-tenant-uuid")
|
|
327
|
+
|
|
255
328
|
# Profile & preferences
|
|
329
|
+
profile = await dominus.portal.get_profile()
|
|
330
|
+
await dominus.portal.update_profile(display_name="John Doe")
|
|
331
|
+
|
|
332
|
+
prefs = await dominus.portal.get_preferences()
|
|
256
333
|
await dominus.portal.update_preferences(theme="dark", timezone="America/New_York")
|
|
257
334
|
|
|
335
|
+
# Password management
|
|
336
|
+
await dominus.portal.change_password("old-password", "new-password")
|
|
337
|
+
await dominus.portal.request_password_reset("john@example.com")
|
|
338
|
+
await dominus.portal.confirm_password_reset("reset-token", "new-password")
|
|
339
|
+
|
|
340
|
+
# Session management
|
|
341
|
+
sessions = await dominus.portal.list_sessions()
|
|
342
|
+
await dominus.portal.revoke_session("session-id")
|
|
343
|
+
await dominus.portal.revoke_all_sessions()
|
|
344
|
+
|
|
345
|
+
# Registration & email verification
|
|
346
|
+
await dominus.portal.register("newuser", "new@example.com", "password", "tenant-id")
|
|
347
|
+
await dominus.portal.verify_email("verification-token")
|
|
348
|
+
await dominus.portal.resend_verification("new@example.com")
|
|
349
|
+
|
|
258
350
|
# Logout
|
|
259
351
|
await dominus.portal.logout()
|
|
260
352
|
```
|
|
@@ -271,6 +363,14 @@ result = await dominus.courier.send(
|
|
|
271
363
|
)
|
|
272
364
|
|
|
273
365
|
# Convenience methods
|
|
366
|
+
await dominus.courier.send_welcome(
|
|
367
|
+
to="user@example.com",
|
|
368
|
+
from_email="noreply@myapp.com",
|
|
369
|
+
name="John",
|
|
370
|
+
action_url="https://myapp.com/start",
|
|
371
|
+
product_name="My App"
|
|
372
|
+
)
|
|
373
|
+
|
|
274
374
|
await dominus.courier.send_password_reset(
|
|
275
375
|
to="user@example.com",
|
|
276
376
|
from_email="noreply@myapp.com",
|
|
@@ -278,6 +378,30 @@ await dominus.courier.send_password_reset(
|
|
|
278
378
|
reset_url="https://myapp.com/reset?token=abc",
|
|
279
379
|
product_name="My App"
|
|
280
380
|
)
|
|
381
|
+
|
|
382
|
+
await dominus.courier.send_email_verification(
|
|
383
|
+
to="user@example.com",
|
|
384
|
+
from_email="noreply@myapp.com",
|
|
385
|
+
name="John",
|
|
386
|
+
verify_url="https://myapp.com/verify?token=xyz",
|
|
387
|
+
product_name="My App"
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
await dominus.courier.send_invitation(
|
|
391
|
+
to="invited@example.com",
|
|
392
|
+
from_email="noreply@myapp.com",
|
|
393
|
+
name="Invited User",
|
|
394
|
+
invite_url="https://myapp.com/invite?token=abc",
|
|
395
|
+
inviter_name="John",
|
|
396
|
+
product_name="My App"
|
|
397
|
+
)
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Health Checks
|
|
401
|
+
|
|
402
|
+
```python
|
|
403
|
+
# Basic health check
|
|
404
|
+
status = await dominus.health.check()
|
|
281
405
|
```
|
|
282
406
|
|
|
283
407
|
## Error Handling
|
|
@@ -290,7 +414,11 @@ from dominus import (
|
|
|
290
414
|
AuthorizationError,
|
|
291
415
|
NotFoundError,
|
|
292
416
|
ValidationError,
|
|
417
|
+
ConflictError,
|
|
418
|
+
ServiceError,
|
|
293
419
|
SecureTableError,
|
|
420
|
+
ConnectionError,
|
|
421
|
+
TimeoutError,
|
|
294
422
|
)
|
|
295
423
|
|
|
296
424
|
try:
|
|
@@ -299,6 +427,14 @@ except NotFoundError as e:
|
|
|
299
427
|
print(f"User not found: {e.message}")
|
|
300
428
|
except SecureTableError as e:
|
|
301
429
|
print("Secure table requires 'reason' and 'actor' parameters")
|
|
430
|
+
except AuthenticationError as e:
|
|
431
|
+
print("Invalid or expired token")
|
|
432
|
+
except AuthorizationError as e:
|
|
433
|
+
print("Insufficient permissions")
|
|
434
|
+
except ValidationError as e:
|
|
435
|
+
print(f"Invalid request: {e.message}")
|
|
436
|
+
except TimeoutError as e:
|
|
437
|
+
print("Request timed out")
|
|
302
438
|
except DominusError as e:
|
|
303
439
|
print(f"Error {e.status_code}: {e.message}")
|
|
304
440
|
if e.details:
|
|
@@ -326,13 +462,17 @@ except DominusError as e:
|
|
|
326
462
|
```bash
|
|
327
463
|
# Required: PSK token for authentication
|
|
328
464
|
export DOMINUS_TOKEN="your-psk-token"
|
|
465
|
+
|
|
466
|
+
# Optional: Project configuration
|
|
467
|
+
export CB_PROJECT_SLUG="my-project"
|
|
468
|
+
export CB_ENVIRONMENT="production"
|
|
329
469
|
```
|
|
330
470
|
|
|
331
471
|
### Token Resolution
|
|
332
472
|
|
|
333
473
|
The SDK resolves the authentication token in this order:
|
|
334
474
|
1. `DOMINUS_TOKEN` environment variable
|
|
335
|
-
2. Hardcoded fallback in `dominus/start.py`
|
|
475
|
+
2. Hardcoded fallback in `dominus/start.py` (development only)
|
|
336
476
|
|
|
337
477
|
## Architecture
|
|
338
478
|
|
|
@@ -356,16 +496,53 @@ The SDK resolves the authentication token in this order:
|
|
|
356
496
|
│ ┌─────────┬─────────┬────────┐ │
|
|
357
497
|
│ │ Warden │Guardian │Archivist│ │
|
|
358
498
|
│ │ Scribe │ Smith │Whisperer│ │
|
|
359
|
-
│ │ Herald │ Portal │ Courier│ │
|
|
499
|
+
│ │ Herald │ Portal │ Courier │ │
|
|
360
500
|
│ └─────────┴─────────┴────────┘ │
|
|
361
501
|
└─────────────────────────────────┘
|
|
362
502
|
```
|
|
363
503
|
|
|
364
|
-
##
|
|
504
|
+
## FastAPI Integration
|
|
365
505
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
506
|
+
```python
|
|
507
|
+
from fastapi import FastAPI, HTTPException
|
|
508
|
+
from dominus import dominus, NotFoundError
|
|
509
|
+
|
|
510
|
+
app = FastAPI()
|
|
511
|
+
|
|
512
|
+
@app.get("/users")
|
|
513
|
+
async def list_users():
|
|
514
|
+
try:
|
|
515
|
+
users = await dominus.db.query("users", filters={"status": "active"}, limit=50)
|
|
516
|
+
return users
|
|
517
|
+
except NotFoundError:
|
|
518
|
+
raise HTTPException(status_code=404, detail="Not found")
|
|
519
|
+
except Exception as e:
|
|
520
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
521
|
+
|
|
522
|
+
@app.get("/users/{user_id}")
|
|
523
|
+
async def get_user(user_id: str):
|
|
524
|
+
try:
|
|
525
|
+
user = await dominus.auth.get_user(user_id)
|
|
526
|
+
return user
|
|
527
|
+
except NotFoundError:
|
|
528
|
+
raise HTTPException(status_code=404, detail="User not found")
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
## Pagination Pattern
|
|
532
|
+
|
|
533
|
+
```python
|
|
534
|
+
async def get_all_users(page_size: int = 100):
|
|
535
|
+
offset = 0
|
|
536
|
+
all_users = []
|
|
537
|
+
while True:
|
|
538
|
+
result = await dominus.db.query("users", limit=page_size, offset=offset)
|
|
539
|
+
rows = result.get("rows", [])
|
|
540
|
+
all_users.extend(rows)
|
|
541
|
+
if len(rows) < page_size:
|
|
542
|
+
break
|
|
543
|
+
offset += page_size
|
|
544
|
+
return all_users
|
|
545
|
+
```
|
|
369
546
|
|
|
370
547
|
## Documentation
|
|
371
548
|
|
|
@@ -374,7 +551,17 @@ The SDK resolves the authentication token in this order:
|
|
|
374
551
|
|
|
375
552
|
## Version
|
|
376
553
|
|
|
377
|
-
**v2.
|
|
554
|
+
**v2.1.6** - Latest release with navigation routes and page scope methods
|
|
555
|
+
|
|
556
|
+
### Changelog
|
|
557
|
+
|
|
558
|
+
- **v2.1.6** - Fix navigation routes and add page scope methods
|
|
559
|
+
- **v2.1.5** - Add PSK-only client login
|
|
560
|
+
- **v2.1.4** - Make `tenant_id` optional in login methods
|
|
561
|
+
- **v2.1.2** - Remove `/verify` endpoint call, keep health warmup
|
|
562
|
+
- **v2.1.1** - Fix hardcoded orchestrator base URL
|
|
563
|
+
- **v2.1.0** - Fix SDK routes and remove hardcoded token support
|
|
564
|
+
- **v2.0.0** - Complete namespace-based API rewrite
|
|
378
565
|
|
|
379
566
|
## License
|
|
380
567
|
|