shelfdb 1.1.1__tar.gz → 2.0.0.dev0__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.
- shelfdb-2.0.0.dev0/PKG-INFO +120 -0
- shelfdb-2.0.0.dev0/README.md +98 -0
- shelfdb-2.0.0.dev0/pyproject.toml +46 -0
- {shelfdb-1.1.1 → shelfdb-2.0.0.dev0/src}/shelfdb/__init__.py +2 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/__init__.py +1 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/SKILL.md +90 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/agents/openai.yaml +4 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/api-reference.md +74 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/embedded-mode.md +155 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/getting-started.md +118 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/index.md +93 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/protocol.md +136 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/query-model.md +188 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/security.md +37 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/server-mode.md +181 -0
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/transactions.md +120 -0
- shelfdb-2.0.0.dev0/src/shelfdb/cli.py +122 -0
- shelfdb-2.0.0.dev0/src/shelfdb/client/__init__.py +38 -0
- shelfdb-2.0.0.dev0/src/shelfdb/client/_impl.py +409 -0
- shelfdb-2.0.0.dev0/src/shelfdb/log.py +36 -0
- shelfdb-2.0.0.dev0/src/shelfdb/protocol/__init__.py +27 -0
- shelfdb-2.0.0.dev0/src/shelfdb/protocol/codec.py +32 -0
- shelfdb-2.0.0.dev0/src/shelfdb/protocol/payload.py +129 -0
- shelfdb-2.0.0.dev0/src/shelfdb/protocol/query.py +22 -0
- shelfdb-2.0.0.dev0/src/shelfdb/protocol/schema.py +70 -0
- shelfdb-2.0.0.dev0/src/shelfdb/server/__init__.py +10 -0
- shelfdb-2.0.0.dev0/src/shelfdb/server/rpc.py +35 -0
- shelfdb-2.0.0.dev0/src/shelfdb/server/runtime.py +144 -0
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/__init__.py +18 -0
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/core.py +349 -0
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/normalize.py +26 -0
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/query.py +76 -0
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/storage/__init__.py +1 -0
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/storage/lmdb.py +150 -0
- shelfdb-2.0.0.dev0/src/shelfdb/util/__init__.py +1 -0
- shelfdb-2.0.0.dev0/src/shelfdb/util/transport.py +31 -0
- shelfdb-2.0.0.dev0/src/shelfdb/util/validation.py +45 -0
- shelfdb-1.1.1/MANIFEST.in +0 -2
- shelfdb-1.1.1/PKG-INFO +0 -85
- shelfdb-1.1.1/README.md +0 -70
- shelfdb-1.1.1/pyproject.toml +0 -6
- shelfdb-1.1.1/setup.cfg +0 -32
- shelfdb-1.1.1/shelfdb/server.py +0 -189
- shelfdb-1.1.1/shelfdb/shelf.py +0 -282
- shelfdb-1.1.1/shelfdb/test_server.py +0 -132
- shelfdb-1.1.1/shelfdb/test_shelf.py +0 -249
- shelfdb-1.1.1/shelfdb.egg-info/PKG-INFO +0 -85
- shelfdb-1.1.1/shelfdb.egg-info/SOURCES.txt +0 -16
- shelfdb-1.1.1/shelfdb.egg-info/dependency_links.txt +0 -1
- shelfdb-1.1.1/shelfdb.egg-info/entry_points.txt +0 -2
- shelfdb-1.1.1/shelfdb.egg-info/requires.txt +0 -4
- shelfdb-1.1.1/shelfdb.egg-info/top_level.txt +0 -1
- {shelfdb-1.1.1 → shelfdb-2.0.0.dev0}/LICENSE +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: shelfdb
|
|
3
|
+
Version: 2.0.0.dev0
|
|
4
|
+
Summary: A tiny documents database for Python
|
|
5
|
+
Keywords: dict,json,database
|
|
6
|
+
Author: Nitipit Nontasuwan
|
|
7
|
+
Author-email: Nitipit Nontasuwan <nitipit@gmail.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Dist: cyclopts>=4.10.2
|
|
14
|
+
Requires-Dist: dictify>=4.0.0,<4.1
|
|
15
|
+
Requires-Dist: dill>=0.4.0,<0.5
|
|
16
|
+
Requires-Dist: lmdb>=1.7.3,<2
|
|
17
|
+
Requires-Dist: msgpack>=1.1.2,<2
|
|
18
|
+
Requires-Dist: structlog>=25.1.0,<26
|
|
19
|
+
Requires-Dist: uvloop>=0.22.0,<0.23 ; sys_platform == 'linux'
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# ShelfDB
|
|
24
|
+
|
|
25
|
+
ShelfDB is a tiny document database for Python that stores JSON-like dictionaries in LMDB.
|
|
26
|
+
|
|
27
|
+
Docs: build and browse the MkDocs site from `docs-src/`.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```shell
|
|
32
|
+
pip install shelfdb
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Develop
|
|
36
|
+
|
|
37
|
+
```shell
|
|
38
|
+
uv sync --dev
|
|
39
|
+
uv run pytest
|
|
40
|
+
uv build
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Local API
|
|
44
|
+
|
|
45
|
+
Local queries are lazy. Build a query chain and call `.run()` to execute it.
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from datetime import datetime
|
|
49
|
+
|
|
50
|
+
import shelfdb
|
|
51
|
+
|
|
52
|
+
db = shelfdb.open("db")
|
|
53
|
+
|
|
54
|
+
db.shelf("note").put(
|
|
55
|
+
"note-1",
|
|
56
|
+
{
|
|
57
|
+
"title": "Shelf DB",
|
|
58
|
+
"content": "Simple note",
|
|
59
|
+
"created_at": datetime.utcnow().isoformat(),
|
|
60
|
+
},
|
|
61
|
+
).run()
|
|
62
|
+
|
|
63
|
+
notes = (
|
|
64
|
+
db.shelf("note")
|
|
65
|
+
.filter(lambda item: item[1]["title"] == "Shelf DB")
|
|
66
|
+
.run()
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
print(sorted(notes, key=lambda item: item[1]["created_at"]))
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`run()` returns a one-shot iterator for local multi-item queries. Each item has the server-style
|
|
73
|
+
shape `["key", data]`, so use `item[0]` for the key and `item[1]` for the stored document.
|
|
74
|
+
|
|
75
|
+
## Server
|
|
76
|
+
|
|
77
|
+
Start the asyncio server:
|
|
78
|
+
|
|
79
|
+
```shell
|
|
80
|
+
shelfdb
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Or choose an explicit transport:
|
|
84
|
+
|
|
85
|
+
```shell
|
|
86
|
+
shelfdb --url tcp://127.0.0.1:17000
|
|
87
|
+
shelfdb --url unix:///tmp/shelfdb.sock
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Control server logging with stdlib-integrated structlog:
|
|
91
|
+
|
|
92
|
+
```shell
|
|
93
|
+
shelfdb --log-level info
|
|
94
|
+
shelfdb --log-level debug
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If you use the Python client directly, call `shelfdb.log.configure_logging(...)` first to
|
|
98
|
+
see client-side debug logs as well.
|
|
99
|
+
|
|
100
|
+
## Network Client
|
|
101
|
+
|
|
102
|
+
RPC queries are also lazy and execute on `.run()`.
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
import shelfdb
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def main():
|
|
109
|
+
db = shelfdb.connect("tcp://127.0.0.1:17000")
|
|
110
|
+
note = db.shelf("note").key("note-1").first().run()
|
|
111
|
+
print(note)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
main()
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Security
|
|
118
|
+
|
|
119
|
+
The RPC protocol uses Python object deserialization and can transport Python callables.
|
|
120
|
+
Only use the server with trusted local clients.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# ShelfDB
|
|
2
|
+
|
|
3
|
+
ShelfDB is a tiny document database for Python that stores JSON-like dictionaries in LMDB.
|
|
4
|
+
|
|
5
|
+
Docs: build and browse the MkDocs site from `docs-src/`.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```shell
|
|
10
|
+
pip install shelfdb
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Develop
|
|
14
|
+
|
|
15
|
+
```shell
|
|
16
|
+
uv sync --dev
|
|
17
|
+
uv run pytest
|
|
18
|
+
uv build
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Local API
|
|
22
|
+
|
|
23
|
+
Local queries are lazy. Build a query chain and call `.run()` to execute it.
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from datetime import datetime
|
|
27
|
+
|
|
28
|
+
import shelfdb
|
|
29
|
+
|
|
30
|
+
db = shelfdb.open("db")
|
|
31
|
+
|
|
32
|
+
db.shelf("note").put(
|
|
33
|
+
"note-1",
|
|
34
|
+
{
|
|
35
|
+
"title": "Shelf DB",
|
|
36
|
+
"content": "Simple note",
|
|
37
|
+
"created_at": datetime.utcnow().isoformat(),
|
|
38
|
+
},
|
|
39
|
+
).run()
|
|
40
|
+
|
|
41
|
+
notes = (
|
|
42
|
+
db.shelf("note")
|
|
43
|
+
.filter(lambda item: item[1]["title"] == "Shelf DB")
|
|
44
|
+
.run()
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
print(sorted(notes, key=lambda item: item[1]["created_at"]))
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`run()` returns a one-shot iterator for local multi-item queries. Each item has the server-style
|
|
51
|
+
shape `["key", data]`, so use `item[0]` for the key and `item[1]` for the stored document.
|
|
52
|
+
|
|
53
|
+
## Server
|
|
54
|
+
|
|
55
|
+
Start the asyncio server:
|
|
56
|
+
|
|
57
|
+
```shell
|
|
58
|
+
shelfdb
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or choose an explicit transport:
|
|
62
|
+
|
|
63
|
+
```shell
|
|
64
|
+
shelfdb --url tcp://127.0.0.1:17000
|
|
65
|
+
shelfdb --url unix:///tmp/shelfdb.sock
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Control server logging with stdlib-integrated structlog:
|
|
69
|
+
|
|
70
|
+
```shell
|
|
71
|
+
shelfdb --log-level info
|
|
72
|
+
shelfdb --log-level debug
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
If you use the Python client directly, call `shelfdb.log.configure_logging(...)` first to
|
|
76
|
+
see client-side debug logs as well.
|
|
77
|
+
|
|
78
|
+
## Network Client
|
|
79
|
+
|
|
80
|
+
RPC queries are also lazy and execute on `.run()`.
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
import shelfdb
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def main():
|
|
87
|
+
db = shelfdb.connect("tcp://127.0.0.1:17000")
|
|
88
|
+
note = db.shelf("note").key("note-1").first().run()
|
|
89
|
+
print(note)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
main()
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Security
|
|
96
|
+
|
|
97
|
+
The RPC protocol uses Python object deserialization and can transport Python callables.
|
|
98
|
+
Only use the server with trusted local clients.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.11.3,<0.12"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "shelfdb"
|
|
7
|
+
version = "2.0.0.dev0"
|
|
8
|
+
description = "A tiny documents database for Python"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Nitipit Nontasuwan", email = "nitipit@gmail.com" },
|
|
15
|
+
]
|
|
16
|
+
keywords = ["dict", "json", "database"]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
]
|
|
22
|
+
dependencies = [
|
|
23
|
+
"cyclopts>=4.10.2",
|
|
24
|
+
"dictify>=4.0.0,<4.1",
|
|
25
|
+
"dill>=0.4.0,<0.5",
|
|
26
|
+
"lmdb>=1.7.3,<2",
|
|
27
|
+
"msgpack>=1.1.2,<2",
|
|
28
|
+
"structlog>=25.1.0,<26",
|
|
29
|
+
"uvloop>=0.22.0,<0.23; platform_system == 'Linux'",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
shelfdb = "shelfdb.cli:main"
|
|
34
|
+
|
|
35
|
+
[dependency-groups]
|
|
36
|
+
dev = [
|
|
37
|
+
"dictify>=4.0.0,<4.1",
|
|
38
|
+
"mkdocs>=1.6.1,<2",
|
|
39
|
+
"mkdocs-shadcn>=0.10.4,<0.11",
|
|
40
|
+
"mkdocstrings[python]>=0.29.0,<0.30",
|
|
41
|
+
"pytest>=8.4.2,<9",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[tool.uv.build-backend]
|
|
45
|
+
module-name = "shelfdb"
|
|
46
|
+
module-root = "src"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""ShelfDB bundled AI skills."""
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shelfdb-usage
|
|
3
|
+
description: "ShelfDB developer workflow for running the local server and querying it from sync or async Python clients. Use when Codex needs to write or debug ShelfDB server-mode code, client queries, transactions, logging, or examples that call `shelfdb.connect`, `connect_async`, `.run()`, or `tx.commit()`."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ShelfDB usage
|
|
7
|
+
|
|
8
|
+
Prefer the simplest mode that fits the task.
|
|
9
|
+
|
|
10
|
+
## Reference docs
|
|
11
|
+
|
|
12
|
+
- Read `references/docs/` for mirrored ShelfDB documentation when you need the full narrative docs.
|
|
13
|
+
- Prefer the most specific page for the task: `server-mode.md`, `query-model.md`, `transactions.md`, and `security.md` are the usual first reads.
|
|
14
|
+
|
|
15
|
+
## Choose the mode
|
|
16
|
+
|
|
17
|
+
- Use embedded mode with `shelfdb.open(...)` when the process can access the LMDB directory directly.
|
|
18
|
+
- Use server mode only when a separate process or multi-client access is required.
|
|
19
|
+
|
|
20
|
+
## Start the server
|
|
21
|
+
|
|
22
|
+
- Run `shelfdb` for the default TCP server on `127.0.0.1:17000` with the `db/` directory.
|
|
23
|
+
- Use `shelfdb --url tcp://HOST:PORT` or `shelfdb --url unix:///path/to/socket.sock` when an explicit transport is needed.
|
|
24
|
+
- Keep the server on loopback or a Unix socket. Treat the RPC layer as trusted-local only.
|
|
25
|
+
|
|
26
|
+
## Connect from Python
|
|
27
|
+
|
|
28
|
+
- Use `shelfdb.connect(url)` in sync code.
|
|
29
|
+
- Use `await shelfdb.connect_async(url)` in async code.
|
|
30
|
+
- Await only `connect_async(...)`, `query.run()` in async code, and `tx.commit()`.
|
|
31
|
+
|
|
32
|
+
## Build queries lazily
|
|
33
|
+
|
|
34
|
+
- Chain query methods and execute only with `.run()`.
|
|
35
|
+
- Reuse the same query object when you need to run the same pipeline again.
|
|
36
|
+
- Use the same query style in embedded and remote code.
|
|
37
|
+
|
|
38
|
+
Available operations:
|
|
39
|
+
|
|
40
|
+
- Read: `key`, `key_range`, `keys_in`, `filter`, `slice`, `first`, `count`
|
|
41
|
+
- Write: `put`, `put_many`, `update`, `replace`, `edit`, `delete`
|
|
42
|
+
|
|
43
|
+
## Handle results correctly
|
|
44
|
+
|
|
45
|
+
- Local multi-item `.run()` returns a one-shot iterator of `['key', data]` items; wrap it in `list(...)` if you need reuse.
|
|
46
|
+
- Remote results are normalized into plain Python values.
|
|
47
|
+
- `first()` returns one item or `None`.
|
|
48
|
+
- `put_many()` returns `None`.
|
|
49
|
+
|
|
50
|
+
## Respect batch and transaction behavior
|
|
51
|
+
|
|
52
|
+
- Pass iterables to `put_many()` and `keys_in()`, but assume the client materializes them before send.
|
|
53
|
+
- `keys_in()` keeps the requested key order and may repeat keys.
|
|
54
|
+
- Use `client.transaction(write=True)` for remote batches; queue queries with `.run()` and send them with `tx.commit()`.
|
|
55
|
+
- Use `db.transaction(write=True)` for embedded atomic writes; inside a local transaction, use `tx.shelf(...)`, not `db.shelf(...)`.
|
|
56
|
+
|
|
57
|
+
## Safety checks
|
|
58
|
+
|
|
59
|
+
- Keep callable `filter()` and `edit()` functions simple and trusted; the protocol uses `dill`.
|
|
60
|
+
- Configure debug logs with `shelfdb.log.configure_logging("debug")` when diagnosing client or server behavior.
|
|
61
|
+
- Do not expose the server to untrusted networks.
|
|
62
|
+
|
|
63
|
+
## Minimal patterns
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
import shelfdb
|
|
67
|
+
|
|
68
|
+
client = shelfdb.connect("tcp://127.0.0.1:17000")
|
|
69
|
+
note = client.shelf("note").key("note-1").first().run()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
import asyncio
|
|
74
|
+
import shelfdb
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async def main():
|
|
78
|
+
client = await shelfdb.connect_async("unix:///tmp/shelfdb.sock")
|
|
79
|
+
rows = await client.shelf("note").keys_in(["note-1", "note-2"]).run()
|
|
80
|
+
print(rows)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
asyncio.run(main())
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
tx = client.transaction(write=True)
|
|
88
|
+
tx.shelf("note").put("note-1", {"title": "ShelfDB"}).run()
|
|
89
|
+
tx.commit()
|
|
90
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
This page is the generated reference for the public Python modules.
|
|
4
|
+
|
|
5
|
+
Use the narrative pages first if you are learning ShelfDB. Come back here when you want exact
|
|
6
|
+
signatures, annotations, class members, or module-level details.
|
|
7
|
+
|
|
8
|
+
## Protocol
|
|
9
|
+
|
|
10
|
+
Start with the [Protocol](protocol.md) page for the conceptual overview and module guide.
|
|
11
|
+
|
|
12
|
+
The sections below show the public `shelfdb.protocol` package surface and the protocol submodules.
|
|
13
|
+
|
|
14
|
+
::: shelfdb.protocol
|
|
15
|
+
|
|
16
|
+
### `shelfdb.protocol.schema`
|
|
17
|
+
|
|
18
|
+
Typed protocol shapes and schema models.
|
|
19
|
+
|
|
20
|
+
::: shelfdb.protocol.schema
|
|
21
|
+
|
|
22
|
+
### `shelfdb.protocol.query`
|
|
23
|
+
|
|
24
|
+
Serialized query-step builders.
|
|
25
|
+
|
|
26
|
+
::: shelfdb.protocol.query
|
|
27
|
+
|
|
28
|
+
### `shelfdb.protocol.payload`
|
|
29
|
+
|
|
30
|
+
Request and response payload helpers.
|
|
31
|
+
|
|
32
|
+
::: shelfdb.protocol.payload
|
|
33
|
+
|
|
34
|
+
### `shelfdb.protocol.codec`
|
|
35
|
+
|
|
36
|
+
Byte-level request and response codecs.
|
|
37
|
+
|
|
38
|
+
::: shelfdb.protocol.codec
|
|
39
|
+
|
|
40
|
+
## Package
|
|
41
|
+
|
|
42
|
+
Top-level package exports such as `open()`, `connect()`, and `connect_async()`.
|
|
43
|
+
|
|
44
|
+
::: shelfdb
|
|
45
|
+
|
|
46
|
+
## Local database
|
|
47
|
+
|
|
48
|
+
Local database, query, and result classes.
|
|
49
|
+
|
|
50
|
+
::: shelfdb.shelf
|
|
51
|
+
|
|
52
|
+
## Client
|
|
53
|
+
|
|
54
|
+
Sync and async remote client types.
|
|
55
|
+
|
|
56
|
+
::: shelfdb.client
|
|
57
|
+
|
|
58
|
+
## Server
|
|
59
|
+
|
|
60
|
+
Programmatic server type for running ShelfDB over TCP or a Unix socket.
|
|
61
|
+
|
|
62
|
+
::: shelfdb.server
|
|
63
|
+
|
|
64
|
+
## CLI
|
|
65
|
+
|
|
66
|
+
CLI entry points and server configuration helpers.
|
|
67
|
+
|
|
68
|
+
::: shelfdb.cli
|
|
69
|
+
|
|
70
|
+
## Logging
|
|
71
|
+
|
|
72
|
+
Logging helpers for configuring ShelfDB debug output.
|
|
73
|
+
|
|
74
|
+
::: shelfdb.log
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Embedded Mode
|
|
2
|
+
|
|
3
|
+
Use `shelfdb.open()` when you want ShelfDB as an embedded database inside your Python process.
|
|
4
|
+
|
|
5
|
+
This is the default way to use the project: your Python process talks directly to LMDB and no
|
|
6
|
+
separate server is required.
|
|
7
|
+
|
|
8
|
+
## Open a database
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
import shelfdb
|
|
12
|
+
|
|
13
|
+
db = shelfdb.open("db")
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`db` is a `shelfdb.DB` object.
|
|
17
|
+
|
|
18
|
+
## Choose a shelf
|
|
19
|
+
|
|
20
|
+
A shelf is a named collection of keyed documents.
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
notes = db.shelf("note")
|
|
24
|
+
users = db.shelf("user")
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Each shelf name is independent, so you can organize documents by purpose.
|
|
28
|
+
|
|
29
|
+
## Read data
|
|
30
|
+
|
|
31
|
+
Read everything in a shelf:
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
all_notes = db.shelf("note").run()
|
|
35
|
+
print(list(all_notes))
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Read one item by key:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
note = db.shelf("note").key("note-1").first().run()
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Filter matching items:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
matching = list(db.shelf("note").filter(lambda item: item[1]["title"] == "updated").run())
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Range and slice:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
selected = list(
|
|
54
|
+
db.shelf("note")
|
|
55
|
+
.key_range("note-1", "note-5")
|
|
56
|
+
.slice(0, 5)
|
|
57
|
+
.run()
|
|
58
|
+
)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Fetch exact keys:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
picked = list(db.shelf("note").keys_in(["note-1", "note-3"]).run())
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If you need custom ordering, sort the returned Python values yourself after `.run()`.
|
|
68
|
+
|
|
69
|
+
Count matches:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
count = db.shelf("note").count().run()
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Write data
|
|
76
|
+
|
|
77
|
+
Insert or replace one document:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
db.shelf("note").put("note-1", {"title": "hello"}).run()
|
|
81
|
+
db.shelf("note").put("note-1", {"title": "updated"}).run()
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Write many documents:
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
db.shelf("note").put_many(
|
|
88
|
+
[
|
|
89
|
+
("note-1", {"title": "hello"}),
|
|
90
|
+
("note-2", {"title": "world"}),
|
|
91
|
+
]
|
|
92
|
+
).run()
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Merge fields into existing documents:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
db.shelf("note").key("note-1").update({"views": 1}).run()
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Replace a full document:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
db.shelf("note").key("note-1").replace({"title": "replaced"}).run()
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Transform with a function:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
db.shelf("note").key("note-1").edit(
|
|
111
|
+
lambda item: {"title": item[1]["title"], "status": "published"}
|
|
112
|
+
).run()
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Delete matching items:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
db.shelf("note").key("note-1").delete().run()
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`update()`, `replace()`, and `edit()` require an existing selection. If nothing matches, they
|
|
122
|
+
raise an error instead of silently creating a new document. All write queries run atomically by
|
|
123
|
+
default, even outside `db.transaction(write=True)`; use an explicit write transaction when you
|
|
124
|
+
need multiple queries to commit together. `delete()` is safe on a missing key and returns an
|
|
125
|
+
empty result. `put_many()` writes multiple documents and returns `None`.
|
|
126
|
+
|
|
127
|
+
Embedded multi-item `run()` results are one-shot iterators.
|
|
128
|
+
|
|
129
|
+
## Result types
|
|
130
|
+
|
|
131
|
+
Embedded execution uses these main types:
|
|
132
|
+
|
|
133
|
+
- `shelfdb.DB` for the database
|
|
134
|
+
- `shelfdb.shelf.ShelfQuery` for lazy embedded query builders
|
|
135
|
+
- one-shot iterators from `run()` for executed selections
|
|
136
|
+
|
|
137
|
+
Each yielded item uses the server-style shape `["key", {"title": "example"}]`.
|
|
138
|
+
|
|
139
|
+
## Close the database
|
|
140
|
+
|
|
141
|
+
When you are done with the embedded database:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
db.close()
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Transactions
|
|
148
|
+
|
|
149
|
+
For consistent reads and atomic writes, use `with db.transaction(...) as tx:` and create
|
|
150
|
+
transaction-scoped queries with `tx.shelf(...)`.
|
|
151
|
+
|
|
152
|
+
Inside the block, embedded `.run()` calls execute immediately. Remote client transactions queue
|
|
153
|
+
their steps until `tx.commit()`.
|
|
154
|
+
|
|
155
|
+
See [Transactions](transactions.md) for the full behavior and examples.
|