beaver-db 0.9.0__py3-none-any.whl → 0.9.2__py3-none-any.whl

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.

Potentially problematic release.


This version of beaver-db might be problematic. Click here for more details.

beaver/channels.py CHANGED
@@ -1,14 +1,44 @@
1
+ import asyncio
1
2
  import json
2
3
  import sqlite3
3
4
  import threading
4
5
  import time
5
6
  from queue import Empty, Queue
6
- from typing import Any, Iterator, Set
7
+ from typing import Any, AsyncIterator, Iterator, Set
7
8
 
8
9
  # A special message object used to signal the listener to gracefully shut down.
9
10
  _SHUTDOWN_SENTINEL = object()
10
11
 
11
12
 
13
+ class AsyncSubscriber:
14
+ """A thread-safe async message receiver for a specific channel subscription."""
15
+
16
+ def __init__(self, subscriber: "Subscriber"):
17
+ self._subscriber = subscriber
18
+
19
+ async def __aenter__(self) -> "AsyncSubscriber":
20
+ """Registers the listener's queue with the channel to start receiving messages."""
21
+ await asyncio.to_thread(self._subscriber.__enter__)
22
+ return self
23
+
24
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
25
+ """Unregisters the listener's queue from the channel to stop receiving messages."""
26
+ await asyncio.to_thread(self._subscriber.__exit__, exc_type, exc_val, exc_tb)
27
+
28
+ async def listen(self, timeout: float | None = None) -> AsyncIterator[Any]:
29
+ """
30
+ Returns a blocking async iterator that yields messages as they arrive.
31
+ """
32
+ while True:
33
+ try:
34
+ msg = await asyncio.to_thread(self._subscriber._queue.get, timeout=timeout)
35
+ if msg is _SHUTDOWN_SENTINEL:
36
+ break
37
+ yield msg
38
+ except Empty:
39
+ raise TimeoutError(f"Timeout {timeout}s expired.")
40
+
41
+
12
42
  class Subscriber:
13
43
  """
14
44
  A thread-safe message receiver for a specific channel subscription.
@@ -54,6 +84,27 @@ class Subscriber:
54
84
  except Empty:
55
85
  raise TimeoutError(f"Timeout {timeout}s expired.")
56
86
 
87
+ def as_async(self) -> "AsyncSubscriber":
88
+ """Returns an async version of the subscriber."""
89
+ return AsyncSubscriber(self)
90
+
91
+
92
+ class AsyncChannelManager:
93
+ """The central async hub for a named pub/sub channel."""
94
+
95
+ def __init__(self, channel: "ChannelManager"):
96
+ self._channel = channel
97
+
98
+ async def publish(self, payload: Any):
99
+ """
100
+ Publishes a JSON-serializable message to the channel asynchronously.
101
+ """
102
+ await asyncio.to_thread(self._channel.publish, payload)
103
+
104
+ def subscribe(self) -> "AsyncSubscriber":
105
+ """Creates a new async subscription, returning an AsyncSubscriber context manager."""
106
+ return self._channel.subscribe().as_async()
107
+
57
108
 
58
109
  class ChannelManager:
59
110
  """
@@ -183,3 +234,7 @@ class ChannelManager:
183
234
  "INSERT INTO beaver_pubsub_log (timestamp, channel_name, message_payload) VALUES (?, ?, ?)",
184
235
  (time.time(), self._name, json_payload),
185
236
  )
237
+
238
+ def as_async(self) -> "AsyncChannelManager":
239
+ """Returns an async version of the channel manager."""
240
+ return AsyncChannelManager(self)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beaver-db
3
- Version: 0.9.0
3
+ Version: 0.9.2
4
4
  Summary: Fast, embedded, and multi-modal DB based on SQLite for AI-powered applications.
5
5
  Requires-Python: >=3.13
6
6
  Description-Content-Type: text/markdown
@@ -9,10 +9,6 @@ Requires-Dist: numpy>=2.3.3
9
9
  Requires-Dist: scipy>=1.16.2
10
10
  Dynamic: license-file
11
11
 
12
- I've updated the README to highlight the new high-efficiency, thread-safe, and process-safe pub/sub system. I've also added an example of how you can use it to build real-time, event-driven applications.
13
-
14
- Here are the changes:
15
-
16
12
  # beaver 🦫
17
13
 
18
14
  A fast, single-file, multi-modal database for Python, built with the standard `sqlite3` library.
