dominus-sdk-python 2.14.0__tar.gz → 2.15.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.14.0 → dominus_sdk_python-2.15.0}/PKG-INFO +1 -1
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/__init__.py +1 -1
- dominus_sdk_python-2.15.0/dominus/namespaces/db.py +392 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/PKG-INFO +1 -1
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/pyproject.toml +1 -1
- dominus_sdk_python-2.14.0/dominus/namespaces/db.py +0 -292
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/README.md +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/config/__init__.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/config/endpoints.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/errors.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/helpers/__init__.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/helpers/auth.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/helpers/cache.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/helpers/console_capture.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/helpers/core.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/helpers/crypto.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/helpers/sse.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/__init__.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/admin.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/ai.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/artifacts.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/auth.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/courier.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/ddl.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/fastapi.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/files.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/health.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/jobs.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/logs.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/open.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/__init__.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/audio_capture.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/oracle_websocket.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/session.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/types.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/vad_gate.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/portal.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/processor.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/redis.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/secrets.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/secure.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/sync.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/workflow.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/services/__init__.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/start.py +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/SOURCES.txt +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/dependency_links.txt +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/requires.txt +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/top_level.txt +0 -0
- {dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/setup.cfg +0 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Database Namespace - DB Worker data CRUD operations.
|
|
3
|
+
|
|
4
|
+
Routes all database operations through the DB Worker (Cloudflare Worker)
|
|
5
|
+
via the gateway at /svc/database/*.
|
|
6
|
+
|
|
7
|
+
Parity target: dominus-sdk-nodejs/src/namespaces/db.ts v1.28.0
|
|
8
|
+
"""
|
|
9
|
+
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from ..start import Dominus
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DbNamespace:
|
|
16
|
+
"""
|
|
17
|
+
Database CRUD namespace.
|
|
18
|
+
|
|
19
|
+
All data operations go through /api/database/* endpoints via the gateway.
|
|
20
|
+
The gateway routes these to the dominus-db-worker (Cloudflare Worker).
|
|
21
|
+
|
|
22
|
+
Usage:
|
|
23
|
+
# List schemas
|
|
24
|
+
schemas = await dominus.db.schemas()
|
|
25
|
+
|
|
26
|
+
# Query with filters
|
|
27
|
+
result = await dominus.db.query("users", filters={"status": "active"})
|
|
28
|
+
|
|
29
|
+
# Query shared hub tables
|
|
30
|
+
companies = await dominus.db.query("hub_companies", use_shared=True)
|
|
31
|
+
|
|
32
|
+
# Insert data
|
|
33
|
+
await dominus.db.insert("users", {"name": "John", "email": "john@example.com"})
|
|
34
|
+
|
|
35
|
+
# Raw SQL
|
|
36
|
+
result = await dominus.db.raw("SELECT * FROM auth.users WHERE id = $1", [user_id])
|
|
37
|
+
|
|
38
|
+
# Transaction
|
|
39
|
+
result = await dominus.db.transaction([
|
|
40
|
+
{"sql": "UPDATE accounts SET balance = balance - $1 WHERE id = $2", "params": [100, from_id]},
|
|
41
|
+
{"sql": "UPDATE accounts SET balance = balance + $1 WHERE id = $2", "params": [100, to_id]},
|
|
42
|
+
])
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(self, client: "Dominus"):
|
|
46
|
+
self._client = client
|
|
47
|
+
|
|
48
|
+
async def schemas(self, use_shared: bool = False, open: bool = False) -> List[str]:
|
|
49
|
+
"""
|
|
50
|
+
List accessible schemas.
|
|
51
|
+
|
|
52
|
+
Returns schemas that the current user can access (public, tenant_*, etc.)
|
|
53
|
+
Excludes system schemas (pg_catalog, information_schema, etc.)
|
|
54
|
+
"""
|
|
55
|
+
body: Dict[str, Any] = {}
|
|
56
|
+
if use_shared:
|
|
57
|
+
body["use_shared"] = True
|
|
58
|
+
if open:
|
|
59
|
+
body["open"] = True
|
|
60
|
+
|
|
61
|
+
result = await self._client._request(
|
|
62
|
+
endpoint="/api/database/schemas",
|
|
63
|
+
body=body,
|
|
64
|
+
use_gateway=True
|
|
65
|
+
)
|
|
66
|
+
if isinstance(result, dict):
|
|
67
|
+
return result.get("schemas", [])
|
|
68
|
+
return result if isinstance(result, list) else []
|
|
69
|
+
|
|
70
|
+
async def tables(self, schema: str = "public", use_shared: bool = False, open: bool = False) -> List[Dict[str, Any]]:
|
|
71
|
+
"""
|
|
72
|
+
List tables in a schema.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
schema: Schema name (default: "public")
|
|
76
|
+
use_shared: If True, query the shared project database
|
|
77
|
+
open: If True, use the open (user-facing) database role
|
|
78
|
+
"""
|
|
79
|
+
body: Dict[str, Any] = {"schema": schema}
|
|
80
|
+
if use_shared:
|
|
81
|
+
body["use_shared"] = True
|
|
82
|
+
if open:
|
|
83
|
+
body["open"] = True
|
|
84
|
+
|
|
85
|
+
result = await self._client._request(
|
|
86
|
+
endpoint="/api/database/tables",
|
|
87
|
+
body=body,
|
|
88
|
+
use_gateway=True
|
|
89
|
+
)
|
|
90
|
+
if isinstance(result, dict):
|
|
91
|
+
return result.get("tables", [])
|
|
92
|
+
return result if isinstance(result, list) else []
|
|
93
|
+
|
|
94
|
+
async def columns(self, table: str, schema: str = "public", use_shared: bool = False, open: bool = False) -> List[Dict[str, Any]]:
|
|
95
|
+
"""
|
|
96
|
+
List columns in a table.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
table: Table name
|
|
100
|
+
schema: Schema name (default: "public")
|
|
101
|
+
use_shared: If True, query the shared project database
|
|
102
|
+
open: If True, use the open (user-facing) database role
|
|
103
|
+
"""
|
|
104
|
+
body: Dict[str, Any] = {"table": table, "schema": schema}
|
|
105
|
+
if use_shared:
|
|
106
|
+
body["use_shared"] = True
|
|
107
|
+
if open:
|
|
108
|
+
body["open"] = True
|
|
109
|
+
|
|
110
|
+
result = await self._client._request(
|
|
111
|
+
endpoint="/api/database/columns",
|
|
112
|
+
body=body,
|
|
113
|
+
use_gateway=True
|
|
114
|
+
)
|
|
115
|
+
if isinstance(result, dict):
|
|
116
|
+
return result.get("columns", [])
|
|
117
|
+
return result if isinstance(result, list) else []
|
|
118
|
+
|
|
119
|
+
async def query(
|
|
120
|
+
self,
|
|
121
|
+
table: str,
|
|
122
|
+
schema: str = "public",
|
|
123
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
124
|
+
sort_by: Optional[str] = None,
|
|
125
|
+
sort_order: str = "ASC",
|
|
126
|
+
limit: int = 100,
|
|
127
|
+
offset: int = 0,
|
|
128
|
+
use_shared: bool = False,
|
|
129
|
+
) -> Dict[str, Any]:
|
|
130
|
+
"""
|
|
131
|
+
Query table data with filtering, sorting, and pagination.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
table: Table name
|
|
135
|
+
schema: Schema name (default: "public")
|
|
136
|
+
filters: Column:value filter dictionary (sent as 'where' to DB Worker)
|
|
137
|
+
sort_by: Column to sort by
|
|
138
|
+
sort_order: "ASC" or "DESC"
|
|
139
|
+
limit: Maximum rows to return (default: 100)
|
|
140
|
+
offset: Rows to skip (default: 0)
|
|
141
|
+
use_shared: If True, query the shared project database
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
Dict with "rows" and "total" keys
|
|
145
|
+
"""
|
|
146
|
+
order_by = [{"column": sort_by, "direction": sort_order}] if sort_by else None
|
|
147
|
+
|
|
148
|
+
body: Dict[str, Any] = {
|
|
149
|
+
"table": table,
|
|
150
|
+
"schema": schema,
|
|
151
|
+
"where": filters,
|
|
152
|
+
"order_by": order_by,
|
|
153
|
+
"limit": limit,
|
|
154
|
+
"offset": offset,
|
|
155
|
+
}
|
|
156
|
+
if use_shared:
|
|
157
|
+
body["use_shared"] = True
|
|
158
|
+
|
|
159
|
+
result = await self._client._request(
|
|
160
|
+
endpoint="/api/database/select",
|
|
161
|
+
body=body,
|
|
162
|
+
use_gateway=True
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
"rows": result.get("rows", []) if isinstance(result, dict) else [],
|
|
167
|
+
"total": result.get("row_count", 0) if isinstance(result, dict) else 0,
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async def insert(
|
|
171
|
+
self,
|
|
172
|
+
table: str,
|
|
173
|
+
data: Dict[str, Any],
|
|
174
|
+
schema: str = "public",
|
|
175
|
+
use_shared: bool = False,
|
|
176
|
+
) -> Dict[str, Any]:
|
|
177
|
+
"""
|
|
178
|
+
Insert a row into a table.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
table: Table name
|
|
182
|
+
data: Column:value dictionary
|
|
183
|
+
schema: Schema name (default: "public")
|
|
184
|
+
use_shared: If True, write to the shared project database
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
Inserted row data
|
|
188
|
+
"""
|
|
189
|
+
body: Dict[str, Any] = {
|
|
190
|
+
"table": table,
|
|
191
|
+
"schema": schema,
|
|
192
|
+
"data": data,
|
|
193
|
+
"returning": ["*"],
|
|
194
|
+
}
|
|
195
|
+
if use_shared:
|
|
196
|
+
body["use_shared"] = True
|
|
197
|
+
|
|
198
|
+
result = await self._client._request(
|
|
199
|
+
endpoint="/api/database/insert",
|
|
200
|
+
body=body,
|
|
201
|
+
use_gateway=True
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
if isinstance(result, dict) and "rows" in result:
|
|
205
|
+
return result["rows"][0] if result["rows"] else result
|
|
206
|
+
return result
|
|
207
|
+
|
|
208
|
+
async def update(
|
|
209
|
+
self,
|
|
210
|
+
table: str,
|
|
211
|
+
data: Dict[str, Any],
|
|
212
|
+
filters: Dict[str, Any],
|
|
213
|
+
schema: str = "public",
|
|
214
|
+
use_shared: bool = False,
|
|
215
|
+
) -> Dict[str, Any]:
|
|
216
|
+
"""
|
|
217
|
+
Update rows matching filters.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
table: Table name
|
|
221
|
+
data: Column:value dictionary of updates
|
|
222
|
+
filters: Column:value dictionary for WHERE clause (sent as 'where' to DB Worker)
|
|
223
|
+
schema: Schema name (default: "public")
|
|
224
|
+
use_shared: If True, write to the shared project database
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
Dict with "affected_rows" count
|
|
228
|
+
"""
|
|
229
|
+
body: Dict[str, Any] = {
|
|
230
|
+
"table": table,
|
|
231
|
+
"schema": schema,
|
|
232
|
+
"data": data,
|
|
233
|
+
"where": filters,
|
|
234
|
+
"returning": ["*"],
|
|
235
|
+
}
|
|
236
|
+
if use_shared:
|
|
237
|
+
body["use_shared"] = True
|
|
238
|
+
|
|
239
|
+
result = await self._client._request(
|
|
240
|
+
endpoint="/api/database/update",
|
|
241
|
+
body=body,
|
|
242
|
+
use_gateway=True
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
return {"affected_rows": result.get("row_count", 0) if isinstance(result, dict) else 0}
|
|
246
|
+
|
|
247
|
+
async def delete(
|
|
248
|
+
self,
|
|
249
|
+
table: str,
|
|
250
|
+
filters: Dict[str, Any],
|
|
251
|
+
schema: str = "public",
|
|
252
|
+
use_shared: bool = False,
|
|
253
|
+
) -> Dict[str, Any]:
|
|
254
|
+
"""
|
|
255
|
+
Delete rows matching filters.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
table: Table name
|
|
259
|
+
filters: Column:value dictionary for WHERE clause (sent as 'where' to DB Worker)
|
|
260
|
+
schema: Schema name (default: "public")
|
|
261
|
+
use_shared: If True, delete from the shared project database
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
Dict with "affected_rows" count
|
|
265
|
+
"""
|
|
266
|
+
body: Dict[str, Any] = {
|
|
267
|
+
"table": table,
|
|
268
|
+
"schema": schema,
|
|
269
|
+
"where": filters,
|
|
270
|
+
"returning": ["*"],
|
|
271
|
+
}
|
|
272
|
+
if use_shared:
|
|
273
|
+
body["use_shared"] = True
|
|
274
|
+
|
|
275
|
+
result = await self._client._request(
|
|
276
|
+
endpoint="/api/database/delete",
|
|
277
|
+
body=body,
|
|
278
|
+
use_gateway=True
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
return {"affected_rows": result.get("row_count", 0) if isinstance(result, dict) else 0}
|
|
282
|
+
|
|
283
|
+
async def raw(
|
|
284
|
+
self,
|
|
285
|
+
sql: str,
|
|
286
|
+
params: Optional[List[Any]] = None,
|
|
287
|
+
schema: str = "public",
|
|
288
|
+
use_shared: bool = False,
|
|
289
|
+
) -> Dict[str, Any]:
|
|
290
|
+
"""
|
|
291
|
+
Execute raw SQL queries.
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
sql: SQL query with $1, $2 style placeholders
|
|
295
|
+
params: Parameter values for placeholders
|
|
296
|
+
schema: Schema name (default: "public")
|
|
297
|
+
use_shared: If True, query the shared project database
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
Dict with "rows" and "total" keys
|
|
301
|
+
"""
|
|
302
|
+
body: Dict[str, Any] = {
|
|
303
|
+
"sql": sql,
|
|
304
|
+
"params": params or [],
|
|
305
|
+
"schema": schema,
|
|
306
|
+
}
|
|
307
|
+
if use_shared:
|
|
308
|
+
body["use_shared"] = True
|
|
309
|
+
|
|
310
|
+
result = await self._client._request(
|
|
311
|
+
endpoint="/api/database/raw",
|
|
312
|
+
body=body,
|
|
313
|
+
use_gateway=True
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
return {
|
|
317
|
+
"rows": result.get("rows", []) if isinstance(result, dict) else [],
|
|
318
|
+
"total": result.get("row_count", 0) if isinstance(result, dict) else 0,
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async def bulk_insert(
|
|
322
|
+
self,
|
|
323
|
+
table: str,
|
|
324
|
+
rows: List[Dict[str, Any]],
|
|
325
|
+
schema: str = "public",
|
|
326
|
+
use_shared: bool = False,
|
|
327
|
+
) -> Dict[str, Any]:
|
|
328
|
+
"""
|
|
329
|
+
Insert multiple rows at once using a raw SQL transaction.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
table: Table name
|
|
333
|
+
rows: List of column:value dictionaries
|
|
334
|
+
schema: Schema name (default: "public")
|
|
335
|
+
use_shared: If True, write to the shared project database
|
|
336
|
+
|
|
337
|
+
Returns:
|
|
338
|
+
Dict with "inserted_count" and optionally "rows"
|
|
339
|
+
"""
|
|
340
|
+
if not rows:
|
|
341
|
+
return {"inserted_count": 0, "rows": []}
|
|
342
|
+
|
|
343
|
+
columns = list(rows[0].keys())
|
|
344
|
+
quoted_cols = ", ".join(f'"{c}"' for c in columns)
|
|
345
|
+
params: List[Any] = []
|
|
346
|
+
value_clauses: List[str] = []
|
|
347
|
+
|
|
348
|
+
for row in rows:
|
|
349
|
+
placeholders = []
|
|
350
|
+
for col in columns:
|
|
351
|
+
params.append(row.get(col))
|
|
352
|
+
placeholders.append(f"${len(params)}")
|
|
353
|
+
value_clauses.append(f"({', '.join(placeholders)})")
|
|
354
|
+
|
|
355
|
+
sql = f'INSERT INTO "{table}" ({quoted_cols}) VALUES {", ".join(value_clauses)} RETURNING *'
|
|
356
|
+
|
|
357
|
+
result = await self.raw(sql, params, schema=schema, use_shared=use_shared)
|
|
358
|
+
|
|
359
|
+
return {
|
|
360
|
+
"inserted_count": result.get("total", 0),
|
|
361
|
+
"rows": result.get("rows", []),
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async def transaction(
|
|
365
|
+
self,
|
|
366
|
+
statements: List[Dict[str, Any]],
|
|
367
|
+
schema: str = "public",
|
|
368
|
+
use_shared: bool = False,
|
|
369
|
+
) -> Dict[str, Any]:
|
|
370
|
+
"""
|
|
371
|
+
Execute multiple SQL statements in a single atomic transaction.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
statements: List of dicts with 'sql' and optional 'params' keys
|
|
375
|
+
schema: Schema name (default: "public")
|
|
376
|
+
use_shared: If True, execute against the shared project database
|
|
377
|
+
|
|
378
|
+
Returns:
|
|
379
|
+
Dict with "results" array containing rows and row_count per statement
|
|
380
|
+
"""
|
|
381
|
+
body: Dict[str, Any] = {
|
|
382
|
+
"statements": statements,
|
|
383
|
+
"schema": schema,
|
|
384
|
+
}
|
|
385
|
+
if use_shared:
|
|
386
|
+
body["use_shared"] = True
|
|
387
|
+
|
|
388
|
+
return await self._client._request(
|
|
389
|
+
endpoint="/api/database/transaction",
|
|
390
|
+
body=body,
|
|
391
|
+
use_gateway=True
|
|
392
|
+
)
|
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Database Namespace - Scribe data CRUD operations.
|
|
3
|
-
|
|
4
|
-
Provides data operations for all schemas with support for secure table access.
|
|
5
|
-
"""
|
|
6
|
-
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
|
7
|
-
|
|
8
|
-
if TYPE_CHECKING:
|
|
9
|
-
from ..start import Dominus
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class DbNamespace:
|
|
13
|
-
"""
|
|
14
|
-
Database CRUD namespace.
|
|
15
|
-
|
|
16
|
-
All data operations go through /api/scribe/data/* endpoints.
|
|
17
|
-
Secure tables (registered in auth.secure_tables) require a `reason` parameter.
|
|
18
|
-
|
|
19
|
-
Usage:
|
|
20
|
-
# List tables
|
|
21
|
-
tables = await dominus.db.tables()
|
|
22
|
-
tables = await dominus.db.tables(schema="tenant_acme")
|
|
23
|
-
|
|
24
|
-
# Query with filters
|
|
25
|
-
users = await dominus.db.query("users", filters={"status": "active"})
|
|
26
|
-
|
|
27
|
-
# Query secure table (requires reason)
|
|
28
|
-
patients = await dominus.db.query(
|
|
29
|
-
"patients",
|
|
30
|
-
schema="tenant_acme",
|
|
31
|
-
reason="Reviewing chart for appointment #123",
|
|
32
|
-
actor=current_user_id
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
# Insert data
|
|
36
|
-
await dominus.db.insert("users", {"name": "John", "email": "john@example.com"})
|
|
37
|
-
|
|
38
|
-
# Update rows
|
|
39
|
-
await dominus.db.update("users", {"status": "inactive"}, filters={"id": user_id})
|
|
40
|
-
|
|
41
|
-
# Delete rows
|
|
42
|
-
await dominus.db.delete("users", filters={"id": user_id})
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
def __init__(self, client: "Dominus"):
|
|
46
|
-
self._client = client
|
|
47
|
-
|
|
48
|
-
async def schemas(self) -> List[str]:
|
|
49
|
-
"""
|
|
50
|
-
List accessible schemas.
|
|
51
|
-
|
|
52
|
-
Returns schemas that the current user can access (public, tenant_*, etc.)
|
|
53
|
-
Excludes system schemas (auth, logs, meta, object, etc.)
|
|
54
|
-
|
|
55
|
-
Returns:
|
|
56
|
-
List of schema names
|
|
57
|
-
"""
|
|
58
|
-
result = await self._client._request(
|
|
59
|
-
endpoint="/api/scribe/schema/list",
|
|
60
|
-
method="GET"
|
|
61
|
-
)
|
|
62
|
-
if isinstance(result, list):
|
|
63
|
-
return result
|
|
64
|
-
return result.get("schemas", [])
|
|
65
|
-
|
|
66
|
-
async def tables(self, schema: str = "public") -> List[Dict[str, Any]]:
|
|
67
|
-
"""
|
|
68
|
-
List tables in a schema.
|
|
69
|
-
|
|
70
|
-
Args:
|
|
71
|
-
schema: Schema name (default: "public")
|
|
72
|
-
|
|
73
|
-
Returns:
|
|
74
|
-
List of table metadata
|
|
75
|
-
"""
|
|
76
|
-
result = await self._client._request(
|
|
77
|
-
endpoint=f"/api/scribe/data/{schema}/tables",
|
|
78
|
-
method="GET"
|
|
79
|
-
)
|
|
80
|
-
return result.get("tables", result) if isinstance(result, dict) else result
|
|
81
|
-
|
|
82
|
-
async def columns(self, table: str, schema: str = "public") -> List[Dict[str, Any]]:
|
|
83
|
-
"""
|
|
84
|
-
List columns in a table.
|
|
85
|
-
|
|
86
|
-
Args:
|
|
87
|
-
table: Table name
|
|
88
|
-
schema: Schema name (default: "public")
|
|
89
|
-
|
|
90
|
-
Returns:
|
|
91
|
-
List of column metadata
|
|
92
|
-
"""
|
|
93
|
-
result = await self._client._request(
|
|
94
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/columns",
|
|
95
|
-
method="GET"
|
|
96
|
-
)
|
|
97
|
-
return result.get("columns", result) if isinstance(result, dict) else result
|
|
98
|
-
|
|
99
|
-
async def query(
|
|
100
|
-
self,
|
|
101
|
-
table: str,
|
|
102
|
-
schema: str = "public",
|
|
103
|
-
filters: Optional[Dict[str, Any]] = None,
|
|
104
|
-
sort_by: Optional[str] = None,
|
|
105
|
-
sort_order: str = "ASC",
|
|
106
|
-
limit: int = 100,
|
|
107
|
-
offset: int = 0,
|
|
108
|
-
reason: Optional[str] = None,
|
|
109
|
-
actor: Optional[str] = None
|
|
110
|
-
) -> Dict[str, Any]:
|
|
111
|
-
"""
|
|
112
|
-
Query table data with filtering, sorting, and pagination.
|
|
113
|
-
|
|
114
|
-
Args:
|
|
115
|
-
table: Table name
|
|
116
|
-
schema: Schema name (default: "public")
|
|
117
|
-
filters: Column:value filter dictionary
|
|
118
|
-
sort_by: Column to sort by
|
|
119
|
-
sort_order: "ASC" or "DESC"
|
|
120
|
-
limit: Maximum rows to return (default: 100)
|
|
121
|
-
offset: Rows to skip (default: 0)
|
|
122
|
-
reason: Access justification (required for secure tables)
|
|
123
|
-
actor: User ID or "machine" for audit trail
|
|
124
|
-
|
|
125
|
-
Returns:
|
|
126
|
-
Dict with "rows" and "total" keys
|
|
127
|
-
|
|
128
|
-
Raises:
|
|
129
|
-
SecureTableError: If accessing secure table without reason
|
|
130
|
-
"""
|
|
131
|
-
body = {
|
|
132
|
-
"filters": filters,
|
|
133
|
-
"sort_by": sort_by,
|
|
134
|
-
"sort_order": sort_order,
|
|
135
|
-
"limit": limit,
|
|
136
|
-
"offset": offset
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if reason:
|
|
140
|
-
body["reason"] = reason
|
|
141
|
-
if actor:
|
|
142
|
-
body["actor"] = actor
|
|
143
|
-
|
|
144
|
-
# Backend returns {items, total, limit, offset} but we normalize to {rows, total}
|
|
145
|
-
result = await self._client._request(
|
|
146
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/query",
|
|
147
|
-
body=body
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
# Normalize response - map 'items' to 'rows' for consistent interface
|
|
151
|
-
return {
|
|
152
|
-
"rows": result.get("items", result.get("rows", [])),
|
|
153
|
-
"total": result.get("total", 0)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async def insert(
|
|
157
|
-
self,
|
|
158
|
-
table: str,
|
|
159
|
-
data: Dict[str, Any],
|
|
160
|
-
schema: str = "public",
|
|
161
|
-
reason: Optional[str] = None,
|
|
162
|
-
actor: Optional[str] = None
|
|
163
|
-
) -> Dict[str, Any]:
|
|
164
|
-
"""
|
|
165
|
-
Insert a row into a table.
|
|
166
|
-
|
|
167
|
-
Args:
|
|
168
|
-
table: Table name
|
|
169
|
-
data: Column:value dictionary
|
|
170
|
-
schema: Schema name (default: "public")
|
|
171
|
-
reason: Access justification (required for secure tables)
|
|
172
|
-
actor: User ID or "machine" for audit trail
|
|
173
|
-
|
|
174
|
-
Returns:
|
|
175
|
-
Inserted row data
|
|
176
|
-
"""
|
|
177
|
-
body = {"data": data}
|
|
178
|
-
|
|
179
|
-
if reason:
|
|
180
|
-
body["reason"] = reason
|
|
181
|
-
if actor:
|
|
182
|
-
body["actor"] = actor
|
|
183
|
-
|
|
184
|
-
return await self._client._request(
|
|
185
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/insert",
|
|
186
|
-
body=body
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
async def update(
|
|
190
|
-
self,
|
|
191
|
-
table: str,
|
|
192
|
-
data: Dict[str, Any],
|
|
193
|
-
filters: Dict[str, Any],
|
|
194
|
-
schema: str = "public",
|
|
195
|
-
reason: Optional[str] = None,
|
|
196
|
-
actor: Optional[str] = None
|
|
197
|
-
) -> Dict[str, Any]:
|
|
198
|
-
"""
|
|
199
|
-
Update rows matching filters.
|
|
200
|
-
|
|
201
|
-
Args:
|
|
202
|
-
table: Table name
|
|
203
|
-
data: Column:value dictionary of updates
|
|
204
|
-
filters: Column:value dictionary for WHERE clause
|
|
205
|
-
schema: Schema name (default: "public")
|
|
206
|
-
reason: Access justification (required for secure tables)
|
|
207
|
-
actor: User ID or "machine" for audit trail
|
|
208
|
-
|
|
209
|
-
Returns:
|
|
210
|
-
Dict with "affected_rows" count
|
|
211
|
-
"""
|
|
212
|
-
body = {
|
|
213
|
-
"data": data,
|
|
214
|
-
"filters": filters
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
if reason:
|
|
218
|
-
body["reason"] = reason
|
|
219
|
-
if actor:
|
|
220
|
-
body["actor"] = actor
|
|
221
|
-
|
|
222
|
-
return await self._client._request(
|
|
223
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/update",
|
|
224
|
-
body=body
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
async def delete(
|
|
228
|
-
self,
|
|
229
|
-
table: str,
|
|
230
|
-
filters: Dict[str, Any],
|
|
231
|
-
schema: str = "public",
|
|
232
|
-
reason: Optional[str] = None,
|
|
233
|
-
actor: Optional[str] = None
|
|
234
|
-
) -> Dict[str, Any]:
|
|
235
|
-
"""
|
|
236
|
-
Delete rows matching filters.
|
|
237
|
-
|
|
238
|
-
Args:
|
|
239
|
-
table: Table name
|
|
240
|
-
filters: Column:value dictionary for WHERE clause
|
|
241
|
-
schema: Schema name (default: "public")
|
|
242
|
-
reason: Access justification (required for secure tables)
|
|
243
|
-
actor: User ID or "machine" for audit trail
|
|
244
|
-
|
|
245
|
-
Returns:
|
|
246
|
-
Dict with "affected_rows" count
|
|
247
|
-
"""
|
|
248
|
-
body = {"filters": filters}
|
|
249
|
-
|
|
250
|
-
if reason:
|
|
251
|
-
body["reason"] = reason
|
|
252
|
-
if actor:
|
|
253
|
-
body["actor"] = actor
|
|
254
|
-
|
|
255
|
-
return await self._client._request(
|
|
256
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/delete",
|
|
257
|
-
body=body
|
|
258
|
-
)
|
|
259
|
-
|
|
260
|
-
async def bulk_insert(
|
|
261
|
-
self,
|
|
262
|
-
table: str,
|
|
263
|
-
rows: List[Dict[str, Any]],
|
|
264
|
-
schema: str = "public",
|
|
265
|
-
reason: Optional[str] = None,
|
|
266
|
-
actor: Optional[str] = None
|
|
267
|
-
) -> Dict[str, Any]:
|
|
268
|
-
"""
|
|
269
|
-
Insert multiple rows at once.
|
|
270
|
-
|
|
271
|
-
Args:
|
|
272
|
-
table: Table name
|
|
273
|
-
rows: List of column:value dictionaries
|
|
274
|
-
schema: Schema name (default: "public")
|
|
275
|
-
reason: Access justification (required for secure tables)
|
|
276
|
-
actor: User ID or "machine" for audit trail
|
|
277
|
-
|
|
278
|
-
Returns:
|
|
279
|
-
Dict with "inserted_count" and optionally "rows"
|
|
280
|
-
"""
|
|
281
|
-
body = {"rows": rows}
|
|
282
|
-
|
|
283
|
-
if reason:
|
|
284
|
-
body["reason"] = reason
|
|
285
|
-
if actor:
|
|
286
|
-
body["actor"] = actor
|
|
287
|
-
|
|
288
|
-
return await self._client._request(
|
|
289
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/bulk-insert",
|
|
290
|
-
body=body
|
|
291
|
-
)
|
|
292
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/__init__.py
RENAMED
|
File without changes
|
{dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/audio_capture.py
RENAMED
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/session.py
RENAMED
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/vad_gate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/requires.txt
RENAMED
|
File without changes
|
{dominus_sdk_python-2.14.0 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|