vention-storage 0.5.2__tar.gz → 0.6__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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: vention-storage
3
- Version: 0.5.2
3
+ Version: 0.6
4
4
  Summary: A framework for storing and managing component and application data for machine apps.
5
5
  License: Proprietary
6
6
  Author: VentionCo
@@ -8,10 +8,9 @@ Requires-Python: >=3.10,<3.11
8
8
  Classifier: License :: Other/Proprietary License
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Programming Language :: Python :: 3.10
11
- Requires-Dist: fastapi (==0.121.1)
12
11
  Requires-Dist: python-multipart (>=0.0.20,<0.0.21)
13
12
  Requires-Dist: sqlmodel (==0.0.27)
14
- Requires-Dist: uvicorn (>=0.35.0,<0.36.0)
13
+ Requires-Dist: vention-communication (>=0.2.2,<0.3.0)
15
14
  Description-Content-Type: text/markdown
16
15
 
17
16
  # Vention Storage
@@ -35,8 +34,8 @@ A framework for storing and managing component and application data with persist
35
34
  - Strong typing & validation via SQLModel
36
35
  - Lifecycle hooks before/after insert, update, delete
37
36
  - Soft delete with `deleted_at` fields
38
- - REST API generation with Create, Read, Update, Delete + audit
39
- - Health & monitoring endpoints (audit log, schema diagram)
37
+ - ConnectRPC bundle generation with Create, Read, Update, Delete + audit
38
+ - Health & monitoring actions (audit log, schema diagram)
40
39
  - Batch operations for insert/delete
41
40
  - Session management with smart reuse & transactions
42
41
  - Bootstrap system for one-command setup
@@ -51,7 +50,7 @@ Vention Storage is a component-based persistence layer for machine apps:
51
50
  - **ModelAccessor** → Strongly-typed Create, Read, Update, Delete interface for your SQLModel classes
52
51
  - **Hooks** → Functions that run before/after Create, Read, Update, Delete operations
53
52
  - **AuditLog** → Automatically records all data mutations
54
- - **Routers** → Auto-generated FastAPI endpoints for Create, Read, Update, Delete + database management
53
+ - **RpcBundle** → Auto-generated ConnectRPC bundle with Create, Read, Update, Delete + database management actions
55
54
 
56
55
  ## ⚙️ Installation & Setup
57
56
 
@@ -76,15 +75,16 @@ pip install sqlalchemy-schemadisplay
76
75
 
77
76
  ## 🚀 Quickstart Tutorial
78
77
 
79
- Define a model, bootstrap storage, and get full Create, Read, Update, Delete endpoints in minutes:
78
+ Define a model, bootstrap storage, and get full Create, Read, Update, Delete RPC actions in minutes:
80
79
 
81
80
  ```python
82
81
  from datetime import datetime
83
82
  from typing import Optional
84
83
  from sqlmodel import Field, SQLModel
85
- from fastapi import FastAPI
84
+ from communication.app import VentionApp
86
85
  from storage.bootstrap import bootstrap
87
86
  from storage.accessor import ModelAccessor
87
+ from storage.vention_communication import build_storage_bundle
88
88
 
89
89
  class User(SQLModel, table=True):
90
90
  id: Optional[int] = Field(default=None, primary_key=True)
@@ -92,18 +92,27 @@ class User(SQLModel, table=True):
92
92
  email: str
93
93
  deleted_at: Optional[datetime] = Field(default=None, index=True)
94
94
 
95
- app = FastAPI()
96
- user_accessor = ModelAccessor(User, "users")
97
-
95
+ # Initialize database
98
96
  bootstrap(
99
- app,
100
- accessors=[user_accessor],
101
97
  database_url="sqlite:///./my_app.db",
102
98
  create_tables=True
103
99
  )
100
+
101
+ # Create accessor
102
+ user_accessor = ModelAccessor(User, "users")
103
+
104
+ # Build RPC bundle and add to app
105
+ app = VentionApp(name="my-app")
106
+ storage_bundle = build_storage_bundle(
107
+ accessors=[user_accessor],
108
+ max_records_per_model=100,
109
+ enable_db_actions=True
110
+ )
111
+ app.add_bundle(storage_bundle)
112
+ app.finalize()
104
113
  ```
