bottle-lmdb 0.1.0__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.
@@ -0,0 +1,36 @@
1
+ Metadata-Version: 2.3
2
+ Name: bottle-lmdb
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Author: Kimikazu Kato
6
+ Author-email: Kimikazu Kato <kimikazu@gmail.com>
7
+ Requires-Dist: bottle>=0.12.25
8
+ Requires-Dist: lmdb>=3.0.0
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+
12
+ # bottle-lmdb
13
+ Lightning Memory-Mapped Database (LMDB) plugin for Bottle.
14
+
15
+ Usage:
16
+
17
+ ```python
18
+ from bottle import Bottle
19
+ from bottle_lmdb import LMDBPlugin
20
+
21
+ app = Bottle()
22
+ plugin = LMDBPlugin("/path/to/db")
23
+ app.install(plugin)
24
+
25
+ @app.get("/write/<key>/<value>")
26
+ def write(key, value, db):
27
+ with db.begin(write=True) as txn:
28
+ txn.put(key.encode(), value.encode())
29
+ return "ok"
30
+
31
+ @app.get("/read/<key>")
32
+ def read(key, db):
33
+ with db.begin() as txn:
34
+ value = txn.get(key.encode())
35
+ return value.decode() if value else "not found"
36
+ ```
@@ -0,0 +1,25 @@
1
+ # bottle-lmdb
2
+ Lightning Memory-Mapped Database (LMDB) plugin for Bottle.
3
+
4
+ Usage:
5
+
6
+ ```python
7
+ from bottle import Bottle
8
+ from bottle_lmdb import LMDBPlugin
9
+
10
+ app = Bottle()
11
+ plugin = LMDBPlugin("/path/to/db")
12
+ app.install(plugin)
13
+
14
+ @app.get("/write/<key>/<value>")
15
+ def write(key, value, db):
16
+ with db.begin(write=True) as txn:
17
+ txn.put(key.encode(), value.encode())
18
+ return "ok"
19
+
20
+ @app.get("/read/<key>")
21
+ def read(key, db):
22
+ with db.begin() as txn:
23
+ value = txn.get(key.encode())
24
+ return value.decode() if value else "not found"
25
+ ```
@@ -0,0 +1,25 @@
1
+ [project]
2
+ name = "bottle-lmdb"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Kimikazu Kato", email = "kimikazu@gmail.com" }
8
+ ]
9
+ requires-python = ">=3.10"
10
+ dependencies = [
11
+ "bottle>=0.12.25",
12
+ "lmdb>=3.0.0",
13
+ ]
14
+
15
+ [build-system]
16
+ requires = ["uv_build>=0.8.22,<0.9.0"]
17
+ build-backend = "uv_build"
18
+
19
+ [dependency-groups]
20
+ dev = [
21
+ "httpx>=0.28.1",
22
+ "mypy>=2.4.1",
23
+ "pytest>=9.2.0",
24
+ "tox-uv>=1.36.1",
25
+ ]
@@ -0,0 +1,3 @@
1
+ from .plugin import LMDBPlugin
2
+
3
+ __all__ = ["LMDBPlugin"]
@@ -0,0 +1,65 @@
1
+ import inspect
2
+ import typing
3
+ import lmdb
4
+
5
+
6
+ class LMDBPlugin:
7
+ name = "lmdb"
8
+ api = 2
9
+
10
+ def __init__(self, db_path: str, **kwargs) -> None:
11
+ """Initialize the plugin.
12
+
13
+ Args:
14
+ db_path: Path to the LMDB database directory.
15
+ **kwargs: Extra options forwarded to ``lmdb.Environment``.
16
+ The ``keyword`` option sets the route keyword argument
17
+ name used to inject the environment (default: ``"db"``).
18
+ """
19
+ self._db_path = db_path
20
+ self._kwargs = kwargs.copy()
21
+ self._env: None | lmdb.Environment = None
22
+ if "keyword" in kwargs:
23
+ keyword = self._kwargs["keyword"]
24
+ del self._kwargs["keyword"]
25
+ else:
26
+ keyword = "db"
27
+ self._keyword: str = keyword
28
+
29
+ @property
30
+ def env(self) -> lmdb.Environment:
31
+ """Return the LMDB environment, opening it lazily on first access.
32
+
33
+ Returns:
34
+ lmdb.Environment: The environment for ``db_path``.
35
+ """
36
+ # When a work process access this first time db is initialized
37
+ if self._env is None:
38
+ self._env = lmdb.Environment(self._db_path, **self._kwargs)
39
+ return self._env
40
+
41
+ def apply(self, callback: typing.Callable, route) -> typing.Callable:
42
+ """Wrap a route callback to inject the LMDB environment.
43
+
44
+ Args:
45
+ callback: The original route callback.
46
+ route: The Bottle route object (unused).
47
+
48
+ Returns:
49
+ A wrapper that passes the environment to the callback
50
+ via the configured keyword argument.
51
+ """
52
+ keyword = route.config.get("lmdb.keyword", self._keyword)
53
+
54
+ try:
55
+ args = inspect.signature(route.callback).parameters
56
+ except (TypeError, ValueError):
57
+ return callback
58
+ if keyword not in args:
59
+ return callback
60
+
61
+ def wrapper(*a, **ka):
62
+ ka[keyword] = self.env
63
+ return callback(*a, **ka)
64
+
65
+ return wrapper
File without changes