shelfdb 2.0.0.dev0__tar.gz → 3.0.1__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 (60) hide show
  1. shelfdb-3.0.1/PKG-INFO +130 -0
  2. shelfdb-3.0.1/README.md +111 -0
  3. shelfdb-3.0.1/ai-skill/shelfdb-usage/SKILL.md +56 -0
  4. shelfdb-3.0.1/pyproject.toml +55 -0
  5. shelfdb-2.0.0.dev0/pyproject.toml → shelfdb-3.0.1/pyproject.toml.orig +17 -11
  6. shelfdb-3.0.1/src/shelfdb/__init__.py +0 -0
  7. shelfdb-3.0.1/src/shelfdb/__main__.py +5 -0
  8. shelfdb-3.0.1/src/shelfdb/cli.py +109 -0
  9. shelfdb-3.0.1/src/shelfdb/client/__init__.py +3 -0
  10. shelfdb-3.0.1/src/shelfdb/client/client.py +225 -0
  11. shelfdb-3.0.1/src/shelfdb/protocol/__init__.py +35 -0
  12. shelfdb-3.0.1/src/shelfdb/protocol/demo_poc.py +62 -0
  13. shelfdb-3.0.1/src/shelfdb/protocol/protocol.py +81 -0
  14. shelfdb-3.0.1/src/shelfdb/protocol/query_result.py +49 -0
  15. shelfdb-3.0.1/src/shelfdb/protocol/server.py +110 -0
  16. shelfdb-3.0.1/src/shelfdb/protocol/session.py +180 -0
  17. shelfdb-3.0.1/src/shelfdb/shelf/__init__.py +4 -0
  18. shelfdb-3.0.1/src/shelfdb/shelf/db.py +217 -0
  19. shelfdb-3.0.1/src/shelfdb/shelf/shelf/__init__.py +4 -0
  20. shelfdb-3.0.1/src/shelfdb/shelf/shelf/query.py +200 -0
  21. shelfdb-3.0.1/src/shelfdb/shelf/shelf/schema.py +55 -0
  22. shelfdb-3.0.1/src/shelfdb/shelf/shelf/shelf.py +209 -0
  23. shelfdb-3.0.1/src/shelfdb/target.py +30 -0
  24. shelfdb-2.0.0.dev0/PKG-INFO +0 -120
  25. shelfdb-2.0.0.dev0/README.md +0 -98
  26. shelfdb-2.0.0.dev0/src/shelfdb/__init__.py +0 -11
  27. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/__init__.py +0 -1
  28. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/SKILL.md +0 -90
  29. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/agents/openai.yaml +0 -4
  30. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/api-reference.md +0 -74
  31. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/embedded-mode.md +0 -155
  32. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/getting-started.md +0 -118
  33. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/index.md +0 -93
  34. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/protocol.md +0 -136
  35. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/query-model.md +0 -188
  36. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/security.md +0 -37
  37. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/server-mode.md +0 -181
  38. shelfdb-2.0.0.dev0/src/shelfdb/ai_skill/shelfdb-usage/references/docs/transactions.md +0 -120
  39. shelfdb-2.0.0.dev0/src/shelfdb/cli.py +0 -122
  40. shelfdb-2.0.0.dev0/src/shelfdb/client/__init__.py +0 -38
  41. shelfdb-2.0.0.dev0/src/shelfdb/client/_impl.py +0 -409
  42. shelfdb-2.0.0.dev0/src/shelfdb/log.py +0 -36
  43. shelfdb-2.0.0.dev0/src/shelfdb/protocol/__init__.py +0 -27
  44. shelfdb-2.0.0.dev0/src/shelfdb/protocol/codec.py +0 -32
  45. shelfdb-2.0.0.dev0/src/shelfdb/protocol/payload.py +0 -129
  46. shelfdb-2.0.0.dev0/src/shelfdb/protocol/query.py +0 -22
  47. shelfdb-2.0.0.dev0/src/shelfdb/protocol/schema.py +0 -70
  48. shelfdb-2.0.0.dev0/src/shelfdb/server/__init__.py +0 -10
  49. shelfdb-2.0.0.dev0/src/shelfdb/server/rpc.py +0 -35
  50. shelfdb-2.0.0.dev0/src/shelfdb/server/runtime.py +0 -144
  51. shelfdb-2.0.0.dev0/src/shelfdb/shelf/__init__.py +0 -18
  52. shelfdb-2.0.0.dev0/src/shelfdb/shelf/core.py +0 -349
  53. shelfdb-2.0.0.dev0/src/shelfdb/shelf/normalize.py +0 -26
  54. shelfdb-2.0.0.dev0/src/shelfdb/shelf/query.py +0 -76
  55. shelfdb-2.0.0.dev0/src/shelfdb/shelf/storage/__init__.py +0 -1
  56. shelfdb-2.0.0.dev0/src/shelfdb/shelf/storage/lmdb.py +0 -150
  57. shelfdb-2.0.0.dev0/src/shelfdb/util/__init__.py +0 -1
  58. shelfdb-2.0.0.dev0/src/shelfdb/util/transport.py +0 -31
  59. shelfdb-2.0.0.dev0/src/shelfdb/util/validation.py +0 -45
  60. {shelfdb-2.0.0.dev0 → shelfdb-3.0.1}/LICENSE +0 -0
