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.
Files changed (68) hide show
  1. shelfdb-2.1.0rc1/PKG-INFO +84 -0
  2. shelfdb-2.1.0rc1/README.md +63 -0
  3. shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/SKILL.md +42 -0
  4. shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/api/cli.md +56 -0
  5. shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/api/client.md +217 -0
  6. shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/api/index.md +14 -0
  7. shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/api/local.md +157 -0
  8. shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/index.md +67 -0
  9. shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/usage/installation.md +35 -0
  10. shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/usage/local.md +73 -0
  11. shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/usage/remote.md +176 -0
  12. shelfdb-2.1.0rc1/ai-skill/shelfdb-usage/docs/usage/server.md +40 -0
  13. {shelfdb-2.0.0.dev0 → shelfdb-2.1.0rc1}/pyproject.toml +11 -4
  14. shelfdb-2.1.0rc1/src/shelfdb/__init__.py +0 -0
  15. shelfdb-2.1.0rc1/src/shelfdb/__main__.py +5 -0
  16. shelfdb-2.1.0rc1/src/shelfdb/cli.py +96 -0
  17. shelfdb-2.1.0rc1/src/shelfdb/client/__init__.py +3 -0
  18. shelfdb-2.1.0rc1/src/shelfdb/client/client.py +225 -0
  19. shelfdb-2.1.0rc1/src/shelfdb/protocol/__init__.py +35 -0
  20. shelfdb-2.1.0rc1/src/shelfdb/protocol/demo_poc.py +62 -0
  21. shelfdb-2.1.0rc1/src/shelfdb/protocol/protocol.py +81 -0
  22. shelfdb-2.1.0rc1/src/shelfdb/protocol/query_result.py +49 -0
  23. shelfdb-2.1.0rc1/src/shelfdb/protocol/server.py +75 -0
  24. shelfdb-2.1.0rc1/src/shelfdb/protocol/session.py +178 -0
  25. shelfdb-2.1.0rc1/src/shelfdb/shelf/__init__.py +4 -0
  26. shelfdb-2.1.0rc1/src/shelfdb/shelf/db.py +217 -0
  27. shelfdb-2.1.0rc1/src/shelfdb/shelf/shelf/__init__.py +4 -0
  28. shelfdb-2.1.0rc1/src/shelfdb/shelf/shelf/query.py +200 -0
  29. shelfdb-2.1.0rc1/src/shelfdb/shelf/shelf/schema.py +55 -0
  30. shelfdb-2.1.0rc1/src/shelfdb/shelf/shelf/shelf.py +209 -0
  31. shelfdb-2.1.0rc1/src/shelfdb/target.py +30 -0
  32. shelfdb-2.0.0.dev0/PKG-INFO +0 -120
  33. shelfdb-2.0.0.dev0/README.md +0 -98
  34. shelfdb-2.0.0.dev0/src/shelfdb/__init__.py +0 -11
  35. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/__init__.py +0 -1
  36. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/SKILL.md +0 -90
  37. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/agents/openai.yaml +0 -4
  38. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/api-reference.md +0 -74
  39. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/embedded-mode.md +0 -155
  40. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/getting-started.md +0 -118
  41. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/index.md +0 -93
  42. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/protocol.md +0 -136
  43. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/query-model.md +0 -188
  44. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/security.md +0 -37
  45. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/server-mode.md +0 -181
  46. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/transactions.md +0 -120
  47. shelfdb-2.0.0.dev0/src/shelfdb/cli.py +0 -122
  48. shelfdb-2.0.0.dev0/src/shelfdb/client/__init__.py +0 -38
  49. shelfdb-2.0.0.dev0/src/shelfdb/client/_impl.py +0 -409
  50. shelfdb-2.0.0.dev0/src/shelfdb/log.py +0 -36
  51. shelfdb-2.0.0.dev0/src/shelfdb/protocol/__init__.py +0 -27
  52. shelfdb-2.0.0.dev0/src/shelfdb/protocol/codec.py +0 -32
  53. shelfdb-2.0.0.dev0/src/shelfdb/protocol/payload.py +0 -129
  54. shelfdb-2.0.0.dev0/src/shelfdb/protocol/query.py +0 -22
  55. shelfdb-2.0.0.dev0/src/shelfdb/protocol/schema.py +0 -70
  56. shelfdb-2.0.0.dev0/src/shelfdb/server/__init__.py +0 -10
  57. shelfdb-2.0.0.dev0/src/shelfdb/server/rpc.py +0 -35
  58. shelfdb-2.0.0.dev0/src/shelfdb/server/runtime.py +0 -144
  59. shelfdb-2.0.0.dev0/src/shelfdb/shelf/__init__.py +0 -18
  60. shelfdb-2.0.0.dev0/src/shelfdb/shelf/core.py +0 -349
  61. shelfdb-2.0.0.dev0/src/shelfdb/shelf/normalize.py +0 -26
  62. shelfdb-2.0.0.dev0/src/shelfdb/shelf/query.py +0 -76
  63. shelfdb-2.0.0.dev0/src/shelfdb/shelf/storage/__init__.py +0 -1
  64. shelfdb-2.0.0.dev0/src/shelfdb/shelf/storage/lmdb.py +0 -150
  65. shelfdb-2.0.0.dev0/src/shelfdb/util/__init__.py +0 -1
  66. shelfdb-2.0.0.dev0/src/shelfdb/util/transport.py +0 -31
  67. shelfdb-2.0.0.dev0/src/shelfdb/util/validation.py +0 -45
  68. {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)