105
114
 
106
- ➡️ You now have Create, Read, Update, Delete, audit, backup, and CSV endpoints at `/users` and `/db`.
115
+ ➡️ You now have Create, Read, Update, Delete, audit, backup, and CSV actions available via ConnectRPC.
107
116
 
108
117
  ## 🛠 How-to Guides
109
118
 
@@ -115,35 +124,46 @@ bootstrap(
115
124
 
116
125
  product_accessor = ModelAccessor(Product, "products")
117
126
 
118
- bootstrap(
119
- app,
127
+ # Build bundle with multiple accessors
128
+ storage_bundle = build_storage_bundle(
120
129
  accessors=[user_accessor, product_accessor],
121
- database_url="sqlite:///./my_app.db",
122
- create_tables=True,
123
130
  max_records_per_model=100,
124
- enable_db_router=True
131
+ enable_db_actions=True
125
132
  )
133
+ app.add_bundle(storage_bundle)
126
134
  ```
127
135
 
128
136
  ### Export to CSV
129
137
 
130
138
  ```python
131
- response = requests.get("http://localhost:8000/db/export.zip")
139
+ # Using ConnectRPC client
140
+ from communication.client import ConnectClient
141
+
142
+ client = ConnectClient("http://localhost:8000")
143
+ response = await client.call("Database_ExportZip", {})
132
144
  with open("backup.zip", "wb") as f:
133
- f.write(response.content)
145
+ f.write(response.data)
134
146
  ```
135
147
 
136
148
  ### Backup & Restore
137
149
 
138
150
  ```python
139
151
  # Backup
140
- r = requests.get("http://localhost:8000/db/backup.sqlite")
141
- with open("backup.sqlite", "wb") as f: f.write(r.content)
152
+ backup_response = await client.call("Database_BackupSqlite", {})
153
+ with open(backup_response.filename, "wb") as f:
154
+ f.write(backup_response.data)
142
155
 
143
156
  # Restore
144
157
  with open("backup.sqlite", "rb") as f:
145
- files = {"file": ("backup.sqlite", f, "application/x-sqlite3")}
146
- requests.post("http://localhost:8000/db/restore", files=files)
158
+ restore_response = await client.call(
159
+ "Database_RestoreSqlite",
160
+ {
161
+ "bytes": f.read(),
162
+ "filename": "backup.sqlite",
163
+ "integrity_check": True,
164
+ "dry_run": False
165
+ }
166
+ )
147
167
  ```
148
168
 
149
169
  ### Use Lifecycle Hooks
@@ -190,52 +210,73 @@ user_accessor.restore(user.id, actor="admin")
190
210
  ```
191
211
 
192
212
 
193
- ### Using the REST API
213
+ ### Using ConnectRPC Client
194
214
 
195
- Once bootstrapped, each `ModelAccessor` automatically exposes full CRUD endpoints.
215
+ Once the bundle is added to your `VentionApp`, each `ModelAccessor` automatically exposes full CRUD actions via ConnectRPC.
196
216
 
197
- Example: interacting with the `/users` API.
217
+ Example: interacting with the `Users` RPC actions.
198
218
 
199
219
  ```typescript
200
- import axios from "axios";
220
+ import { createPromiseClient } from "@connectrpc/connect";
221
+ import { createConnectTransport } from "@connectrpc/connect-web";
201
222
 
202
- const api = axios.create({
203
- baseURL: "http://localhost:8000", // your backend url
204
- headers: { "X-User": "operator" }, // used in audit logs
223
+ const transport = createConnectTransport({
224
+ baseUrl: "http://localhost:8000",
205
225
  });
206
226
 
227
+ const client = createPromiseClient(YourServiceClient, transport);
228
+
207
229
  // Create
208
230
  export async function createUser(name: string, email: string) {
209
- const res = await api.post("/users/", { name, email });
210
- return res.data;
231
+ const res = await client.usersCreateRecord({
232
+ record: { name, email },
233
+ actor: "operator"
234
+ });
235
+ return res.record;
211
236
  }
212
237
 
213
238
  // Read
214
239
  export async function getUser(id: number) {
215
- const res = await api.get(`/users/${id}`);
216
- return res.data;
240
+ const res = await client.usersGetRecord({
241
+ recordId: id,
242
+ includeDeleted: false
243
+ });
244
+ return res.record;
217
245
  }
218
246
 
219
247
  // Update
220
248
  export async function updateUser(id: number, name: string) {
221
- const res = await api.put(`/users/${id}`, { name });
222
- return res.data;
249
+ const res = await client.usersUpdateRecord({
250
+ recordId: id,
251
+ record: { name },
252
+ actor: "operator"
253
+ });
254
+ return res.record;
223
255
  }
224
256
 
225
257
  // Delete (soft delete if model supports deleted_at)
226
258
  export async function deleteUser(id: number) {
227
- await api.delete(`/users/${id}`);
259
+ await client.usersDeleteRecord({
260
+ recordId: id,
261
+ actor: "operator"
262
+ });
228
263
  }
229
264
 
230
265
  // Restore
231
266
  export async function restoreUser(id: number) {
232
- await api.post(`/users/${id}/restore`);
267
+ const res = await client.usersRestoreRecord({
268
+ recordId: id,
269
+ actor: "operator"
270
+ });
271
+ return res.record;
233
272
  }
234
273
 
235
274
  // List
236
275
  export async function listUsers() {
237
- const res = await api.get("/users/");
238
- return res.data;
276
+ const res = await client.usersListRecords({
277
+ includeDeleted: false
278
+ });
279
+ return res.records;
239
280
  }
240
281
  ```
241
282
 
@@ -246,20 +287,36 @@ export async function listUsers() {
246
287
 
247
288
  ```python
248
289
  def bootstrap(
249
- app: FastAPI,
250
290
  *,
251
- accessors: Iterable[ModelAccessor[Any]],
252
291
  database_url: Optional[str] = None,
253
292
  create_tables: bool = True,
254
- max_records_per_model: Optional[int] = 5,
255
- enable_db_router: bool = True,
256
293
  ) -> None
257
294
  ```
258
295
 
296
+ Initialize the database engine and optionally create tables. This function performs environment setup only.
297
+
298
+ ### build_storage_bundle
299
+
300
+ ```python
301
+ def build_storage_bundle(
302
+ *,
303
+ accessors: Sequence[ModelAccessor[Any]],
304
+ max_records_per_model: Optional[int] = 5,
305
+ enable_db_actions: bool = True,
306
+ ) -> RpcBundle
307
+ ```
308
+
309
+ Build a ConnectRPC RpcBundle exposing CRUD and database utilities. Returns an `RpcBundle` that can be added to a `VentionApp` using `app.add_bundle()`.
310
+
259
311
  ### ModelAccessor
260
312
 
261
313
  ```python
262
- ModelAccessor(model: Type[ModelType], component_name: str)
314
+ ModelAccessor(
315
+ model: Type[ModelType],
316
+ component_name: str,
317
+ *,
318
+ enable_auditing: bool = True,
319
+ )
263
320
  ```
264
321
 
265
322
  **Read**
@@ -284,10 +341,8 @@ ModelAccessor(model: Type[ModelType], component_name: str)
284
341
  - `@accessor.before_delete()`
285
342
  - `@accessor.after_delete()`
286
343
 
287
- ### Routers
288
-
289
- - `build_crud_router(accessor, max_records=100) -> APIRouter`
290
- - `build_db_router(audit_default_limit=100, audit_max_limit=1000) -> APIRouter`
344
+ **Parameters**
345
+ - `enable_auditing`: If `False`, disables audit logging for this accessor. Useful for models that shouldn't be audited (e.g., audit logs themselves). Defaults to `True`.
291
346
 
292
347
  ### Database Helpers
293
348
 
@@ -19,8 +19,8 @@ A framework for storing and managing component and application data with persist
19
19
  - Strong typing & validation via SQLModel
20
20
  - Lifecycle hooks before/after insert, update, delete
21
21
  - Soft delete with `deleted_at` fields
22
- - REST API generation with Create, Read, Update, Delete + audit
23
- - Health & monitoring endpoints (audit log, schema diagram)
22
+ - ConnectRPC bundle generation with Create, Read, Update, Delete + audit
23
+ - Health & monitoring actions (audit log, schema diagram)
24
24
  - Batch operations for insert/delete
25
25
  - Session management with smart reuse & transactions
26
26
  - Bootstrap system for one-command setup
@@ -35,7 +35,7 @@ Vention Storage is a component-based persistence layer for machine apps:
35
35
  - **ModelAccessor** → Strongly-typed Create, Read, Update, Delete interface for your SQLModel classes
36
36
  - **Hooks** → Functions that run before/after Create, Read, Update, Delete operations
37
37
  - **AuditLog** → Automatically records all data mutations
38
- - **Routers** → Auto-generated FastAPI endpoints for Create, Read, Update, Delete + database management
38
+ - **RpcBundle** → Auto-generated ConnectRPC bundle with Create, Read, Update, Delete + database management actions
39
39
 
40
40
  ## ⚙️ Installation & Setup
41
41
 
@@ -60,15 +60,16 @@ pip install sqlalchemy-schemadisplay
60
60
 
61
61
  ## 🚀 Quickstart Tutorial
62
62
 
63
- Define a model, bootstrap storage, and get full Create, Read, Update, Delete endpoints in minutes:
63
+ Define a model, bootstrap storage, and get full Create, Read, Update, Delete RPC actions in minutes:
64
64
 
65
65
  ```python
66
66
  from datetime import datetime
67
67
  from typing import Optional
68
68
  from sqlmodel import Field, SQLModel
69
- from fastapi import FastAPI
69
+ from communication.app import VentionApp
70
70
  from storage.bootstrap import bootstrap
71
71
  from storage.accessor import ModelAccessor
72
+ from storage.vention_communication import build_storage_bundle
72
73
 
73
74
  class User(SQLModel, table=True):
74
75
  id: Optional[int] = Field(default=None, primary_key=True)
@@ -76,18 +77,27 @@ class User(SQLModel, table=True):
76
77
  email: str
77
78
  deleted_at: Optional[datetime] = Field(default=None, index=True)
78
79
 
79
- app = FastAPI()
80
- user_accessor = ModelAccessor(User, "users")
81
-
80
+ # Initialize database
82
81
  bootstrap(
83
- app,
84
- accessors=[user_accessor],
85
82
  database_url="sqlite:///./my_app.db",
86
83
  create_tables=True
87
84
  )
85
+
86
+ # Create accessor
87
+ user_accessor = ModelAccessor(User, "users")
88
+
89
+ # Build RPC bundle and add to app
90
+ app = VentionApp(name="my-app")
91
+ storage_bundle = build_storage_bundle(
92
+ accessors=[user_accessor],
93
+ max_records_per_model=100,
94
+ enable_db_actions=True
95
+ )
96
+ app.add_bundle(storage_bundle)
97
+ app.finalize()
88
98
  ```
89
99
 
90
- ➡️ You now have Create, Read, Update, Delete, audit, backup, and CSV endpoints at `/users` and `/db`.
100
+ ➡️ You now have Create, Read, Update, Delete, audit, backup, and CSV actions available via ConnectRPC.
91
101
 
92
102
  ## 🛠 How-to Guides
93
103
 
@@ -99,35 +109,46 @@ bootstrap(
99
109
 
100
110
  product_accessor = ModelAccessor(Product, "products")
101
111
 
102
- bootstrap(
103
- app,
112
+ # Build bundle with multiple accessors
113
+ storage_bundle = build_storage_bundle(
104
114
  accessors=[user_accessor, product_accessor],
105
- database_url="sqlite:///./my_app.db",
106
- create_tables=True,
107
115
  max_records_per_model=100,
108
- enable_db_router=True
116
+ enable_db_actions=True
109
117
  )
118
+ app.add_bundle(storage_bundle)
110
119
  ```
111
120
 
112
121
  ### Export to CSV
113
122
 
114
123
  ```python
115
- response = requests.get("http://localhost:8000/db/export.zip")
124
+ # Using ConnectRPC client
125
+ from communication.client import ConnectClient
126
+
127
+ client = ConnectClient("http://localhost:8000")
128
+ response = await client.call("Database_ExportZip", {})
116
129
  with open("backup.zip", "wb") as f:
117
- f.write(response.content)
130
+ f.write(response.data)
118
131
  ```
119
132
 
120
133
  ### Backup & Restore
121
134
 
122
135
  ```python
123
136
  # Backup
124
- r = requests.get("http://localhost:8000/db/backup.sqlite")
125
- with open("backup.sqlite", "wb") as f: f.write(r.content)
137
+ backup_response = await client.call("Database_BackupSqlite", {})
138
+ with open(backup_response.filename, "wb") as f:
139
+ f.write(backup_response.data)
126
140
 
127
141
  # Restore
128
142
  with open("backup.sqlite", "rb") as f:
129
- files = {"file": ("backup.sqlite", f, "application/x-sqlite3")}
130
- requests.post("http://localhost:8000/db/restore", files=files)
143
+ restore_response = await client.call(
144
+ "Database_RestoreSqlite",
145
+ {
146
+ "bytes": f.read(),
147
+ "filename": "backup.sqlite",
148
+ "integrity_check": True,
149
+ "dry_run": False
150
+ }
151
+ )
131
152
  ```
132
153
 
133
154
  ### Use Lifecycle Hooks
@@ -174,52 +195,73 @@ user_accessor.restore(user.id, actor="admin")
174
195
  ```
175
196
 
176
197
 
177
- ### Using the REST API
198
+ ### Using ConnectRPC Client
178
199
 
179
- Once bootstrapped, each `ModelAccessor` automatically exposes full CRUD endpoints.
200
+ Once the bundle is added to your `VentionApp`, each `ModelAccessor` automatically exposes full CRUD actions via ConnectRPC.
180
201
 
181
- Example: interacting with the `/users` API.
202
+ Example: interacting with the `Users` RPC actions.
182
203
 
183
204
  ```typescript
184
- import axios from "axios";
205
+ import { createPromiseClient } from "@connectrpc/connect";
206
+ import { createConnectTransport } from "@connectrpc/connect-web";
185
207
 
186
- const api = axios.create({
187
- baseURL: "http://localhost:8000", // your backend url
188
- headers: { "X-User": "operator" }, // used in audit logs
208
+ const transport = createConnectTransport({
209
+ baseUrl: "http://localhost:8000",
189
210
  });
190
211
 
212
+ const client = createPromiseClient(YourServiceClient, transport);
213
+
191
214
  // Create
192
215
  export async function createUser(name: string, email: string) {
193
- const res = await api.post("/users/", { name, email });
194
- return res.data;
216
+ const res = await client.usersCreateRecord({
217
+ record: { name, email },
218
+ actor: "operator"
219
+ });
220
+ return res.record;
195
221
  }
196
222
 
197
223
  // Read
198
224
  export async function getUser(id: number) {
199
- const res = await api.get(`/users/${id}`);
200
- return res.data;
225
+ const res = await client.usersGetRecord({
226
+ recordId: id,
227
+ includeDeleted: false
228
+ });
229
+ return res.record;
201
230
  }
202
231
 
203
232
  // Update
204
233
  export async function updateUser(id: number, name: string) {
205
- const res = await api.put(`/users/${id}`, { name });
206
- return res.data;
234
+ const res = await client.usersUpdateRecord({
235
+ recordId: id,
236
+ record: { name },
237
+ actor: "operator"
238
+ });
239
+ return res.record;
207
240
  }
208
241
 
209
242
  // Delete (soft delete if model supports deleted_at)
210
243
  export async function deleteUser(id: number) {
211
- await api.delete(`/users/${id}`);
244
+ await client.usersDeleteRecord({
245
+ recordId: id,
246
+ actor: "operator"
247
+ });
212
248
  }
213
249
 
214
250
  // Restore
215
251
  export async function restoreUser(id: number) {
216
- await api.post(`/users/${id}/restore`);
252
+ const res = await client.usersRestoreRecord({
253
+ recordId: id,
254
+ actor: "operator"
255
+ });
256
+ return res.record;
217
257
  }
218
258
 
219
259
  // List
220
260
  export async function listUsers() {
221
- const res = await api.get("/users/");
222
- return res.data;
261
+ const res = await client.usersListRecords({
262
+ includeDeleted: false
263
+ });
264
+ return res.records;
223
265
  }
224
266
  ```
225
267
 
@@ -230,20 +272,36 @@ export async function listUsers() {
230
272
 
231
273
  ```python
232
274
  def bootstrap(
233
- app: FastAPI,
234
275
  *,
235
- accessors: Iterable[ModelAccessor[Any]],
236
276
  database_url: Optional[str] = None,
237
277
  create_tables: bool = True,
238
- max_records_per_model: Optional[int] = 5,
239
- enable_db_router: bool = True,
240
278
  ) -> None
241
279
  ```
242
280
 
281
+ Initialize the database engine and optionally create tables. This function performs environment setup only.
282
+
283
+ ### build_storage_bundle
284
+
285
+ ```python
286
+ def build_storage_bundle(
287
+ *,
288
+ accessors: Sequence[ModelAccessor[Any]],
289
+ max_records_per_model: Optional[int] = 5,
290
+ enable_db_actions: bool = True,
291
+ ) -> RpcBundle
292
+ ```
293
+
294
+ Build a ConnectRPC RpcBundle exposing CRUD and database utilities. Returns an `RpcBundle` that can be added to a `VentionApp` using `app.add_bundle()`.
295
+
243
296
  ### ModelAccessor
244
297
 
245
298
  ```python
246
- ModelAccessor(model: Type[ModelType], component_name: str)
299
+ ModelAccessor(
300
+ model: Type[ModelType],
301
+ component_name: str,
302
+ *,
303
+ enable_auditing: bool = True,
304
+ )
247
305
  ```
248
306
 
249
307
  **Read**
@@ -268,10 +326,8 @@ ModelAccessor(model: Type[ModelType], component_name: str)
268
326
  - `@accessor.before_delete()`
269
327
  - `@accessor.after_delete()`
270
328
 
271
- ### Routers
272
-
273
- - `build_crud_router(accessor, max_records=100) -> APIRouter`
274
- - `build_db_router(audit_default_limit=100, audit_max_limit=1000) -> APIRouter`
329
+ **Parameters**
330
+ - `enable_auditing`: If `False`, disables audit logging for this accessor. Useful for models that shouldn't be audited (e.g., audit logs themselves). Defaults to `True`.
275
331
 
276
332
  ### Database Helpers
277
333
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "vention-storage"
3
- version = "0.5.2"
3
+ version = "0.6"
4
4
  description = "A framework for storing and managing component and application data for machine apps."
5
5
  authors = [ "VentionCo" ]
6
6
  readme = "README.md"
@@ -10,16 +10,9 @@ packages = [{ include = "storage", from = "src" }]
10
10
  [tool.poetry.dependencies]
11
11
  sqlmodel = "0.0.27"
12
12
  python = ">=3.10,<3.11"
13
- fastapi = "0.121.1"
14
- uvicorn = "^0.35.0"
15
13
  python-multipart = "^0.0.20"
14
+ vention-communication= "^0.2.2"
16
15
 
17
16
  [tool.poetry.group.dev.dependencies]
18
17
  pytest = "^8.3.4"
19
- ruff = "^0.8.0"
20
-
21
- [build-system]
22
- requires = [
23
- "poetry-core>=1.0.0,<2.0.0"
24
- ]
25
- build-backend = "poetry.core.masonry.api"
18
+ ruff = "^0.8.0"