shelfdb-3.0.1/PKG-INFO ADDED
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.4
2
+ Name: shelfdb
3
+ Version: 3.0.1
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: Operating System :: OS Independent
11
+ Requires-Dist: cyclopts>=4.10.2,<5
12
+ Requires-Dist: dill>=0.4.0,<0.5
13
+ Requires-Dist: lmdb>=1.7.3,<2
14
+ Requires-Dist: msgpack>=1.2.1,<2
15
+ Requires-Python: >=3.12
16
+ Project-URL: Documentation, https://keenlycode.github.io/shelfdb/
17
+ Project-URL: Repository, https://github.com/keenlycode/shelfdb
18
+ Description-Content-Type: text/markdown
19
+
20
+ # shelfdb
21
+
22
+ Tiny LMDB-backed shelf database utilities.
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install shelfdb
28
+ ```
29
+
30
+ > [!WARNING]
31
+ > The client/server protocol uses `dill` to support Python callables. Only use it
32
+ > between trusted processes; do not expose the server to untrusted clients or public
33
+ > networks.
34
+
35
+ ## Development
36
+
37
+ Install development dependencies:
38
+
39
+ ```bash
40
+ uv sync --dev
41
+ ```
42
+
43
+ Run the complete non-publishing release gate:
44
+
45
+ ```bash
46
+ uv run python -m dev release-check
47
+ ```
48
+
49
+ The gate audits locked dependencies, checks formatting, linting, types, supported
50
+ Python versions, strict documentation, release artifacts, metadata, and a clean
51
+ wheel installation. GitHub Actions runs the same gate on pull requests, `main`,
52
+ and version tags.
53
+
54
+ Serve the docs locally:
55
+
56
+ ```bash
57
+ uv run python -m dev docs serve --port 9001 --livereload
58
+ ```
59
+
60
+ Publish the docs with mike to the `docs` branch:
61
+
62
+ ```bash
63
+ uv run python -m dev docs publish
64
+ ```
65
+
66
+ Override the publish target when needed:
67
+
68
+ ```bash
69
+ uv run python -m dev docs publish --publish-version 3.0.1 --alias latest --branch docs --remote origin
70
+ ```
71
+
72
+ ## Server
73
+
74
+ Run the protocol server:
75
+
76
+ ```bash
77
+ shelfdb server
78
+ ```
79
+
80
+ Run the protocol server on a custom address:
81
+
82
+ ```bash
83
+ shelfdb server --url "tcp://0.0.0.0:17001" --db-path ./db
84
+ ```
85
+
86
+ ## Client
87
+
88
+ Connect a client:
89
+
90
+ ```python
91
+ from shelfdb.client import Client
92
+
93
+ client = await Client.connect("tcp://127.0.0.1:31337")
94
+ ```
95
+
96
+ Unix sockets also work:
97
+
98
+ ```python
99
+ from shelfdb.client import Client
100
+
101
+ client = await Client.connect("unix:///tmp/shelfdb.sock")
102
+ ```
103
+
104
+ ## Example
105
+
106
+ ```python
107
+ from shelfdb.client import Client
108
+
109
+ client = await Client.connect("tcp://127.0.0.1:31337")
110
+
111
+ try:
112
+ async with client.transaction() as tx:
113
+ users = tx.shelf("users")
114
+
115
+ count = await users.count().query()
116
+ alice = await users.key("alice").item().query()
117
+ admins = await users.filter(
118
+ lambda item: item.value["role"] == "admin"
119
+ ).sort(reverse=True).query()
120
+
121
+ async with client.transaction(write=True) as tx:
122
+ users = tx.shelf("users")
123
+
124
+ await users.put("eve", {"role": "user"}).query()
125
+ await users.key("eve").update(
126
+ lambda item: {**item.value, "role": "admin"}
127
+ ).query()
128
+ finally:
129
+ await client.close()
130
+ ```
@@ -0,0 +1,111 @@
1
+ # shelfdb
2
+
3
+ Tiny LMDB-backed shelf database utilities.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install shelfdb
9
+ ```
10
+
11
+ > [!WARNING]
12
+ > The client/server protocol uses `dill` to support Python callables. Only use it
13
+ > between trusted processes; do not expose the server to untrusted clients or public
14
+ > networks.
15
+
16
+ ## Development
17
+
18
+ Install development dependencies:
19
+
20
+ ```bash
21
+ uv sync --dev
22
+ ```
23
+
24
+ Run the complete non-publishing release gate:
25
+
26
+ ```bash
27
+ uv run python -m dev release-check
28
+ ```
29
+
30
+ The gate audits locked dependencies, checks formatting, linting, types, supported
31
+ Python versions, strict documentation, release artifacts, metadata, and a clean
32
+ wheel installation. GitHub Actions runs the same gate on pull requests, `main`,
33
+ and version tags.
34
+
35
+ Serve the docs locally:
36
+
37
+ ```bash
38
+ uv run python -m dev docs serve --port 9001 --livereload
39
+ ```
40
+
41
+ Publish the docs with mike to the `docs` branch:
42
+
43
+ ```bash
44
+ uv run python -m dev docs publish
45
+ ```
46
+
47
+ Override the publish target when needed:
48
+
49
+ ```bash
50
+ uv run python -m dev docs publish --publish-version 3.0.1 --alias latest --branch docs --remote origin
51
+ ```
52
+
53
+ ## Server
54
+
55
+ Run the protocol server:
56
+
57
+ ```bash
58
+ shelfdb server
59
+ ```
60
+
61
+ Run the protocol server on a custom address:
62
+
63
+ ```bash
64
+ shelfdb server --url "tcp://0.0.0.0:17001" --db-path ./db
65
+ ```
66
+
67
+ ## Client
68
+
69
+ Connect a client:
70
+
71
+ ```python
72
+ from shelfdb.client import Client
73
+
74
+ client = await Client.connect("tcp://127.0.0.1:31337")
75
+ ```
76
+
77
+ Unix sockets also work:
78
+
79
+ ```python
80
+ from shelfdb.client import Client
81
+
82
+ client = await Client.connect("unix:///tmp/shelfdb.sock")
83
+ ```
84
+
85
+ ## Example
86
+
87
+ ```python
88
+ from shelfdb.client import Client
89
+
90
+ client = await Client.connect("tcp://127.0.0.1:31337")
91
+
92
+ try:
93
+ async with client.transaction() as tx:
94
+ users = tx.shelf("users")
95
+
96
+ count = await users.count().query()
97
+ alice = await users.key("alice").item().query()
98
+ admins = await users.filter(
99
+ lambda item: item.value["role"] == "admin"
100
+ ).sort(reverse=True).query()
101
+
102
+ async with client.transaction(write=True) as tx:
103
+ users = tx.shelf("users")
104
+
105
+ await users.put("eve", {"role": "user"}).query()
106
+ await users.key("eve").update(
107
+ lambda item: {**item.value, "role": "admin"}
108
+ ).query()
109
+ finally:
110
+ await client.close()
111
+ ```
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: shelfdb-usage
3
+ description: Use when writing, reviewing, or explaining ShelfDB local database code, async client/server code, transactions, or fluent queries.
4
+ ---
5
+
6
+ # ShelfDB usage
7
+
8
+ Choose access mode from the deployment:
9
+
10
+ - Use `shelfdb.shelf.DB` when the process can open the LMDB database directly.
11
+ - Use `shelfdb.client.Client` when a separate trusted process runs `shelfdb server`.
12
+
13
+ ## Safety boundary
14
+
15
+ The remote protocol uses `dill` so queries can contain Python callables. Deserializing a
16
+ request can execute arbitrary code in the server process. Never expose the server to
17
+ untrusted clients or public networks.
18
+
19
+ ## Local API
20
+
21
+ Use synchronous transactions. Operations execute directly; do not add `.query()`.
22
+
23
+ ```python
24
+ from shelfdb.shelf import DB
25
+
26
+ with DB("db") as db:
27
+ with db.transaction(write=False) as tx:
28
+ users = list(tx.shelf("users").items())
29
+ ```
30
+
31
+ ## Remote API
32
+
33
+ Connect asynchronously, use read transactions by default, and pass `write=True` for
34
+ mutations. Fluent operations only build a remote query; `await ...query()` sends it.
35
+
36
+ ```python
37
+ from shelfdb.client import Client
38
+
39
+ client = await Client.connect("tcp://127.0.0.1:31337")
40
+ try:
41
+ async with client.transaction() as tx:
42
+ users = await tx.shelf("users").items().query()
43
+ finally:
44
+ await client.close()
45
+ ```
46
+
47
+ ## Rules
48
+
49
+ - Use `client.transaction()` for remote reads.
50
+ - Use `client.transaction(write=True)` for remote mutations.
51
+ - Always close a remote client with `await client.close()`.
52
+ - Keep local and remote terminal behavior distinct.
53
+ - In a ShelfDB source checkout, use `tests/usage/` as executable examples.
54
+ - Consult the current documentation before assuming unsupported query behavior.
55
+
56
+ Documentation: https://keenlycode.github.io/shelfdb/
@@ -0,0 +1,55 @@
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 = "3.0.1"
8
+ description = "A tiny database for Python"
9
+ readme = "README.md"
10
+ requires-python = ">=3.12"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3.12",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+ dependencies = [
18
+ "cyclopts>=4.10.2,<5",
19
+ "dill>=0.4.0,<0.5",
20
+ "lmdb>=1.7.3,<2",
21
+ "msgpack>=1.2.1,<2",
22
+ ]
23
+
24
+ [[project.authors]]
25
+ name = "Nitipit Nontasuwan"
26
+ email = "nitipit@gmail.com"
27
+
28
+ [project.scripts]
29
+ shelfdb = "shelfdb.cli:main"
30
+
31
+ [project.urls]
32
+ Documentation = "https://keenlycode.github.io/shelfdb/"
33
+ Repository = "https://github.com/keenlycode/shelfdb"
34
+
35
+ [dependency-groups]
36
+ dev = [
37
+ "mike>=2.1.3,<3",
38
+ "mkdocs>=1.6.1,<2",
39
+ "mkdocs-shadcn>=0.10.4,<0.11",
40
+ "mkdocstrings[python]>=0.29.0,<0.30",
41
+ "pytest-cov>=7.0.0,<8",
42
+ "pymdown-extensions>=11.0.0,<12",
43
+ "pytest>=9.0.0,<10",
44
+ "ruff>=0.13.0,<0.14",
45
+ "tinydb>=4.8.2,<5",
46
+ "ty>=0.0.1a17,<0.0.2",
47
+ ]
48
+
49
+ [tool.uv.build-backend]
50
+ module-name = "shelfdb"
51
+ module-root = "src"
52
+ source-include = ["ai-skill/**"]
53
+
54
+ [tool.uv.build-backend.data]
55
+ data = "ai-skill"
@@ -4,8 +4,8 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "shelfdb"
7
- version = "2.0.0.dev0"
8
- description = "A tiny documents database for Python"
7
+ version = "3.0.1"
8
+ description = "A tiny database for Python"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
11
11
  license = "MIT"
