zova 0.17.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.
zova-0.17.0/Cargo.lock ADDED
@@ -0,0 +1,148 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "heck"
7
+ version = "0.5.0"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
10
+
11
+ [[package]]
12
+ name = "libc"
13
+ version = "0.2.186"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
16
+
17
+ [[package]]
18
+ name = "once_cell"
19
+ version = "1.21.4"
20
+ source = "registry+https://github.com/rust-lang/crates.io-index"
21
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
22
+
23
+ [[package]]
24
+ name = "portable-atomic"
25
+ version = "1.13.1"
26
+ source = "registry+https://github.com/rust-lang/crates.io-index"
27
+ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
28
+
29
+ [[package]]
30
+ name = "proc-macro2"
31
+ version = "1.0.106"
32
+ source = "registry+https://github.com/rust-lang/crates.io-index"
33
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
34
+ dependencies = [
35
+ "unicode-ident",
36
+ ]
37
+
38
+ [[package]]
39
+ name = "pyo3"
40
+ version = "0.29.0"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "cd274650b21d4bfc26a0a47587962c1edb425f69287324355cd040c3ea66071c"
43
+ dependencies = [
44
+ "libc",
45
+ "once_cell",
46
+ "portable-atomic",
47
+ "pyo3-build-config",
48
+ "pyo3-ffi",
49
+ "pyo3-macros",
50
+ ]
51
+
52
+ [[package]]
53
+ name = "pyo3-build-config"
54
+ version = "0.29.0"
55
+ source = "registry+https://github.com/rust-lang/crates.io-index"
56
+ checksum = "c5e2a7d2f0d013342f295c048ad19237add5154a55b1c5a254c0ec93d4109078"
57
+ dependencies = [
58
+ "target-lexicon",
59
+ ]
60
+
61
+ [[package]]
62
+ name = "pyo3-ffi"
63
+ version = "0.29.0"
64
+ source = "registry+https://github.com/rust-lang/crates.io-index"
65
+ checksum = "ca85c467da1bbc8d866eea5deff9cf29ea5f7785054a17da36e65bda9c05845b"
66
+ dependencies = [
67
+ "libc",
68
+ "pyo3-build-config",
69
+ ]
70
+
71
+ [[package]]
72
+ name = "pyo3-macros"
73
+ version = "0.29.0"
74
+ source = "registry+https://github.com/rust-lang/crates.io-index"
75
+ checksum = "9ac53762fd065daa3194dd09337a38bd793a188100fd1a9304c4ab312d901771"
76
+ dependencies = [
77
+ "proc-macro2",
78
+ "pyo3-macros-backend",
79
+ "quote",
80
+ "syn",
81
+ ]
82
+
83
+ [[package]]
84
+ name = "pyo3-macros-backend"
85
+ version = "0.29.0"
86
+ source = "registry+https://github.com/rust-lang/crates.io-index"
87
+ checksum = "4ca3a1557399783172dc5bf39cfca835157732532cba56b71d2292161e53b362"
88
+ dependencies = [
89
+ "heck",
90
+ "proc-macro2",
91
+ "quote",
92
+ "syn",
93
+ ]
94
+
95
+ [[package]]
96
+ name = "quote"
97
+ version = "1.0.46"
98
+ source = "registry+https://github.com/rust-lang/crates.io-index"
99
+ checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
100
+ dependencies = [
101
+ "proc-macro2",
102
+ ]
103
+
104
+ [[package]]
105
+ name = "syn"
106
+ version = "2.0.118"
107
+ source = "registry+https://github.com/rust-lang/crates.io-index"
108
+ checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
109
+ dependencies = [
110
+ "proc-macro2",
111
+ "quote",
112
+ "unicode-ident",
113
+ ]
114
+
115
+ [[package]]
116
+ name = "target-lexicon"
117
+ version = "0.13.5"
118
+ source = "registry+https://github.com/rust-lang/crates.io-index"
119
+ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
120
+
121
+ [[package]]
122
+ name = "unicode-ident"
123
+ version = "1.0.24"
124
+ source = "registry+https://github.com/rust-lang/crates.io-index"
125
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
126
+
127
+ [[package]]
128
+ name = "zova"
129
+ version = "0.17.0"
130
+ source = "registry+https://github.com/rust-lang/crates.io-index"
131
+ checksum = "4a8fb0a3a7ca0fef420a4c4e1bd31bb519e7bc697553f541e249163cf866ef56"
132
+ dependencies = [
133
+ "zova-sys",
134
+ ]
135
+
136
+ [[package]]
137
+ name = "zova-python"
138
+ version = "0.17.0"
139
+ dependencies = [
140
+ "pyo3",
141
+ "zova",
142
+ ]
143
+
144
+ [[package]]
145
+ name = "zova-sys"
146
+ version = "0.17.0"
147
+ source = "registry+https://github.com/rust-lang/crates.io-index"
148
+ checksum = "4c11b4d0622a9a16ef3f75518face4a6425c70bd5c4e872612c8c231a0f915bf"
zova-0.17.0/Cargo.toml ADDED
@@ -0,0 +1,17 @@
1
+ [package]
2
+ name = "zova-python"
3
+ version = "0.17.0"
4
+ edition = "2021"
5
+ license = "MIT"
6
+ description = "PyO3 extension for the Zova Python package."
7
+ repository = "https://github.com/atasesli/zova"
8
+ homepage = "https://github.com/atasesli/zova"
9
+ readme = "README.md"
10
+
11
+ [lib]
12
+ name = "zova_python"
13
+ crate-type = ["cdylib"]
14
+
15
+ [dependencies]
16
+ pyo3 = { version = "0.29.0", features = ["extension-module"] }
17
+ zova_rust = { package = "zova", version = "0.17.0" }
zova-0.17.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ata Sesli
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
zova-0.17.0/PKG-INFO ADDED
@@ -0,0 +1,319 @@
1
+ Metadata-Version: 2.4
2
+ Name: zova
3
+ Version: 0.17.0
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Operating System :: OS Independent
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Programming Language :: Rust
14
+ Classifier: Topic :: Database
15
+ License-File: LICENSE
16
+ Summary: SQLite-backed embedded database for records, objects, and vectors in one local file.
17
+ Keywords: zova,sqlite,database,objects,vectors
18
+ Home-Page: https://github.com/atasesli/zova
19
+ Author: Ata Sesli
20
+ License-Expression: MIT
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
23
+ Project-URL: Homepage, https://github.com/atasesli/zova
24
+ Project-URL: Issues, https://github.com/atasesli/zova/issues
25
+ Project-URL: Repository, https://github.com/atasesli/zova
26
+
27
+ # Zova Python Bindings
28
+
29
+ This package contains the source-first Python bindings for Zova.
30
+
31
+ It is a PyO3/maturin extension backed by the safe Rust `zova` binding. It does
32
+ not wrap the C ABI directly with `ctypes` or cffi. The native build still uses
33
+ Zova's C ABI underneath through the Rust `zova-sys` crate, so Python gets the
34
+ same records/objects/vectors foundation without reimplementing the ABI ownership
35
+ rules.
36
+
37
+ ## Contents
38
+
39
+ 1. [How It Fits](#how-it-fits)
40
+ 2. [Install](#install)
41
+ 3. [Local Development](#local-development)
42
+ 4. [What It Covers](#what-it-covers)
43
+ 5. [Savepoints](#savepoints)
44
+ 6. [Operational Safety](#operational-safety)
45
+ 7. [Objects](#objects)
46
+ 8. [Vectors](#vectors)
47
+ 9. [SQL-Native Vector Search](#sql-native-vector-search)
48
+
49
+ ## How It Fits
50
+
51
+ Python users import `zova`. The extension is built with PyO3 and reuses the
52
+ safe Rust binding, which in turn links Zova's C ABI.
53
+
54
+ ```mermaid
55
+ flowchart LR
56
+ App["Python app"]
57
+ PyPkg["zova Python package"]
58
+ PyO3["PyO3 extension"]
59
+ Rust["Rust zova crate"]
60
+ CABI["libzova_c.a"]
61
+ File["local .zova file"]
62
+
63
+ App --> PyPkg
64
+ PyPkg --> PyO3
65
+ PyO3 --> Rust
66
+ Rust --> CABI
67
+ CABI --> File
68
+ ```
69
+
70
+ ## Install
71
+
72
+ After the Python package is published to PyPI:
73
+
74
+ ```sh
75
+ python -m pip install zova
76
+ ```
77
+
78
+ The v0.17 Python package is source-first. It builds the PyO3 extension locally
79
+ through maturin and Cargo, and the Rust crates `zova` and `zova-sys` must be
80
+ available on crates.io first. Users need Python 3.10 or newer, Rust/Cargo, Zig
81
+ 0.16.0 or newer, and a working C compiler/linker.
82
+
83
+ No official platform wheel matrix is promised in v0.17.
84
+
85
+ ## Local Development
86
+
87
+ From `bindings/python`:
88
+
89
+ ```sh
90
+ uv run --isolated --with maturin --with pytest maturin develop
91
+ uv run --isolated --with pytest python -m pytest
92
+ ```
93
+
94
+ The native build uses maturin, Cargo, Zig, and the Rust `zova` crate. Users do
95
+ not need to locate a shared C library manually.
96
+
97
+ The Python API is pre-1.0 and may still change alongside the Rust binding.
98
+
99
+ ## What It Covers
100
+
101
+ The Python package exposes database lifecycle, conversion, prepared SQL
102
+ statements, transactions, explicit vacuum, backup/compact/restore, objects,
103
+ streaming object writes, vectors, SQL-native vector search, context managers,
104
+ and Zova status exceptions.
105
+
106
+ One Python `Database` object owns one native handle. The native C ABI serializes
107
+ calls on that handle, so one handle is safe but not parallel. Open additional
108
+ database handles when an application needs independent concurrent connections;
109
+ SQLite locking rules still apply across handles. PyO3 classes remain unsendable
110
+ in this release even though the native C ABI serializes its own calls.
111
+
112
+ Use `Database.open(path, read_only=True)` for read-only handles, and
113
+ `Database.set_busy_timeout(milliseconds)` when an application wants SQLite to
114
+ wait briefly on cross-handle contention. No nonzero timeout is installed by
115
+ default.
116
+
117
+ Use `Database.last_insert_rowid()`, `Database.changes()`,
118
+ `Database.total_changes()`, and `Statement.column_name(index)` for normal
119
+ application SQL record helpers. They do not expose or stabilize Zova's private
120
+ `_zova_*` tables.
121
+
122
+ ## Savepoints
123
+
124
+ Use explicit savepoints for partial rollback inside one database connection:
125
+
126
+ ```python
127
+ with zova.Database.open("app.zova") as db:
128
+ db.begin_immediate()
129
+ db.savepoint("attach_file")
130
+ db.exec("insert into attachments(filename) values ('draft.txt')")
131
+ db.rollback_to_savepoint("attach_file")
132
+ db.release_savepoint("attach_file")
133
+ db.commit()
134
+ ```
135
+
136
+ Savepoint names are strict ASCII identifiers: 1-64 bytes, first byte
137
+ `[A-Za-z_]`, remaining bytes `[A-Za-z0-9_]`, and no case-insensitive `_zova_`
138
+ prefix. `rollback_to_savepoint()` keeps the savepoint active;
139
+ `release_savepoint()` removes it.
140
+ An inner released savepoint can still be undone by rolling back an outer
141
+ transaction or savepoint.
142
+
143
+ Use `savepoint_context()` when you want rollback cleanup tied to a `with` block:
144
+
145
+ ```python
146
+ with db.savepoint_context("attach_file") as scoped_db:
147
+ scoped_db.exec("insert into attachments(filename) values ('draft.txt')")
148
+ ```
149
+
150
+ On normal exit the context releases the savepoint. On exception it rolls back,
151
+ releases, and then re-raises the original exception when cleanup succeeds.
152
+
153
+ ## Operational Safety
154
+
155
+ Use `backup_to()` for a faithful snapshot, `compact_to()` for a
156
+ space-reclaiming copy, and `restore_backup()` to copy a backup into a new
157
+ destination file. Destinations must be `.zova` paths and are never overwritten.
158
+
159
+ ```python
160
+ with zova.Database.open("app.zova") as db:
161
+ db.backup_to("app.backup.zova")
162
+ db.compact_to("app.compact.zova")
163
+
164
+ zova.restore_backup("app.backup.zova", "app.restored.zova")
165
+ ```
166
+
167
+ By default, each operation verifies the destination after copying. Pass
168
+ `verify=False` only when you will verify separately, for example with
169
+ `zova check --deep`.
170
+
171
+ Diagnostic recovery commands such as `zova doctor`, `zova salvage --dry-run`,
172
+ and `zova salvage <source> <destination>` are CLI-first in the v0.16 line. The
173
+ Python package does not expose typed doctor/salvage report APIs yet, and library
174
+ code should not parse the human text output as a stable binding contract.
175
+
176
+ ## Objects
177
+
178
+ The Python binding exposes Zova objects as content-addressed byte values while
179
+ keeping application metadata in normal SQL tables.
180
+
181
+ ```python
182
+ import zova
183
+
184
+ with zova.Database.create("app.zova") as db:
185
+ db.exec(
186
+ "create table attachments("
187
+ "id integer primary key, "
188
+ "filename text not null, "
189
+ "object_id blob not null)"
190
+ )
191
+
192
+ object_id = db.put_object(b"hello from Zova")
193
+
194
+ with db.prepare("insert into attachments(filename, object_id) values (?1, ?2)") as stmt:
195
+ stmt.bind_text(1, "hello.txt")
196
+ stmt.bind_blob(2, bytes(object_id))
197
+ stmt.step()
198
+
199
+ assert db.read_object_range(object_id, 0, 5) == b"hello"
200
+ ```
201
+
202
+ For large inputs, use `ObjectWriter` so the full object does not have to be held
203
+ in memory by the caller:
204
+
205
+ ```python
206
+ with db.object_writer() as writer:
207
+ writer.write(b"chunk one")
208
+ writer.write(b"chunk two")
209
+ object_id = writer.finish()
210
+ ```
211
+
212
+ If a writer leaves the context without `finish()`, it is cancelled and any
213
+ unreferenced chunks written by that writer are cleaned up. Writer operations
214
+ follow Zova's object transaction policy and reject active user transactions.
215
+
216
+ Loose chunks and assembly are also exposed for receive-side workflows:
217
+ applications track transfer state in their own SQL tables, call
218
+ `put_object_chunk()` for verified chunks, then call
219
+ `assemble_object_from_chunks()` when the manifest is complete.
220
+
221
+ ## Vectors
222
+
223
+ The Python binding exposes Zova vectors with the same model as the Rust binding:
224
+ Zova stores numeric vectors in named collections, while application metadata
225
+ stays in normal SQL tables.
226
+
227
+ ```python
228
+ import zova
229
+
230
+ with zova.Database.create("vectors.zova") as db:
231
+ db.exec(
232
+ "create table chunks("
233
+ "id text primary key, "
234
+ "document_id text not null, "
235
+ "text text not null, "
236
+ "vector_id text not null)"
237
+ )
238
+
239
+ db.create_vector_collection(
240
+ "chunks",
241
+ zova.VectorCollectionOptions(2, zova.VectorMetric.L2),
242
+ )
243
+ db.put_vectors(
244
+ "chunks",
245
+ [
246
+ zova.VectorInput("chunk:1", [0.0, 0.0]),
247
+ zova.VectorInput("chunk:2", [1.0, 0.0]),
248
+ ],
249
+ )
250
+
251
+ db.exec(
252
+ "insert into chunks(id, document_id, text, vector_id) values "
253
+ "('c1', 'doc-a', 'first chunk', 'chunk:1'), "
254
+ "('c2', 'doc-a', 'near chunk', 'chunk:2')"
255
+ )
256
+
257
+ results = db.search_vectors_in(
258
+ "chunks",
259
+ [0.0, 0.0],
260
+ ["chunk:1", "chunk:2"],
261
+ 2,
262
+ )
263
+ for result in results:
264
+ with db.prepare("select text from chunks where vector_id = ?1") as stmt:
265
+ stmt.bind_text(1, result.id)
266
+ stmt.step()
267
+ print(result.id, result.distance, stmt.column_text(0))
268
+ ```
269
+
270
+ Search is exact and lower distance is better. Candidate-filtered searches skip
271
+ missing ids and deduplicate duplicate candidates. Search-by-id excludes the
272
+ source vector. Threshold variants are inclusive, and dot-product thresholds may
273
+ be negative because dot distance is `-dot_product`.
274
+
275
+ Deleting a vector collection removes Zova's private vector rows only. User SQL
276
+ metadata rows that reference vector ids are application-owned and remain in
277
+ place.
278
+
279
+ ## SQL-Native Vector Search
280
+
281
+ Zova registers SQL vector functions and the `zova_vector_search` virtual table
282
+ on Zova database connections. Bind query vectors as little-endian `f32` blobs
283
+ with `encode_f32_le()`:
284
+
285
+ ```python
286
+ query = zova.encode_f32_le([0.0, 0.0])
287
+
288
+ with db.prepare(
289
+ "select c.id, zova_vector_distance('chunks', c.vector_id, ?1) as distance "
290
+ "from chunks as c "
291
+ "where c.document_id = 'doc-a' "
292
+ "order by distance "
293
+ "limit 10"
294
+ ) as stmt:
295
+ stmt.bind_blob(1, query)
296
+ ```
297
+
298
+ Row-to-row distances use `zova_vector_distance_by_id(collection, vector_id,
299
+ source_vector_id)`. Collection-wide SQL search uses `zova_vector_search`:
300
+
301
+ ```python
302
+ with db.prepare(
303
+ "select c.text, s.distance "
304
+ "from zova_vector_search as s "
305
+ "join chunks as c on c.vector_id = s.vector_id "
306
+ "where s.collection = 'chunks' "
307
+ "and s.query_vector = ?1 "
308
+ "and s.top_k = 10 "
309
+ "order by s.rank"
310
+ ) as stmt:
311
+ stmt.bind_blob(1, query)
312
+ ```
313
+
314
+ Python's built-in `sqlite3` module opens an ordinary SQLite connection and does
315
+ not automatically register Zova's SQL functions or virtual table. Use
316
+ `zova.Database` for SQL-native vector search in this binding. A future SQLite
317
+ loadable extension may make the SQL surface available to external SQLite
318
+ connections.
319
+