dirsql 0.3.82__cp311-abi3-win_amd64.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.
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: dirsql
3
+ Version: 0.3.82
4
+ Summary: Ephemeral SQL index over a local directory
5
+ Keywords: sql,filesystem,directory,sqlite,index
6
+ Author: Kevin Scott
7
+ License-Expression: MIT
8
+ Requires-Python: >=3.11
9
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
10
+
11
+ # `dirsql` (Python SDK)
12
+
13
+ Ephemeral SQL index over a local directory. `dirsql` watches a filesystem, ingests structured files into an in-memory SQLite database, and exposes a SQL query interface -- the filesystem is always the source of truth.
14
+
15
+ [Documentation](https://thekevinscott.github.io/dirsql/?lang=python)
16
+
17
+ Also available as [`dirsql` on crates.io](https://crates.io/crates/dirsql) and [`dirsql` on npm](https://www.npmjs.com/package/dirsql).
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pip install dirsql
23
+ ```
24
+
25
+ Requires Python >= 3.12. Ships as a native extension (Rust via PyO3); prebuilt binary wheels are provided for common platforms.
26
+
27
+ ## Quick start
28
+
29
+ `DirSQL` is async by default: the constructor returns immediately, scanning runs in a background thread, and you `await db.ready()` before querying. Each table is a `(ddl, glob, extract)` triple: the DDL defines the SQLite schema, the glob selects files (relative to the root), and `extract` turns a matched file into a list of row dicts. `dirsql` does not read file contents -- if `extract` needs the file body it reads `path` itself; return an empty list to skip a file.
30
+
31
+ ```python
32
+ import asyncio
33
+ import json
34
+ from dirsql import DirSQL, Table
35
+
36
+ async def main():
37
+ db = DirSQL(
38
+ "./my-blog",
39
+ tables=[
40
+ Table(
41
+ ddl="CREATE TABLE posts (title TEXT, author TEXT)",
42
+ glob="posts/*.json",
43
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
44
+ ),
45
+ ],
46
+ )
47
+ await db.ready()
48
+
49
+ posts = await db.query("SELECT * FROM posts WHERE author = 'alice'")
50
+ print(posts)
51
+
52
+ asyncio.run(main())
53
+ ```
54
+
55
+ ## Multiple tables and joins
56
+
57
+ ```python
58
+ db = DirSQL(
59
+ "./my-blog",
60
+ tables=[
61
+ Table(
62
+ ddl="CREATE TABLE posts (title TEXT, author_id TEXT)",
63
+ glob="posts/*.json",
64
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
65
+ ),
66
+ Table(
67
+ ddl="CREATE TABLE authors (id TEXT, name TEXT)",
68
+ glob="authors/*.json",
69
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
70
+ ),
71
+ ],
72
+ )
73
+ await db.ready()
74
+
75
+ results = await db.query("""
76
+ SELECT posts.title, authors.name
77
+ FROM posts JOIN authors ON posts.author_id = authors.id
78
+ """)
79
+ ```
80
+
81
+ ## Ignoring files
82
+
83
+ Pass `ignore` patterns to skip files during scanning and watching:
84
+
85
+ ```python
86
+ db = DirSQL(
87
+ "./my-blog",
88
+ ignore=["**/drafts/**", "**/.git/**"],
89
+ tables=[...],
90
+ )
91
+ ```
92
+
93
+ ## Loading SQLite extensions
94
+
95
+ Pass `extensions` to load SQLite extension shared libraries onto the connection at startup (before any `CREATE TABLE`). Each entry is a dict with a `path` and an optional `entrypoint` init-symbol override:
96
+
97
+ ```python
98
+ db = DirSQL(
99
+ "./my-blog",
100
+ tables=[...],
101
+ extensions=[
102
+ {"path": "./ext/vec0.dylib", "entrypoint": "sqlite3_vec_init"},
103
+ {"path": "./ext/myext.so"}, # entrypoint derived from the filename
104
+ ],
105
+ )
106
+ await db.ready()
107
+
108
+ # The extension's functions are now callable in queries:
109
+ rows = await db.query("SELECT vec_version() AS v")
110
+ ```
111
+
112
+ `dirsql` enables extension loading only while loading the configured libraries, then disables it again, so the SQL `load_extension()` function is never exposed to your queries. Programmatic entries load first, followed by any `[[dirsql.extension]]` entries declared in a `config` file. See the [config reference](https://github.com/thekevinscott/dirsql/blob/main/docs/reference/config.md#dirsqlextension).
113
+
114
+ ## Watching for changes
115
+
116
+ `db.watch()` returns an async iterator of row-level change events as files change on disk:
117
+
118
+ ```python
119
+ async for event in db.watch():
120
+ print(f"{event.action} on {event.table}: {event.row}")
121
+ if event.action == "error":
122
+ print(f" error: {event.error}")
123
+ ```
124
+
125
+ Each event has `.action` (`"insert"`, `"update"`, `"delete"`, or `"error"`), `.table`, `.row` (the new row, or the deleted row on `delete`), `.old_row` (the previous row, on `update`), `.file_path`, and `.error` (on `error`).
126
+
127
+ ## CLI
128
+
129
+ `pip install dirsql` also installs a `dirsql` console script that runs an HTTP server exposing the SDK over HTTP: `POST /query` for SQL and `GET /events` for a Server-Sent Events change stream. Run `dirsql` (or `uvx dirsql`) to start it. See the [CLI reference](https://thekevinscott.github.io/dirsql/reference/cli).
130
+
131
+ ## License
132
+
133
+ MIT
134
+
@@ -0,0 +1,18 @@
1
+ dirsql/__init__.py,sha256=R4O-oQ4SvQQJqoBEeovbAGMu82hBii_FVlCvLTxXQHc,300
2
+ dirsql/_async.py,sha256=upENiNP85rHIijjtrLg5EazKbs1hTYO-mbfNEIisWOU,6674
3
+ dirsql/_binary/dirsql.exe,sha256=FW4s46VeeTExjnWbB7fxqu7sq3TVrNll2Rem227fHqA,6820864
4
+ dirsql/_dirsql.pyd,sha256=03Sm1-JhYjG7syRMm_nXanY1z6JgR-cbF87PLrpYzr4,4998656
5
+ dirsql/_dirsql.pyi,sha256=IktVp22ELjIwFLtiCmQyhSAYLhxzQQJPCoe2-FLCtFA,2198
6
+ dirsql/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ dirsql/cli/binary_path.py,sha256=Sd_dYCmifwlWqSgziVlMYd905b6PyydANewgkmvom7g,729
8
+ dirsql/cli/is_windows.py,sha256=SixXdOcdeRmvuSClwRtctyv2wF-xoCnLLscmZZygZEs,154
9
+ dirsql/cli/main.py,sha256=TxbEJNl5qfO8gNJCvjFH-BZ7RBNdZZSzu4RXi1fgKbw,1113
10
+ dirsql/cli/resolve_config_extensions.py,sha256=MyjTWGBtPqn8MFZWe5pUWLMvrEfcORDohfWRPF-thNM,2363
11
+ dirsql/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ dirsql/resolve_config_extensions.py,sha256=VK6Qjnh-_jqAmH-5FzJQ7FQ6HaNU0zXQVZSarWAeA3M,2558
13
+ dirsql/resolve_extension.py,sha256=uj2nZfhOW5CKH_PhgCqDmEBSPGhXPYjkpi8wiy9Wbyc,3809
14
+ dirsql-0.3.82.dist-info/METADATA,sha256=nhD_2SzITfY2ipnSM6xnSqoOfl0JiXTchOuwIxy0pl0,4785
15
+ dirsql-0.3.82.dist-info/WHEEL,sha256=nv5WBZ27cxxDjIIqxBMqK2cOF025DwkFmqJGqL3SpXU,96
16
+ dirsql-0.3.82.dist-info/entry_points.txt,sha256=tudtE91DSGc4rRXqbZurACS8VizzUBfhdQL63Ta0LbI,46
17
+ dirsql-0.3.82.dist-info/sboms/dirsql-py-ext.cyclonedx.json,sha256=vNjaII3tK4WzwHKTfv68NtR5IV2X0JvDdzy8pY4gH14,93903
18
+ dirsql-0.3.82.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.14.1)
3
+ Root-Is-Purelib: false
4
+ Tag: cp311-abi3-win_amd64
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dirsql=dirsql.cli.main:main