@@ -13,34 +13,40 @@ license-files = ["LICENSE"]
13
13
  authors = [
14
14
  { name = "Nitipit Nontasuwan", email = "nitipit@gmail.com" },
15
15
  ]
16
- keywords = ["dict", "json", "database"]
17
16
  classifiers = [
18
17
  "Programming Language :: Python :: 3.12",
19
- "License :: OSI Approved :: MIT License",
20
18
  "Operating System :: OS Independent",
21
19
  ]
22
20
  dependencies = [
23
- "cyclopts>=4.10.2",
24
- "dictify>=4.0.0,<4.1",
21
+ "cyclopts>=4.10.2,<5",
25
22
  "dill>=0.4.0,<0.5",
26
23
  "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'",
24
+ "msgpack>=1.2.1,<2",
30
25
  ]
31
26
 
32
27
  [project.scripts]
33
28
  shelfdb = "shelfdb.cli:main"
34
29
 
30
+ [project.urls]
31
+ Documentation = "https://keenlycode.github.io/shelfdb/"
32
+ Repository = "https://github.com/keenlycode/shelfdb"
33
+
35
34
  [dependency-groups]
36
35
  dev = [
37
- "dictify>=4.0.0,<4.1",
36
+ "mike>=2.1.3,<3",
38
37
  "mkdocs>=1.6.1,<2",
39
38
  "mkdocs-shadcn>=0.10.4,<0.11",
40
39
  "mkdocstrings[python]>=0.29.0,<0.30",
41
- "pytest>=8.4.2,<9",
40
+ "pytest-cov>=7.0.0,<8",
41
+ "pymdown-extensions>=11.0.0,<12",
42
+ "pytest>=9.0.0,<10",
43
+ "ruff>=0.13.0,<0.14",
44
+ "tinydb>=4.8.2,<5",
45
+ "ty>=0.0.1a17,<0.0.2",
42
46
  ]