@@ -31,7 +27,7 @@ A fast, single-file, multi-modal database for Python, built with the standard `s
31
27
 
32
28
  ## Core Features
33
29
 
34
- - **High-Efficiency Pub/Sub**: A powerful, thread and process-safe publish-subscribe system for real-time messaging with a fan-out architecture.
30
+ - **Sync/Async High-Efficiency Pub/Sub**: A powerful, thread and process-safe publish-subscribe system for real-time messaging with a fan-out architecture. Sync by default, but with an `as_async` wrapper for async applications.
35
31
  - **Namespaced Key-Value Dictionaries**: A Pythonic, dictionary-like interface for storing any JSON-serializable object within separate namespaces with optional TTL for cache implementations.
36
32
  - **Pythonic List Management**: A fluent, Redis-like interface for managing persistent, ordered lists.
37
33
  - **Persistent Priority Queue**: A high-performance, persistent queue that always returns the item with the highest priority, perfect for task management.
@@ -194,6 +190,7 @@ For more in-depth examples, check out the scripts in the `examples/` directory:
194
190
  - [`examples/fts.py`](examples/fts.py): A detailed look at full-text search, including targeted searches on specific metadata fields.
195
191
  - [`examples/graph.py`](examples/graph.py): Shows how to create relationships between documents and perform multi-hop graph traversals.
196
192
  - [`examples/pubsub.py`](examples/pubsub.py): A demonstration of the synchronous, thread-safe publish/subscribe system in a single process.
193
+ - [`examples/async_pubsub.py`](examples/async_pubsub.py): A demonstration of the asynchronous wrapper for the publish/subscribe system.
197
194
  - [`examples/publisher.py`](examples/publisher.py) and [`examples/subscriber.py`](examples/subscriber.py): A pair of examples demonstrating inter-process message passing with the publish/subscribe system.
198
195
  - [`examples/cache.py`](examples/cache.py): A practical example of using a dictionary with TTL as a cache for API calls.
199
196
  - [`examples/rerank.py`](examples/rerank.py): Shows how to combine results from vector and text search for more refined results.
@@ -1,12 +1,12 @@
1
1
  beaver/__init__.py,sha256=-z5Gj6YKMOswpJOOn5Gej8z5i6k3c0Xs00DIYLA-bMI,75
2
- beaver/channels.py,sha256=6Fr6uyp_1TtVzNzQobgCa_-c8KS285Z2fyC7OzUOd34,6611
2
+ beaver/channels.py,sha256=jKL1sVLOe_Q_pP0q1-iceZbPe8FOi0EwqJtOMOe96f4,8675
3
3
  beaver/collections.py,sha256=R4bVmP37s_ZnCkb3Jdck2H8dRvD3-ihFV4mEsA14YeE,15716
4
4
  beaver/core.py,sha256=l5hI55vc2VlF1b_a6CP7ZP5r7H-MQdTNV4zr2lSumcs,7864
5
5
  beaver/dicts.py,sha256=y4z632XKWU29ekP_vdFSOP-MAG9Z8b79kBEHA88gO7E,4463
6
6
  beaver/lists.py,sha256=jFlDWwyaYycG0ZFVm58rMChefUaVZhaP1UeQ-hVo3Sg,9082
7
7
  beaver/queues.py,sha256=WKpBzlXr9Hp_rOKEs_Y1Tjyj_hWx6ql1uBRKBV7rw8w,2780
8
- beaver_db-0.9.0.dist-info/licenses/LICENSE,sha256=1xrIY5JnMk_QDQzsqmVzPIIyCgZAkWCC8kF2Ddo1UT0,1071
9
- beaver_db-0.9.0.dist-info/METADATA,sha256=Fd_Qvcs5a_wbCVMCvfmxOXAKBX4FbtQKJwrWwFAxjrE,9732
10
- beaver_db-0.9.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
- beaver_db-0.9.0.dist-info/top_level.txt,sha256=FxA4XnX5Qm5VudEXCduFriqi4dQmDWpQ64d7g69VQKI,7
12
- beaver_db-0.9.0.dist-info/RECORD,,
8
+ beaver_db-0.9.2.dist-info/licenses/LICENSE,sha256=1xrIY5JnMk_QDQzsqmVzPIIyCgZAkWCC8kF2Ddo1UT0,1071
9
+ beaver_db-0.9.2.dist-info/METADATA,sha256=vUT6BRbtpQ-lY_FatTiNx2z8ZaxDwOepFPuhF-NRHvA,9725
10
+ beaver_db-0.9.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ beaver_db-0.9.2.dist-info/top_level.txt,sha256=FxA4XnX5Qm5VudEXCduFriqi4dQmDWpQ64d7g69VQKI,7
12
+ beaver_db-0.9.2.dist-info/RECORD,,