dominus-sdk-python-dev 2.1.6__py3-none-any.whl → 2.1.7__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/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
+