shelfdb 2.0.0.dev0__tar.gz → 2.1.0rc1__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.1.0rc1/PKG-INFO +84 -0
- shelfdb-2.1.0rc1/README.md +63 -0
- shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/SKILL.md +42 -0
- shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/api/cli.md +56 -0
- shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/api/client.md +217 -0
- shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/api/index.md +14 -0
- shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/api/local.md +157 -0
- shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/index.md +67 -0
- shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/usage/installation.md +35 -0
- shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/usage/local.md +73 -0
- shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/usage/remote.md +176 -0
- shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/usage/server.md +40 -0
- {shelfdb-2.0.0.dev0 → shelfdb-2.1.0rc1}/pyproject.toml +11 -4
- shelfdb-2.1.0rc1/src/shelfdb/__init__.py +0 -0
- shelfdb-2.1.0rc1/src/shelfdb/__main__.py +5 -0
- shelfdb-2.1.0rc1/src/shelfdb/cli.py +96 -0
- shelfdb-2.1.0rc1/src/shelfdb/client/__init__.py +3 -0
- shelfdb-2.1.0rc1/src/shelfdb/client/client.py +225 -0
- shelfdb-2.1.0rc1/src/shelfdb/protocol/__init__.py +35 -0
- shelfdb-2.1.0rc1/src/shelfdb/protocol/demo_poc.py +62 -0
- shelfdb-2.1.0rc1/src/shelfdb/protocol/protocol.py +81 -0
- shelfdb-2.1.0rc1/src/shelfdb/protocol/query_result.py +49 -0
- shelfdb-2.1.0rc1/src/shelfdb/protocol/server.py +75 -0
- shelfdb-2.1.0rc1/src/shelfdb/protocol/session.py +178 -0
- shelfdb-2.1.0rc1/src/shelfdb/shelf/__init__.py +4 -0
- shelfdb-2.1.0rc1/src/shelfdb/shelf/db.py +217 -0
- shelfdb-2.1.0rc1/src/shelfdb/shelf/shelf/__init__.py +4 -0
- shelfdb-2.1.0rc1/src/shelfdb/shelf/shelf/query.py +200 -0
- shelfdb-2.1.0rc1/src/shelfdb/shelf/shelf/schema.py +55 -0
- shelfdb-2.1.0rc1/src/shelfdb/shelf/shelf/shelf.py +209 -0
- shelfdb-2.1.0rc1/src/shelfdb/target.py +30 -0
- shelfdb-2.0.0.dev0/PKG-INFO +0 -120
- shelfdb-2.0.0.dev0/README.md +0 -98
- shelfdb-2.0.0.dev0/src/shelfdb/__init__.py +0 -11
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/__init__.py +0 -1
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/SKILL.md +0 -90
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/agents/openai.yaml +0 -4
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/api-reference.md +0 -74
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/embedded-mode.md +0 -155
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/getting-started.md +0 -118
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/index.md +0 -93
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/protocol.md +0 -136
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/query-model.md +0 -188
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/security.md +0 -37
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/server-mode.md +0 -181
- shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/transactions.md +0 -120
- shelfdb-2.0.0.dev0/src/shelfdb/cli.py +0 -122
- shelfdb-2.0.0.dev0/src/shelfdb/client/__init__.py +0 -38
- shelfdb-2.0.0.dev0/src/shelfdb/client/_impl.py +0 -409
- shelfdb-2.0.0.dev0/src/shelfdb/log.py +0 -36
- shelfdb-2.0.0.dev0/src/shelfdb/protocol/__init__.py +0 -27
- shelfdb-2.0.0.dev0/src/shelfdb/protocol/codec.py +0 -32
- shelfdb-2.0.0.dev0/src/shelfdb/protocol/payload.py +0 -129
- shelfdb-2.0.0.dev0/src/shelfdb/protocol/query.py +0 -22
- shelfdb-2.0.0.dev0/src/shelfdb/protocol/schema.py +0 -70
- shelfdb-2.0.0.dev0/src/shelfdb/server/__init__.py +0 -10
- shelfdb-2.0.0.dev0/src/shelfdb/server/rpc.py +0 -35
- shelfdb-2.0.0.dev0/src/shelfdb/server/runtime.py +0 -144
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/__init__.py +0 -18
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/core.py +0 -349
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/normalize.py +0 -26
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/query.py +0 -76
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/storage/__init__.py +0 -1
- shelfdb-2.0.0.dev0/src/shelfdb/shelf/storage/lmdb.py +0 -150
- shelfdb-2.0.0.dev0/src/shelfdb/util/__init__.py +0 -1
- shelfdb-2.0.0.dev0/src/shelfdb/util/transport.py +0 -31
- shelfdb-2.0.0.dev0/src/shelfdb/util/validation.py +0 -45
- {shelfdb-2.0.0.dev0 → shelfdb-2.1.0rc1}/LICENSE +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: shelfdb
|
|
3
|
+
Version: 2.1.0rc1
|
|
4
|
+
Summary: A tiny database for Python
|
|
5
|
+
Author: Nitipit Nontasuwan
|
|
6
|
+
Author-email: Nitipit Nontasuwan <nitipit@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Dist: cyclopts>=4.10.2
|
|
13
|
+
Requires-Dist: dictify>=4.0.0,<4.1
|
|
14
|
+
Requires-Dist: dill>=0.4.0,<0.5
|
|
15
|
+
Requires-Dist: lmdb>=1.7.3,<2
|
|
16
|
+
Requires-Dist: msgpack>=1.1.2,<2
|
|
17
|
+
Requires-Dist: structlog>=25.1.0,<26
|
|
18
|
+
Requires-Dist: uvloop>=0.22.0,<0.23 ; sys_platform == 'linux'
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# shelfdb
|
|
23
|
+
|
|
24
|
+
Tiny LMDB-backed shelf database utilities.
|
|
25
|
+
|
|
26
|
+
## Server
|
|
27
|
+
|
|
28
|
+
Run the protocol server:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
shelfdb server
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Run the protocol server on a custom address:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
shelfdb server --url "tcp://0.0.0.0:17001" --db-path ./db
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Client
|
|
41
|
+
|
|
42
|
+
Connect a client:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from shelfdb.client import Client
|
|
46
|
+
|
|
47
|
+
client = await Client.connect("tcp://127.0.0.1:31337")
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Unix sockets also work:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from shelfdb.client import Client
|
|
54
|
+
|
|
55
|
+
client = await Client.connect("unix:///tmp/shelfdb.sock")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Example
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from shelfdb.client import Client
|
|
62
|
+
|
|
63
|
+
client = await Client.connect("tcp://127.0.0.1:31337")
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
async with client.transaction() as tx:
|
|
67
|
+
users = tx.shelf("users")
|
|
68
|
+
|
|
69
|
+
count = await users.count().query()
|
|
70
|
+
alice = await users.key("alice").item().query()
|
|
71
|
+
admins = await users.filter(
|
|
72
|
+
lambda item: item.value["role"] == "admin"
|
|
73
|
+
).sort(reverse=True).query()
|
|
74
|
+
|
|
75
|
+
async with client.transaction(write=True) as tx:
|
|
76
|
+
users = tx.shelf("users")
|
|
77
|
+
|
|
78
|
+
await users.put("eve", {"role": "user"}).query()
|
|
79
|
+
await users.key("eve").update(
|
|
80
|
+
lambda item: {**item.value, "role": "admin"}
|
|
81
|
+
).query()
|
|
82
|
+
finally:
|
|
83
|
+
await client.close()
|
|
84
|
+
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# shelfdb
|
|
2
|
+
|
|
3
|
+
Tiny LMDB-backed shelf database utilities.
|
|
4
|
+
|
|
5
|
+
## Server
|
|
6
|
+
|
|
7
|
+
Run the protocol server:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
shelfdb server
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Run the protocol server on a custom address:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
shelfdb server --url "tcp://0.0.0.0:17001" --db-path ./db
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Client
|
|
20
|
+
|
|
21
|
+
Connect a client:
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from shelfdb.client import Client
|
|
25
|
+
|
|
26
|
+
client = await Client.connect("tcp://127.0.0.1:31337")
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Unix sockets also work:
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from shelfdb.client import Client
|
|
33
|
+
|
|
34
|
+
client = await Client.connect("unix:///tmp/shelfdb.sock")
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Example
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from shelfdb.client import Client
|
|
41
|
+
|
|
42
|
+
client = await Client.connect("tcp://127.0.0.1:31337")
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
async with client.transaction() as tx:
|
|
46
|
+
users = tx.shelf("users")
|
|
47
|
+
|
|
48
|
+
count = await users.count().query()
|
|
49
|
+
alice = await users.key("alice").item().query()
|
|
50
|
+
admins = await users.filter(
|
|
51
|
+
lambda item: item.value["role"] == "admin"
|
|
52
|
+
).sort(reverse=True).query()
|
|
53
|
+
|
|
54
|
+
async with client.transaction(write=True) as tx:
|
|
55
|
+
users = tx.shelf("users")
|
|
56
|
+
|
|
57
|
+
await users.put("eve", {"role": "user"}).query()
|
|
58
|
+
await users.key("eve").update(
|
|
59
|
+
lambda item: {**item.value, "role": "admin"}
|
|
60
|
+
).query()
|
|
61
|
+
finally:
|
|
62
|
+
await client.close()
|
|
63
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shelfdb-usage
|
|
3
|
+
description: Use ShelfDB correctly in this repository when writing code, tests, docs, examples, or answering questions about ShelfDB usage. Trigger this skill when work involves starting the ShelfDB server, using the async remote client, using the local direct DB API, choosing between local and remote access, or pointing users to the right ShelfDB docs and examples.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ShelfDB usage
|
|
7
|
+
|
|
8
|
+
Use ShelfDB in one of two modes:
|
|
9
|
+
|
|
10
|
+
- **Remote client/server**: start `shelfdb server`, connect with `shelfdb.client.Client`, open async transactions, and end remote reads or writes with `await ...query()`.
|
|
11
|
+
- **Local direct DB**: open `shelfdb.shelf.DB(...)`, use local transactions, and run queries directly without `.query()`.
|
|
12
|
+
|
|
13
|
+
## Core rules
|
|
14
|
+
|
|
15
|
+
- Prefer the **remote client** flow for application code and flexible deployment.
|
|
16
|
+
- Use **local DB access** only when the process can open the database directly.
|
|
17
|
+
- For remote usage, remember: builder methods do nothing until `await .query()`.
|
|
18
|
+
- For local usage, do not add `.query()`; local operations run directly.
|
|
19
|
+
- Use `client.transaction()` for reads and `client.transaction(write=True)` for mutations.
|
|
20
|
+
- Close remote clients with `await client.close()`.
|
|
21
|
+
- Start the server with `shelfdb server`; default URL is `tcp://127.0.0.1:31337` and default DB path is `db`.
|
|
22
|
+
|
|
23
|
+
## Read the bundled docs for details
|
|
24
|
+
|
|
25
|
+
Read the skill-local docs under `ai-skill/shelfdb-usage/docs/` as needed:
|
|
26
|
+
|
|
27
|
+
- `docs/index.md` — overview, fit, and navigation
|
|
28
|
+
- `docs/usage/installation.md` — install and CLI verification
|
|
29
|
+
- `docs/usage/server.md` — server startup and URL formats
|
|
30
|
+
- `docs/usage/remote.md` — async client usage and `.query()` behavior
|
|
31
|
+
- `docs/usage/local.md` — direct local DB usage
|
|
32
|
+
- `docs/api/index.md` — API reference index
|
|
33
|
+
- `docs/api/client.md` — remote client API
|
|
34
|
+
- `docs/api/local.md` — local DB API
|
|
35
|
+
- `docs/api/cli.md` — CLI reference
|
|
36
|
+
|
|
37
|
+
## Practical guidance
|
|
38
|
+
|
|
39
|
+
- If the user asks for app code that talks to a running ShelfDB instance, use the remote client API.
|
|
40
|
+
- If the user asks for simple in-process storage examples, use `DB(...)` and local transactions.
|
|
41
|
+
- If the user is confused about why nothing happens remotely, check whether `.query()` is missing.
|
|
42
|
+
- If the user needs a server command example, prefer `shelfdb server --db-path ./db --url tcp://127.0.0.1:31337` unless they need a Unix socket.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# CLI Reference
|
|
2
|
+
|
|
3
|
+
ShelfDB currently provides one main CLI command for running the server.
|
|
4
|
+
|
|
5
|
+
## `shelfdb server`
|
|
6
|
+
|
|
7
|
+
Run the ShelfDB protocol server.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
$ shelfdb server --help
|
|
11
|
+
Usage: shelfdb server [ARGS]
|
|
12
|
+
|
|
13
|
+
Run the ShelfDB protocol server.
|
|
14
|
+
|
|
15
|
+
╭─ Parameters ─────────────────────────────────────────────────────────────────╮
|
|
16
|
+
│ DB-PATH --db-path [default: db] │
|
|
17
|
+
│ URL --url [default: tcp://127.0.0.1:31337] │
|
|
18
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Options
|
|
22
|
+
|
|
23
|
+
- `--db-path PATH` — database directory path, default: `db`
|
|
24
|
+
- `--url URL` — server target URL, default: `tcp://127.0.0.1:31337`
|
|
25
|
+
|
|
26
|
+
Supported URL styles:
|
|
27
|
+
|
|
28
|
+
- `tcp://127.0.0.1:31337`
|
|
29
|
+
- `unix:///tmp/shelfdb.sock`
|
|
30
|
+
- `unix://tmp/shelfdb.sock`
|
|
31
|
+
|
|
32
|
+
### Examples
|
|
33
|
+
|
|
34
|
+
Run with the default TCP address:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
shelfdb server
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Run on a specific TCP address:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
shelfdb server --db-path ./db --url tcp://0.0.0.0:31337
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Run on a Unix socket:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
shelfdb server --db-path ./db --url unix:///tmp/shelfdb.sock
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Run on a relative Unix socket path:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
shelfdb server --url unix://tmp/shelfdb.sock
|
|
56
|
+
```
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Client API
|
|
2
|
+
|
|
3
|
+
Use the client API when your application talks to a running ShelfDB server over TCP or Unix sockets.
|
|
4
|
+
|
|
5
|
+
## `Client`
|
|
6
|
+
|
|
7
|
+
`Client` is the main entry point for remote usage.
|
|
8
|
+
|
|
9
|
+
Typical flow:
|
|
10
|
+
|
|
11
|
+
1. connect with `Client.connect(...)`
|
|
12
|
+
2. open a transaction with `client.transaction(...)`
|
|
13
|
+
3. work with a shelf inside the transaction
|
|
14
|
+
4. execute remote reads or writes with `.query()`
|
|
15
|
+
5. close the client with `client.close()`
|
|
16
|
+
|
|
17
|
+
## `Client.connect(target: str) -> Client`
|
|
18
|
+
|
|
19
|
+
Connect to a ShelfDB server.
|
|
20
|
+
|
|
21
|
+
Supported targets:
|
|
22
|
+
|
|
23
|
+
- `tcp://127.0.0.1:31337`
|
|
24
|
+
- `unix:///tmp/shelfdb.sock`
|
|
25
|
+
- `unix://tmp/shelfdb.sock`
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from shelfdb.client import Client
|
|
29
|
+
|
|
30
|
+
client = await Client.connect("tcp://127.0.0.1:31337")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## `client.transaction(*, write: bool = False) -> ClientTransaction`
|
|
34
|
+
|
|
35
|
+
Open a remote transaction.
|
|
36
|
+
|
|
37
|
+
Use the default `write=False` for read-only work. Use `write=True` for mutations.
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
async with client.transaction() as tx:
|
|
41
|
+
users = tx.shelf("users")
|
|
42
|
+
count = await users.count().query()
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## `client.close() -> None`
|
|
46
|
+
|
|
47
|
+
Close the client connection.
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
await client.close()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Query object from `tx.shelf(name)`
|
|
54
|
+
|
|
55
|
+
Inside a client transaction, `tx.shelf("users")` returns a remote query object.
|
|
56
|
+
|
|
57
|
+
Builder methods only build query state locally. Remote execution happens only when you await `.query()`.
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
users = tx.shelf("users")
|
|
61
|
+
alice = await users.key("alice").item().query()
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Selection methods
|
|
65
|
+
|
|
66
|
+
### `key(key: str) -> RemoteShelfQuery`
|
|
67
|
+
|
|
68
|
+
Select one key.
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
alice = await users.key("alice").item().query()
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### `keys_range(start: str, stop: str | None = None) -> RemoteShelfQuery`
|
|
75
|
+
|
|
76
|
+
Select keys in the half-open range `[start, stop)`.
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
result = await users.keys_range("bob", "d").query()
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### `keys() -> RemoteShelfQuery`
|
|
83
|
+
|
|
84
|
+
Project the current selection to keys.
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
result = await users.items().keys().query()
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### `items() -> RemoteShelfQuery`
|
|
91
|
+
|
|
92
|
+
Project the current selection to loaded key/value items.
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
result = await users.items().query()
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### `asc() -> RemoteShelfQuery`
|
|
99
|
+
|
|
100
|
+
Use ascending key order.
|
|
101
|
+
|
|
102
|
+
### `desc() -> RemoteShelfQuery`
|
|
103
|
+
|
|
104
|
+
Use descending key order.
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
result = await users.desc().query()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Transform methods
|
|
111
|
+
|
|
112
|
+
### `filter(fn) -> RemoteShelfQuery`
|
|
113
|
+
|
|
114
|
+
Filter matching items.
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
admins = await users.filter(
|
|
118
|
+
lambda item: item.value["role"] == "admin"
|
|
119
|
+
).query()
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### `slice(start: int | None = None, stop: int | None = None, step: int | None = None) -> RemoteShelfQuery`
|
|
123
|
+
|
|
124
|
+
Slice the current selection.
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
result = await users.sort(reverse=True).slice(0, 2).query()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### `sort(key=None, reverse: bool = False) -> RemoteShelfQuery`
|
|
131
|
+
|
|
132
|
+
Sort the current selection.
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
result = await users.sort(reverse=True).query()
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Terminal execution
|
|
139
|
+
|
|
140
|
+
### `query() -> Any`
|
|
141
|
+
|
|
142
|
+
Execute the built remote query or action.
|
|
143
|
+
|
|
144
|
+
This is the only terminal method on the remote client.
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
count = await users.count().query()
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Read actions
|
|
151
|
+
|
|
152
|
+
### `count() -> RemoteShelfQuery`
|
|
153
|
+
|
|
154
|
+
Build an action that returns the number of selected items.
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
count = await users.count().query()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### `exists() -> RemoteShelfQuery`
|
|
161
|
+
|
|
162
|
+
Build an action that returns whether the selection exists.
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
exists = await users.key("alice").exists().query()
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### `item() -> RemoteShelfQuery`
|
|
169
|
+
|
|
170
|
+
Build an action that returns exactly one item.
|
|
171
|
+
|
|
172
|
+
Raises an error if zero or more than one item matches.
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
alice = await users.key("alice").item().query()
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Write actions
|
|
179
|
+
|
|
180
|
+
### `put(key: str, value: Any) -> RemoteShelfQuery`
|
|
181
|
+
|
|
182
|
+
Build an action that stores one key/value pair.
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
await users.put("alice", {"role": "admin"}).query()
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### `put_many(items: list[Item]) -> RemoteShelfQuery`
|
|
189
|
+
|
|
190
|
+
Build an action that stores multiple items.
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
from shelfdb.shelf import Item
|
|
194
|
+
|
|
195
|
+
await users.put_many([
|
|
196
|
+
Item("alice", {"role": "admin"}),
|
|
197
|
+
Item("bob", {"role": "user"}),
|
|
198
|
+
]).query()
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### `update(fn) -> RemoteShelfQuery`
|
|
202
|
+
|
|
203
|
+
Build an action that updates the selected items using `fn`.
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
await users.key("alice").update(
|
|
207
|
+
lambda item: {**item.value, "active": True}
|
|
208
|
+
).query()
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### `delete() -> RemoteShelfQuery`
|
|
212
|
+
|
|
213
|
+
Build an action that deletes the selected items.
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
await users.key("alice").delete().query()
|
|
217
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
This section documents the public usage surface of ShelfDB.
|
|
4
|
+
|
|
5
|
+
It complements the usage guides:
|
|
6
|
+
|
|
7
|
+
- the usage pages explain the workflow and mental model
|
|
8
|
+
- the API pages list the public entry points, signatures, and common examples
|
|
9
|
+
|
|
10
|
+
Available reference pages:
|
|
11
|
+
|
|
12
|
+
- [Client API](client.md)
|
|
13
|
+
- [Local DB API](local.md)
|
|
14
|
+
- [CLI Reference](cli.md)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Local DB API
|
|
2
|
+
|
|
3
|
+
Use the local API when your code can open the database directly.
|
|
4
|
+
|
|
5
|
+
## `DB`
|
|
6
|
+
|
|
7
|
+
`DB` is the main entry point for direct local usage.
|
|
8
|
+
|
|
9
|
+
## `DB(path: str, *, map_size: int = 1024 * 1024 * 1024, max_dbs: int = 128)`
|
|
10
|
+
|
|
11
|
+
Open a local ShelfDB database.
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from shelfdb.shelf import DB
|
|
15
|
+
|
|
16
|
+
with DB("./db") as db:
|
|
17
|
+
...
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## `db.transaction(*, write: bool = True) -> Transaction`
|
|
21
|
+
|
|
22
|
+
Open a local transaction.
|
|
23
|
+
|
|
24
|
+
Use `write=True` for writes and `write=False` for read-only access.
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
with DB("./db") as db:
|
|
28
|
+
with db.transaction(write=False) as tx:
|
|
29
|
+
users = tx.shelf("users")
|
|
30
|
+
count = users.count()
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Query object from `tx.shelf(name)`
|
|
34
|
+
|
|
35
|
+
Inside a local transaction, `tx.shelf("users")` returns a query object.
|
|
36
|
+
|
|
37
|
+
Unlike remote client usage, local queries run directly and do not end with `.query()`.
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
users = tx.shelf("users")
|
|
41
|
+
alice = users.key("alice").item()
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Selection methods
|
|
45
|
+
|
|
46
|
+
### `key(key: str) -> ShelfQuery`
|
|
47
|
+
|
|
48
|
+
Select one key.
|
|
49
|
+
|
|
50
|
+
### `keys_range(start: str, stop: str | None = None) -> ShelfQuery`
|
|
51
|
+
|
|
52
|
+
Select keys in the half-open range `[start, stop)`.
|
|
53
|
+
|
|
54
|
+
### `keys() -> ShelfQuery`
|
|
55
|
+
|
|
56
|
+
Project the current selection to keys.
|
|
57
|
+
|
|
58
|
+
### `items() -> ShelfQuery`
|
|
59
|
+
|
|
60
|
+
Project the current selection to loaded key/value items.
|
|
61
|
+
|
|
62
|
+
### `asc() -> ShelfQuery`
|
|
63
|
+
|
|
64
|
+
Use ascending key order.
|
|
65
|
+
|
|
66
|
+
### `desc() -> ShelfQuery`
|
|
67
|
+
|
|
68
|
+
Use descending key order.
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
result = list(users.desc())
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Transform methods
|
|
75
|
+
|
|
76
|
+
### `filter(fn) -> ShelfQuery`
|
|
77
|
+
|
|
78
|
+
Filter matching items.
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
admins = list(users.filter(lambda item: item.value["role"] == "admin"))
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `slice(start: int | None = None, stop: int | None = None, step: int | None = None) -> ShelfQuery`
|
|
85
|
+
|
|
86
|
+
Slice the current selection.
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
result = list(users.sort(reverse=True).slice(0, 2))
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### `sort(key=None, reverse: bool = False) -> ShelfQuery`
|
|
93
|
+
|
|
94
|
+
Sort the current selection.
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
result = list(users.sort(reverse=True))
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Read methods
|
|
101
|
+
|
|
102
|
+
### `count() -> int`
|
|
103
|
+
|
|
104
|
+
Return the number of selected items.
|
|
105
|
+
|
|
106
|
+
### `exists() -> bool`
|
|
107
|
+
|
|
108
|
+
Return whether the current selection contains at least one item.
|
|
109
|
+
|
|
110
|
+
### `item() -> Item`
|
|
111
|
+
|
|
112
|
+
Return exactly one selected item.
|
|
113
|
+
|
|
114
|
+
Raises an error if zero or more than one item matches.
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
alice = users.key("alice").item()
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Write methods
|
|
121
|
+
|
|
122
|
+
### `put(key: str, value: Any) -> MutationResult`
|
|
123
|
+
|
|
124
|
+
Store one key/value pair.
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
users.put("alice", {"role": "admin"})
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### `put_many(items: Iterable[Item]) -> list[MutationResult]`
|
|
131
|
+
|
|
132
|
+
Store multiple items.
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from shelfdb.shelf import Item
|
|
136
|
+
|
|
137
|
+
users.put_many([
|
|
138
|
+
Item("alice", {"role": "admin"}),
|
|
139
|
+
Item("bob", {"role": "user"}),
|
|
140
|
+
])
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### `update(fn) -> list[MutationResult]`
|
|
144
|
+
|
|
145
|
+
Update the selected items using `fn`.
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
users.key("alice").update(lambda item: {**item.value, "active": True})
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `delete() -> list[MutationResult]`
|
|
152
|
+
|
|
153
|
+
Delete the selected items.
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
users.key("alice").delete()
|
|
157
|
+
```
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# ShelfDB
|
|
2
|
+
|
|
3
|
+
ShelfDB is a simple, fast key-value database for Python asyncio apps.
|
|
4
|
+
|
|
5
|
+
Store Python values like `str`, `int`, `dict`, `list`, and `bytes` with transactions, query chaining, and flexible local or client/server access over TCP or Unix sockets.
|
|
6
|
+
|
|
7
|
+
## Quick example
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
from shelfdb.shelf import DB
|
|
11
|
+
|
|
12
|
+
with DB("./db") as db:
|
|
13
|
+
with db.transaction(write=True) as tx:
|
|
14
|
+
users = tx.shelf("users")
|
|
15
|
+
users.put("alice", {"role": "admin", "age": 30})
|
|
16
|
+
|
|
17
|
+
with db.transaction(write=False) as tx:
|
|
18
|
+
users = tx.shelf("users")
|
|
19
|
+
alice = users.key("alice").item()
|
|
20
|
+
print(alice)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Other access styles:
|
|
24
|
+
|
|
25
|
+
- [Remote client usage over TCP](usage/remote.md)
|
|
26
|
+
- [Remote client usage over Unix sockets](usage/remote.md)
|
|
27
|
+
|
|
28
|
+
## Key features
|
|
29
|
+
|
|
30
|
+
- **Simple key-value model** for application data
|
|
31
|
+
- **Asyncio-friendly client usage** for Python async applications
|
|
32
|
+
- **Transactions** for reads and writes
|
|
33
|
+
- **Client/server access** over TCP or Unix sockets
|
|
34
|
+
- **Local direct access** when your code can open the database itself
|
|
35
|
+
- **Chainable query style** for readable data access
|
|
36
|
+
|
|
37
|
+
## Where ShelfDB fits
|
|
38
|
+
|
|
39
|
+
ShelfDB fits between TinyDB and SQLite for Python application storage.
|
|
40
|
+
|
|
41
|
+
| Feature | ShelfDB | SQLite | TinyDB |
|
|
42
|
+
| --- | --- | --- | --- |
|
|
43
|
+
| Type of data store | Key-value store | Relational SQL database | Document database |
|
|
44
|
+
| Asyncio-friendly client usage | Yes | Limited / adapter-based | No |
|
|
45
|
+
| Transactions | Yes | Yes | No |
|
|
46
|
+
| Client/server access | Yes | Not the usual model | No |
|
|
47
|
+
| Local direct access | Yes | Yes | Yes |
|
|
48
|
+
| Chainable Python query style | Yes | No | Yes |
|
|
49
|
+
|
|
50
|
+
ShelfDB is a good fit when you want something simpler than a SQL workflow, but more structured and deployable than a tiny in-process document store.
|
|
51
|
+
|
|
52
|
+
## When to use it
|
|
53
|
+
|
|
54
|
+
ShelfDB fits well when you want:
|
|
55
|
+
|
|
56
|
+
- a simple database for Python asyncio applications
|
|
57
|
+
- application state, metadata, caches, queues, or internal tools
|
|
58
|
+
- a local database today with the option to move to client/server access later
|
|
59
|
+
- something simpler than SQL for app storage
|
|
60
|
+
- something more structured than a tiny JSON-style store
|
|
61
|
+
|
|
62
|
+
## Next steps
|
|
63
|
+
|
|
64
|
+
- Start with [Installation](usage/installation.md)
|
|
65
|
+
- Learn how to [run the server](usage/server.md)
|
|
66
|
+
- See [remote client usage](usage/remote.md)
|
|
67
|
+
- See [local database usage](usage/local.md)
|