43
47
 
44
48
  [tool.uv.build-backend]
45
49
  module-name = "shelfdb"
46
50
  module-root = "src"
51
+ data = { data = "ai-skill" }
52
+ source-include = ["ai-skill/**"]
File without changes
@@ -0,0 +1,5 @@
1
+ from .cli import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ main()
@@ -0,0 +1,109 @@
1
+ """Command-line interface for ShelfDB."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import shutil
6
+ import sysconfig
7
+ from contextlib import suppress
8
+ from pathlib import Path
9
+
10
+ from cyclopts import App
11
+
12
+ from shelfdb.protocol import serve, serve_unix
13
+ from shelfdb.shelf import DB
14
+ from shelfdb.target import parse_target, parse_tcp_location, parse_unix_location
15
+
16
+ app = App("shelfdb")
17
+ DEFAULT_AI_SKILL_INSTALL_PATH = ".agents/skills/shelfdb-usage"
18
+
19
+
20
+ def repo_root() -> Path:
21
+ return Path(__file__).resolve().parents[2]
22
+
23
+
24
+ def bundled_ai_skill_path() -> Path:
25
+ data_root = Path(sysconfig.get_path("data"))
26
+ installed_path = data_root / "shelfdb-usage"
27
+ if installed_path.exists():
28
+ return installed_path
29
+
30
+ repo_path = repo_root() / "ai-skill" / "shelfdb-usage"
31
+ if repo_path.exists():
32
+ return repo_path
33
+
34
+ raise FileNotFoundError("Bundled ShelfDB AI skill not found.")
35
+
36
+
37
+ def install_ai_skill(destination: Path, *, force: bool = False) -> Path:
38
+ source_file = bundled_ai_skill_path() / "SKILL.md"
39
+ if not source_file.is_file():
40
+ raise FileNotFoundError("Bundled ShelfDB SKILL.md not found.")
41
+
42
+ if destination.exists():
43
+ if not destination.is_dir():
44
+ raise NotADirectoryError(
45
+ f"AI skill destination is not a directory: {destination}"
46
+ )
47
+ if not force:
48
+ raise FileExistsError(
49
+ f"AI skill destination already exists: {destination}. Use --force to replace SKILL.md."
50
+ )
51
+ else:
52
+ destination.mkdir(parents=True)
53
+
54
+ shutil.copy2(source_file, destination / "SKILL.md")
55
+ return destination
56
+
57
+
58
+ def prompt_ai_skill_install_path(
59
+ default_path: str = DEFAULT_AI_SKILL_INSTALL_PATH,
60
+ ) -> Path:
61
+ response = input(f"Install ShelfDB AI skill to [{default_path}]: ").strip()
62
+ return Path(response or default_path)
63
+
64
+
65
+ async def run_server(
66
+ *,
67
+ db_path: str,
68
+ url: str = "tcp://127.0.0.1:31337",
69
+ ) -> None:
70
+ scheme, location = parse_target(url)
71
+ socket_path = None
72
+
73
+ with DB(db_path) as db:
74
+ if scheme == "tcp":
75
+ host, port = parse_tcp_location(location)
76
+ server = await serve(db, host=host, port=port)
77
+ else:
78
+ socket_path = str(Path(parse_unix_location(location)))
79
+ server = await serve_unix(db, path=socket_path)
80
+
81
+ try:
82
+ await server.serve_forever()
83
+ finally:
84
+ server.close()
85
+ await server.wait_closed()
86
+ if socket_path is not None:
87
+ with suppress(FileNotFoundError):
88
+ Path(socket_path).unlink()
89
+
90
+
91
+ @app.command
92
+ async def server(
93
+ db_path: str = "db",
94
+ url: str = "tcp://127.0.0.1:31337",
95
+ ) -> None:
96
+ """Run the ShelfDB protocol server."""
97
+ await run_server(db_path=db_path, url=url)
98
+
99
+
100
+ @app.command(name="ai-skill-install")
101
+ def ai_skill_install(path: str | None = None, force: bool = False) -> None:
102
+ """Install the bundled ShelfDB AI skill to a local path."""
103
+ destination = Path(path) if path is not None else prompt_ai_skill_install_path()
104
+ installed = install_ai_skill(destination, force=force)
105
+ print(f"Installed ShelfDB AI skill to {installed}")
106
+
107
+
108
+ def main(argv: list[str] | None = None) -> None:
109
+ app(argv, backend="asyncio", result_action="return_none")
@@ -0,0 +1,3 @@
1
+ from .client import Client, ClientError, ClientTransaction, RemoteShelfQuery
2
+
3
+ __all__ = ["Client", "ClientError", "ClientTransaction", "RemoteShelfQuery"]