dominus-sdk-python-dev 2.1.6__py3-none-any.whl → 2.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dominus/__init__.py +47 -47
- dominus/config/__init__.py +24 -24
- dominus/config/endpoints.py +39 -39
- dominus/errors.py +201 -201
- dominus/helpers/__init__.py +2 -2
- dominus/helpers/auth.py +23 -23
- dominus/helpers/cache.py +192 -192
- dominus/helpers/core.py +657 -657
- dominus/helpers/crypto.py +118 -118
- dominus/namespaces/__init__.py +26 -26
- dominus/namespaces/_deprecated_crossover.py +10 -10
- dominus/namespaces/_deprecated_sql.py +1341 -1341
- dominus/namespaces/auth.py +1056 -1056
- dominus/namespaces/courier.py +251 -251
- dominus/namespaces/db.py +267 -267
- dominus/namespaces/ddl.py +590 -590
- dominus/namespaces/files.py +299 -299
- dominus/namespaces/health.py +59 -59
- dominus/namespaces/logs.py +367 -367
- dominus/namespaces/open.py +72 -72
- dominus/namespaces/portal.py +504 -504
- dominus/namespaces/redis.py +357 -357
- dominus/namespaces/secrets.py +126 -126
- dominus/services/__init__.py +2 -2
- dominus/services/_deprecated_architect.py +323 -323
- dominus/services/_deprecated_sovereign.py +93 -93
- dominus/start.py +1034 -1034
- {dominus_sdk_python_dev-2.1.6.dist-info → dominus_sdk_python_dev-2.1.8.dist-info}/METADATA +381 -381
- dominus_sdk_python_dev-2.1.8.dist-info/RECORD +31 -0
- dominus_sdk_python_dev-2.1.6.dist-info/RECORD +0 -31
- {dominus_sdk_python_dev-2.1.6.dist-info → dominus_sdk_python_dev-2.1.8.dist-info}/WHEEL +0 -0
- {dominus_sdk_python_dev-2.1.6.dist-info → dominus_sdk_python_dev-2.1.8.dist-info}/top_level.txt +0 -0
dominus/namespaces/db.py
CHANGED
|
@@ -1,267 +1,267 @@
|
|
|
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 tables(self, schema: str = "public") -> List[Dict[str, Any]]:
|
|
49
|
-
"""
|
|
50
|
-
List tables in a schema.
|
|
51
|
-
|
|
52
|
-
Args:
|
|
53
|
-
schema: Schema name (default: "public")
|
|
54
|
-
|
|
55
|
-
Returns:
|
|
56
|
-
List of table metadata
|
|
57
|
-
"""
|
|
58
|
-
result = await self._client._request(
|
|
59
|
-
endpoint=f"/api/scribe/data/{schema}/tables",
|
|
60
|
-
method="GET"
|
|
61
|
-
)
|
|
62
|
-
return result.get("tables", result) if isinstance(result, dict) else result
|
|
63
|
-
|
|
64
|
-
async def columns(self, table: str, schema: str = "public") -> List[Dict[str, Any]]:
|
|
65
|
-
"""
|
|
66
|
-
List columns in a table.
|
|
67
|
-
|
|
68
|
-
Args:
|
|
69
|
-
table: Table name
|
|
70
|
-
schema: Schema name (default: "public")
|
|
71
|
-
|
|
72
|
-
Returns:
|
|
73
|
-
List of column metadata
|
|
74
|
-
"""
|
|
75
|
-
result = await self._client._request(
|
|
76
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/columns",
|
|
77
|
-
method="GET"
|
|
78
|
-
)
|
|
79
|
-
return result.get("columns", result) if isinstance(result, dict) else result
|
|
80
|
-
|
|
81
|
-
async def query(
|
|
82
|
-
self,
|
|
83
|
-
table: str,
|
|
84
|
-
schema: str = "public",
|
|
85
|
-
filters: Optional[Dict[str, Any]] = None,
|
|
86
|
-
sort_by: Optional[str] = None,
|
|
87
|
-
sort_order: str = "ASC",
|
|
88
|
-
limit: int = 100,
|
|
89
|
-
offset: int = 0,
|
|
90
|
-
reason: Optional[str] = None,
|
|
91
|
-
actor: Optional[str] = None
|
|
92
|
-
) -> Dict[str, Any]:
|
|
93
|
-
"""
|
|
94
|
-
Query table data with filtering, sorting, and pagination.
|
|
95
|
-
|
|
96
|
-
Args:
|
|
97
|
-
table: Table name
|
|
98
|
-
schema: Schema name (default: "public")
|
|
99
|
-
filters: Column:value filter dictionary
|
|
100
|
-
sort_by: Column to sort by
|
|
101
|
-
sort_order: "ASC" or "DESC"
|
|
102
|
-
limit: Maximum rows to return (default: 100)
|
|
103
|
-
offset: Rows to skip (default: 0)
|
|
104
|
-
reason: Access justification (required for secure tables)
|
|
105
|
-
actor: User ID or "machine" for audit trail
|
|
106
|
-
|
|
107
|
-
Returns:
|
|
108
|
-
Dict with "rows" and "total" keys
|
|
109
|
-
|
|
110
|
-
Raises:
|
|
111
|
-
SecureTableError: If accessing secure table without reason
|
|
112
|
-
"""
|
|
113
|
-
body = {
|
|
114
|
-
"filters": filters,
|
|
115
|
-
"sort_by": sort_by,
|
|
116
|
-
"sort_order": sort_order,
|
|
117
|
-
"limit": limit,
|
|
118
|
-
"offset": offset
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if reason:
|
|
122
|
-
body["reason"] = reason
|
|
123
|
-
if actor:
|
|
124
|
-
body["actor"] = actor
|
|
125
|
-
|
|
126
|
-
return await self._client._request(
|
|
127
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/query",
|
|
128
|
-
body=body
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
async def insert(
|
|
132
|
-
self,
|
|
133
|
-
table: str,
|
|
134
|
-
data: Dict[str, Any],
|
|
135
|
-
schema: str = "public",
|
|
136
|
-
reason: Optional[str] = None,
|
|
137
|
-
actor: Optional[str] = None
|
|
138
|
-
) -> Dict[str, Any]:
|
|
139
|
-
"""
|
|
140
|
-
Insert a row into a table.
|
|
141
|
-
|
|
142
|
-
Args:
|
|
143
|
-
table: Table name
|
|
144
|
-
data: Column:value dictionary
|
|
145
|
-
schema: Schema name (default: "public")
|
|
146
|
-
reason: Access justification (required for secure tables)
|
|
147
|
-
actor: User ID or "machine" for audit trail
|
|
148
|
-
|
|
149
|
-
Returns:
|
|
150
|
-
Inserted row data
|
|
151
|
-
"""
|
|
152
|
-
body = {"data": data}
|
|
153
|
-
|
|
154
|
-
if reason:
|
|
155
|
-
body["reason"] = reason
|
|
156
|
-
if actor:
|
|
157
|
-
body["actor"] = actor
|
|
158
|
-
|
|
159
|
-
return await self._client._request(
|
|
160
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/insert",
|
|
161
|
-
body=body
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
async def update(
|
|
165
|
-
self,
|
|
166
|
-
table: str,
|
|
167
|
-
data: Dict[str, Any],
|
|
168
|
-
filters: Dict[str, Any],
|
|
169
|
-
schema: str = "public",
|
|
170
|
-
reason: Optional[str] = None,
|
|
171
|
-
actor: Optional[str] = None
|
|
172
|
-
) -> Dict[str, Any]:
|
|
173
|
-
"""
|
|
174
|
-
Update rows matching filters.
|
|
175
|
-
|
|
176
|
-
Args:
|
|
177
|
-
table: Table name
|
|
178
|
-
data: Column:value dictionary of updates
|
|
179
|
-
filters: Column:value dictionary for WHERE clause
|
|
180
|
-
schema: Schema name (default: "public")
|
|
181
|
-
reason: Access justification (required for secure tables)
|
|
182
|
-
actor: User ID or "machine" for audit trail
|
|
183
|
-
|
|
184
|
-
Returns:
|
|
185
|
-
Dict with "affected_rows" count
|
|
186
|
-
"""
|
|
187
|
-
body = {
|
|
188
|
-
"data": data,
|
|
189
|
-
"filters": filters
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if reason:
|
|
193
|
-
body["reason"] = reason
|
|
194
|
-
if actor:
|
|
195
|
-
body["actor"] = actor
|
|
196
|
-
|
|
197
|
-
return await self._client._request(
|
|
198
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/update",
|
|
199
|
-
body=body
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
async def delete(
|
|
203
|
-
self,
|
|
204
|
-
table: str,
|
|
205
|
-
filters: Dict[str, Any],
|
|
206
|
-
schema: str = "public",
|
|
207
|
-
reason: Optional[str] = None,
|
|
208
|
-
actor: Optional[str] = None
|
|
209
|
-
) -> Dict[str, Any]:
|
|
210
|
-
"""
|
|
211
|
-
Delete rows matching filters.
|
|
212
|
-
|
|
213
|
-
Args:
|
|
214
|
-
table: Table name
|
|
215
|
-
filters: Column:value dictionary for WHERE clause
|
|
216
|
-
schema: Schema name (default: "public")
|
|
217
|
-
reason: Access justification (required for secure tables)
|
|
218
|
-
actor: User ID or "machine" for audit trail
|
|
219
|
-
|
|
220
|
-
Returns:
|
|
221
|
-
Dict with "affected_rows" count
|
|
222
|
-
"""
|
|
223
|
-
body = {"filters": filters}
|
|
224
|
-
|
|
225
|
-
if reason:
|
|
226
|
-
body["reason"] = reason
|
|
227
|
-
if actor:
|
|
228
|
-
body["actor"] = actor
|
|
229
|
-
|
|
230
|
-
return await self._client._request(
|
|
231
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/delete",
|
|
232
|
-
body=body
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
async def bulk_insert(
|
|
236
|
-
self,
|
|
237
|
-
table: str,
|
|
238
|
-
rows: List[Dict[str, Any]],
|
|
239
|
-
schema: str = "public",
|
|
240
|
-
reason: Optional[str] = None,
|
|
241
|
-
actor: Optional[str] = None
|
|
242
|
-
) -> Dict[str, Any]:
|
|
243
|
-
"""
|
|
244
|
-
Insert multiple rows at once.
|
|
245
|
-
|
|
246
|
-
Args:
|
|
247
|
-
table: Table name
|
|
248
|
-
rows: List of column:value dictionaries
|
|
249
|
-
schema: Schema name (default: "public")
|
|
250
|
-
reason: Access justification (required for secure tables)
|
|
251
|
-
actor: User ID or "machine" for audit trail
|
|
252
|
-
|
|
253
|
-
Returns:
|
|
254
|
-
Dict with "inserted_count" and optionally "rows"
|
|
255
|
-
"""
|
|
256
|
-
body = {"rows": rows}
|
|
257
|
-
|
|
258
|
-
if reason:
|
|
259
|
-
body["reason"] = reason
|
|
260
|
-
if actor:
|
|
261
|
-
body["actor"] = actor
|
|
262
|
-
|
|
263
|
-
return await self._client._request(
|
|
264
|
-
endpoint=f"/api/scribe/data/{schema}/{table}/bulk-insert",
|
|
265
|
-
body=body
|
|
266
|
-
)
|
|
267
|
-
|
|
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 tables(self, schema: str = "public") -> List[Dict[str, Any]]:
|
|
49
|
+
"""
|
|
50
|
+
List tables in a schema.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
schema: Schema name (default: "public")
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
List of table metadata
|
|
57
|
+
"""
|
|
58
|
+
result = await self._client._request(
|
|
59
|
+
endpoint=f"/api/scribe/data/{schema}/tables",
|
|
60
|
+
method="GET"
|
|
61
|
+
)
|
|
62
|
+
return result.get("tables", result) if isinstance(result, dict) else result
|
|
63
|
+
|
|
64
|
+
async def columns(self, table: str, schema: str = "public") -> List[Dict[str, Any]]:
|
|
65
|
+
"""
|
|
66
|
+
List columns in a table.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
table: Table name
|
|
70
|
+
schema: Schema name (default: "public")
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
List of column metadata
|
|
74
|
+
"""
|
|
75
|
+
result = await self._client._request(
|
|
76
|
+
endpoint=f"/api/scribe/data/{schema}/{table}/columns",
|
|
77
|
+
method="GET"
|
|
78
|
+
)
|
|
79
|
+
return result.get("columns", result) if isinstance(result, dict) else result
|
|
80
|
+
|
|
81
|
+
async def query(
|
|
82
|
+
self,
|
|
83
|
+
table: str,
|
|
84
|
+
schema: str = "public",
|
|
85
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
86
|
+
sort_by: Optional[str] = None,
|
|
87
|
+
sort_order: str = "ASC",
|
|
88
|
+
limit: int = 100,
|
|
89
|
+
offset: int = 0,
|
|
90
|
+
reason: Optional[str] = None,
|
|
91
|
+
actor: Optional[str] = None
|
|
92
|
+
) -> Dict[str, Any]:
|
|
93
|
+
"""
|
|
94
|
+
Query table data with filtering, sorting, and pagination.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
table: Table name
|
|
98
|
+
schema: Schema name (default: "public")
|
|
99
|
+
filters: Column:value filter dictionary
|
|
100
|
+
sort_by: Column to sort by
|
|
101
|
+
sort_order: "ASC" or "DESC"
|
|
102
|
+
limit: Maximum rows to return (default: 100)
|
|
103
|
+
offset: Rows to skip (default: 0)
|
|
104
|
+
reason: Access justification (required for secure tables)
|
|
105
|
+
actor: User ID or "machine" for audit trail
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Dict with "rows" and "total" keys
|
|
109
|
+
|
|
110
|
+
Raises:
|
|
111
|
+
SecureTableError: If accessing secure table without reason
|
|
112
|
+
"""
|
|
113
|
+
body = {
|
|
114
|
+
"filters": filters,
|
|
115
|
+
"sort_by": sort_by,
|
|
116
|
+
"sort_order": sort_order,
|
|
117
|
+
"limit": limit,
|
|
118
|
+
"offset": offset
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if reason:
|
|
122
|
+
body["reason"] = reason
|
|
123
|
+
if actor:
|
|
124
|
+
body["actor"] = actor
|
|
125
|
+
|
|
126
|
+
return await self._client._request(
|
|
127
|
+
endpoint=f"/api/scribe/data/{schema}/{table}/query",
|
|
128
|
+
body=body
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
async def insert(
|
|
132
|
+
self,
|
|
133
|
+
table: str,
|
|
134
|
+
data: Dict[str, Any],
|
|
135
|
+
schema: str = "public",
|
|
136
|
+
reason: Optional[str] = None,
|
|
137
|
+
actor: Optional[str] = None
|
|
138
|
+
) -> Dict[str, Any]:
|
|
139
|
+
"""
|
|
140
|
+
Insert a row into a table.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
table: Table name
|
|
144
|
+
data: Column:value dictionary
|
|
145
|
+
schema: Schema name (default: "public")
|
|
146
|
+
reason: Access justification (required for secure tables)
|
|
147
|
+
actor: User ID or "machine" for audit trail
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Inserted row data
|
|
151
|
+
"""
|
|
152
|
+
body = {"data": data}
|
|
153
|
+
|
|
154
|
+
if reason:
|
|
155
|
+
body["reason"] = reason
|
|
156
|
+
if actor:
|
|
157
|
+
body["actor"] = actor
|
|
158
|
+
|
|
159
|
+
return await self._client._request(
|
|
160
|
+
endpoint=f"/api/scribe/data/{schema}/{table}/insert",
|
|
161
|
+
body=body
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
async def update(
|
|
165
|
+
self,
|
|
166
|
+
table: str,
|
|
167
|
+
data: Dict[str, Any],
|
|
168
|
+
filters: Dict[str, Any],
|
|
169
|
+
schema: str = "public",
|
|
170
|
+
reason: Optional[str] = None,
|
|
171
|
+
actor: Optional[str] = None
|
|
172
|
+
) -> Dict[str, Any]:
|
|
173
|
+
"""
|
|
174
|
+
Update rows matching filters.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
table: Table name
|
|
178
|
+
data: Column:value dictionary of updates
|
|
179
|
+
filters: Column:value dictionary for WHERE clause
|
|
180
|
+
schema: Schema name (default: "public")
|
|
181
|
+
reason: Access justification (required for secure tables)
|
|
182
|
+
actor: User ID or "machine" for audit trail
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
Dict with "affected_rows" count
|
|
186
|
+
"""
|
|
187
|
+
body = {
|
|
188
|
+
"data": data,
|
|
189
|
+
"filters": filters
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if reason:
|
|
193
|
+
body["reason"] = reason
|
|
194
|
+
if actor:
|
|
195
|
+
body["actor"] = actor
|
|
196
|
+
|
|
197
|
+
return await self._client._request(
|
|
198
|
+
endpoint=f"/api/scribe/data/{schema}/{table}/update",
|
|
199
|
+
body=body
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
async def delete(
|
|
203
|
+
self,
|
|
204
|
+
table: str,
|
|
205
|
+
filters: Dict[str, Any],
|
|
206
|
+
schema: str = "public",
|
|
207
|
+
reason: Optional[str] = None,
|
|
208
|
+
actor: Optional[str] = None
|
|
209
|
+
) -> Dict[str, Any]:
|
|
210
|
+
"""
|
|
211
|
+
Delete rows matching filters.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
table: Table name
|
|
215
|
+
filters: Column:value dictionary for WHERE clause
|
|
216
|
+
schema: Schema name (default: "public")
|
|
217
|
+
reason: Access justification (required for secure tables)
|
|
218
|
+
actor: User ID or "machine" for audit trail
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
Dict with "affected_rows" count
|
|
222
|
+
"""
|
|
223
|
+
body = {"filters": filters}
|
|
224
|
+
|
|
225
|
+
if reason:
|
|
226
|
+
body["reason"] = reason
|
|
227
|
+
if actor:
|
|
228
|
+
body["actor"] = actor
|
|
229
|
+
|
|
230
|
+
return await self._client._request(
|
|
231
|
+
endpoint=f"/api/scribe/data/{schema}/{table}/delete",
|
|
232
|
+
body=body
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
async def bulk_insert(
|
|
236
|
+
self,
|
|
237
|
+
table: str,
|
|
238
|
+
rows: List[Dict[str, Any]],
|
|
239
|
+
schema: str = "public",
|
|
240
|
+
reason: Optional[str] = None,
|
|
241
|
+
actor: Optional[str] = None
|
|
242
|
+
) -> Dict[str, Any]:
|
|
243
|
+
"""
|
|
244
|
+
Insert multiple rows at once.
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
table: Table name
|
|
248
|
+
rows: List of column:value dictionaries
|
|
249
|
+
schema: Schema name (default: "public")
|
|
250
|
+
reason: Access justification (required for secure tables)
|
|
251
|
+
actor: User ID or "machine" for audit trail
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
Dict with "inserted_count" and optionally "rows"
|
|
255
|
+
"""
|
|
256
|
+
body = {"rows": rows}
|
|
257
|
+
|
|
258
|
+
if reason:
|
|
259
|
+
body["reason"] = reason
|
|
260
|
+
if actor:
|
|
261
|
+
body["actor"] = actor
|
|
262
|
+
|
|
263
|
+
return await self._client._request(
|
|
264
|
+
endpoint=f"/api/scribe/data/{schema}/{table}/bulk-insert",
|
|
265
|
+
body=body
|
|
266
|
+
)
|
|
267
|
+
|