dominus-sdk-python 2.13.4__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.13.4 → dominus_sdk_python-2.15.0}/PKG-INFO +1 -1
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/__init__.py +1 -1
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/helpers/console_capture.py +5 -6
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/auth.py +126 -0
- dominus_sdk_python-2.15.0/dominus/namespaces/db.py +392 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/start.py +2 -2
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/PKG-INFO +1 -1
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/pyproject.toml +1 -1
- dominus_sdk_python-2.13.4/dominus/namespaces/db.py +0 -292
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/README.md +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/config/__init__.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/config/endpoints.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/errors.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/helpers/__init__.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/helpers/auth.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/helpers/cache.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/helpers/core.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/helpers/crypto.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/helpers/sse.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/__init__.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/admin.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/ai.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/artifacts.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/courier.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/ddl.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/fastapi.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/files.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/health.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/jobs.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/logs.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/open.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/__init__.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/audio_capture.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/oracle_websocket.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/session.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/types.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/vad_gate.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/portal.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/processor.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/redis.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/secrets.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/secure.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/sync.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/workflow.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/services/__init__.py +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/SOURCES.txt +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/dependency_links.txt +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/requires.txt +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/top_level.txt +0 -0
- {dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/setup.cfg +0 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Console Capture - Auto-forwards print() and logging.* to Dominus Logs Worker.
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
Enabled by default. Set DOMINUS_CAPTURE_CONSOLE=false to disable.
|
|
5
5
|
Preserves original output and never throws errors.
|
|
6
6
|
|
|
7
7
|
Usage:
|
|
8
|
-
# Automatic (
|
|
9
|
-
# Set DOMINUS_CAPTURE_CONSOLE=true before importing SDK
|
|
8
|
+
# Automatic (default, disable with DOMINUS_CAPTURE_CONSOLE=false)
|
|
10
9
|
|
|
11
10
|
# Manual:
|
|
12
11
|
from dominus import dominus
|
|
@@ -56,10 +55,10 @@ def _fire_log(level: str, message: str) -> None:
|
|
|
56
55
|
global _sending
|
|
57
56
|
if _sending or not _logs_ref:
|
|
58
57
|
return
|
|
59
|
-
_sending = True
|
|
60
58
|
|
|
61
59
|
async def _send():
|
|
62
60
|
global _sending
|
|
61
|
+
_sending = True
|
|
63
62
|
try:
|
|
64
63
|
if level == "debug":
|
|
65
64
|
await _logs_ref.debug(message, {"source": "console"}, "console")
|
|
@@ -79,8 +78,8 @@ def _fire_log(level: str, message: str) -> None:
|
|
|
79
78
|
loop = asyncio.get_running_loop()
|
|
80
79
|
loop.create_task(_send())
|
|
81
80
|
except RuntimeError:
|
|
82
|
-
# No running event loop - skip
|
|
83
|
-
|
|
81
|
+
# No running event loop - skip silently
|
|
82
|
+
pass
|
|
84
83
|
|
|
85
84
|
|
|
86
85
|
def _patched_print(*args, **kwargs):
|
|
@@ -210,6 +210,132 @@ class AuthNamespace:
|
|
|
210
210
|
body=body
|
|
211
211
|
)
|
|
212
212
|
|
|
213
|
+
async def get_user_attribute(self, attribute_id: str) -> Dict[str, Any]:
|
|
214
|
+
"""Get a user attribute by ID."""
|
|
215
|
+
return await self._client._request(
|
|
216
|
+
endpoint=f"/api/guardian/user-attributes/{attribute_id}",
|
|
217
|
+
method="GET"
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
async def list_user_attributes(
|
|
221
|
+
self,
|
|
222
|
+
user_id: Optional[str] = None,
|
|
223
|
+
attribute_type: Optional[str] = None,
|
|
224
|
+
attribute_key: Optional[str] = None,
|
|
225
|
+
attribute_value: Optional[str] = None,
|
|
226
|
+
active: Optional[bool] = None,
|
|
227
|
+
verified: Optional[bool] = None,
|
|
228
|
+
limit: int = 100,
|
|
229
|
+
offset: int = 0,
|
|
230
|
+
order_by: str = "created_at",
|
|
231
|
+
order_desc: bool = True,
|
|
232
|
+
) -> Dict[str, Any]:
|
|
233
|
+
"""List user attributes with optional filters."""
|
|
234
|
+
params = f"?limit={limit}&offset={offset}&order_by={order_by}&order_desc={str(order_desc).lower()}"
|
|
235
|
+
if user_id:
|
|
236
|
+
params += f"&user_id={user_id}"
|
|
237
|
+
if attribute_type:
|
|
238
|
+
params += f"&attribute_type={attribute_type}"
|
|
239
|
+
if attribute_key:
|
|
240
|
+
params += f"&attribute_key={attribute_key}"
|
|
241
|
+
if attribute_value:
|
|
242
|
+
params += f"&attribute_value={attribute_value}"
|
|
243
|
+
if active is not None:
|
|
244
|
+
params += f"&active={str(active).lower()}"
|
|
245
|
+
if verified is not None:
|
|
246
|
+
params += f"&verified={str(verified).lower()}"
|
|
247
|
+
|
|
248
|
+
return await self._client._request(
|
|
249
|
+
endpoint=f"/api/guardian/user-attributes{params}",
|
|
250
|
+
method="GET"
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
async def create_user_attribute(
|
|
254
|
+
self,
|
|
255
|
+
user_id: str,
|
|
256
|
+
attribute_type: str,
|
|
257
|
+
attribute_key: str,
|
|
258
|
+
attribute_value: str,
|
|
259
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
260
|
+
active: Optional[bool] = None,
|
|
261
|
+
verified: Optional[bool] = None,
|
|
262
|
+
) -> Dict[str, Any]:
|
|
263
|
+
"""Create a user attribute."""
|
|
264
|
+
body: Dict[str, Any] = {
|
|
265
|
+
"user_id": user_id,
|
|
266
|
+
"attribute_type": attribute_type,
|
|
267
|
+
"attribute_key": attribute_key,
|
|
268
|
+
"attribute_value": attribute_value,
|
|
269
|
+
}
|
|
270
|
+
if metadata is not None:
|
|
271
|
+
body["metadata"] = metadata
|
|
272
|
+
if active is not None:
|
|
273
|
+
body["active"] = active
|
|
274
|
+
if verified is not None:
|
|
275
|
+
body["verified"] = verified
|
|
276
|
+
|
|
277
|
+
return await self._client._request(
|
|
278
|
+
endpoint="/api/guardian/user-attributes",
|
|
279
|
+
body=body
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
async def update_user_attribute(
|
|
283
|
+
self,
|
|
284
|
+
attribute_id: str,
|
|
285
|
+
attribute_type: Optional[str] = None,
|
|
286
|
+
attribute_key: Optional[str] = None,
|
|
287
|
+
attribute_value: Optional[str] = None,
|
|
288
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
289
|
+
active: Optional[bool] = None,
|
|
290
|
+
verified: Optional[bool] = None,
|
|
291
|
+
) -> Dict[str, Any]:
|
|
292
|
+
"""Update a user attribute."""
|
|
293
|
+
body: Dict[str, Any] = {}
|
|
294
|
+
if attribute_type is not None:
|
|
295
|
+
body["attribute_type"] = attribute_type
|
|
296
|
+
if attribute_key is not None:
|
|
297
|
+
body["attribute_key"] = attribute_key
|
|
298
|
+
if attribute_value is not None:
|
|
299
|
+
body["attribute_value"] = attribute_value
|
|
300
|
+
if metadata is not None:
|
|
301
|
+
body["metadata"] = metadata
|
|
302
|
+
if active is not None:
|
|
303
|
+
body["active"] = active
|
|
304
|
+
if verified is not None:
|
|
305
|
+
body["verified"] = verified
|
|
306
|
+
|
|
307
|
+
return await self._client._request(
|
|
308
|
+
endpoint=f"/api/guardian/user-attributes/{attribute_id}",
|
|
309
|
+
method="PUT",
|
|
310
|
+
body=body
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
async def delete_user_attribute(self, attribute_id: str) -> Dict[str, Any]:
|
|
314
|
+
"""Delete a user attribute."""
|
|
315
|
+
return await self._client._request(
|
|
316
|
+
endpoint=f"/api/guardian/user-attributes/{attribute_id}",
|
|
317
|
+
method="DELETE"
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
async def find_by_attribute(
|
|
321
|
+
self,
|
|
322
|
+
attribute_type: str,
|
|
323
|
+
attribute_value: str,
|
|
324
|
+
active: Optional[bool] = None,
|
|
325
|
+
verified: Optional[bool] = None,
|
|
326
|
+
limit: int = 100,
|
|
327
|
+
offset: int = 0,
|
|
328
|
+
) -> Dict[str, Any]:
|
|
329
|
+
"""Find user attributes by attribute type and value."""
|
|
330
|
+
return await self.list_user_attributes(
|
|
331
|
+
attribute_type=attribute_type,
|
|
332
|
+
attribute_value=attribute_value,
|
|
333
|
+
active=active,
|
|
334
|
+
verified=verified,
|
|
335
|
+
limit=limit,
|
|
336
|
+
offset=offset,
|
|
337
|
+
)
|
|
338
|
+
|
|
213
339
|
# User junction tables
|
|
214
340
|
async def get_user_roles(self, user_id: str) -> List[Dict[str, Any]]:
|
|
215
341
|
"""Get roles assigned to user."""
|
|
@@ -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
|
+
)
|
|
@@ -378,8 +378,8 @@ class Dominus:
|
|
|
378
378
|
# Cache for JWT public key
|
|
379
379
|
self._public_key_cache = None
|
|
380
380
|
|
|
381
|
-
# Auto-activate console capture
|
|
382
|
-
if os.environ.get("DOMINUS_CAPTURE_CONSOLE")
|
|
381
|
+
# Auto-activate console capture (opt-out with DOMINUS_CAPTURE_CONSOLE=false)
|
|
382
|
+
if os.environ.get("DOMINUS_CAPTURE_CONSOLE", "true").lower() != "false":
|
|
383
383
|
from .helpers.console_capture import install_console_capture
|
|
384
384
|
install_console_capture(self.logs)
|
|
385
385
|
|
|
@@ -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
|
{dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/__init__.py
RENAMED
|
File without changes
|
{dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/audio_capture.py
RENAMED
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus/namespaces/oracle/session.py
RENAMED
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-2.13.4 → 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
|
{dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/requires.txt
RENAMED
|
File without changes
|
{dominus_sdk_python-2.13.4 → dominus_sdk_python-2.15.0}/dominus_sdk_python.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|