Python bindings for tokio-memq
Project description
tokio-memq-python
tokio-memq-python is a high-performance, asynchronous in-memory message queue library for Python, powered by the robust Rust tokio-memq crate.
It bridges the gap between Python's ease of use and Rust's performance, providing a seamless asyncio interface for building high-throughput, low-latency messaging applications. Whether you are building a local event bus, a job queue, or a high-speed data pipeline, tokio-memq-python offers the speed and reliability you need.
Features
- 🚀 High Performance: Built on Rust's Tokio runtime, offering exceptional throughput and low latency.
- ⚡ Async/Await Native: Fully integrated with Python's
asynciofor non-blocking I/O. Supportsasync forloops. - � Consumer Groups: Built-in support for competing consumers pattern with automatic load balancing.
- � Partition Support: Scale horizontally with built-in partitioned topics and flexible routing strategies (RoundRobin, Hash, Random, Fixed).
- 🛠 Type Safety: Leverages Rust's strong type system to ensure stability and correctness.
- 🔧 Cross-Platform: Pre-compiled wheels available for Linux, Windows, and macOS (Intel & Apple Silicon).
- ⚙️ Configurable: Fine-tune queue depth, message TTL (Time-To-Live), and eviction policies (LRU).
� Use Cases
- High-Performance Event Bus: Decouple components in your Python application with minimal latency overhead.
- Async Job Processing: Efficiently distribute tasks to worker coroutines or threads using consumer groups.
- Data Streaming Pipelines: Handle high-velocity data ingestion and processing with backpressure support.
- Local Microservices Communication: Fast inter-process-like communication within a single application instance.
- Testing & Simulation: Simulate complex distributed messaging scenarios (like Kafka/RabbitMQ) locally without infrastructure overhead.
�📊 Benchmarks
Environment:
- OS: macOS
- Device: Apple M4 (24GB RAM)
- Python: 3.12
Results (Run with python3 examples/benchmark.py --count 10000):
| Scenario | Metric | Result | Resource Usage (Avg CPU / Peak Mem) |
|---|---|---|---|
| Latency (1 Pub → 1 Sub) | Avg Latency | 120.17 µs | N/A |
| P99 Latency | 174.55 µs | ||
| Throughput (1 Pub → 1 Sub) | Publish Rate | 12,883 msg/s | 148% / 37 MB |
| Consume Rate | 12,882 msg/s | ||
| Fan-Out (1 Pub → 5 Sub) | Publish Rate | 6,647 msg/s | 216% / 40 MB |
| Total Consume Rate | 28,306 msg/s | ||
| Fan-In (5 Pub → 1 Sub) | Publish Rate | 32,974 msg/s | 143% / 44 MB |
| Consume Rate | 13,662 msg/s |
Note: Benchmarks include Python object serialization overhead. Raw Rust performance is significantly higher. Resource usage reflects the Python process overhead.
Installation
pip install tokio-memq-python
Requires Python 3.8 or later.
Examples
1. Basic Publish-Subscribe
A simple example demonstrating how to create a queue, publish messages, and consume them asynchronously.
import asyncio
from tokio_memq import MessageQueue
async def main():
# Initialize the Message Queue
mq = MessageQueue()
# Create a publisher for "notifications"
publisher = mq.publisher("notifications")
# Create a subscriber for the same topic
# This automatically creates the topic if it doesn't exist
subscriber = await mq.subscriber("notifications")
# Publish messages (any JSON-serializable data)
await publisher.send({"type": "email", "to": "user@example.com"})
await publisher.send({"type": "sms", "to": "+1234567890"})
# Process messages using async iterator
async for msg in subscriber:
print(f"Processed notification: {msg}")
# For this example, break after 2 messages
if msg["type"] == "sms":
break
if __name__ == "__main__":
asyncio.run(main())
2. Consumer Groups (Load Balancing)
Multiple consumers can join a group to share the workload. Messages are distributed among active consumers.
import asyncio
from tokio_memq import MessageQueue
async def worker(mq, topic, group_id, name):
# Join a consumer group with "Earliest" mode to get existing messages
sub = await mq.subscriber_group(topic, group_id, mode="Earliest")
print(f"[{name}] Joined group '{group_id}' (ID: {sub.consumer_id})")
async for msg in sub:
print(f"[{name}] Processing: {msg}")
async def main():
mq = MessageQueue()
topic = "jobs"
group = "workers"
# Start two workers
w1 = asyncio.create_task(worker(mq, topic, group, "Worker-1"))
w2 = asyncio.create_task(worker(mq, topic, group, "Worker-2"))
# Publish tasks
pub = mq.publisher(topic)
for i in range(10):
await pub.send({"task_id": i})
# Keep running...
if __name__ == "__main__":
asyncio.run(main())
3. Partitioned Topics with Hash Routing
This example shows how to use partitioned topics to distribute load while ensuring message ordering for specific keys (e.g., user IDs).
import asyncio
from tokio_memq import MessageQueue
async def main():
mq = MessageQueue()
topic = "user_activity"
# Create a topic with 4 partitions for parallel processing
await mq.create_partitioned_topic(topic, partition_count=4)
# Configure "Hash" routing: messages with the same key go to the same partition
await mq.set_partition_routing(topic, "Hash", key="message")
pub = mq.publisher(topic)
# Simulate user events
# Events for 'user_123' will always land in the same partition
await pub.send({"event": "login"}, key="user_123")
await pub.send({"event": "view_item"}, key="user_123")
# Events for 'user_456' will land in a different partition (likely)
await pub.send({"event": "logout"}, key="user_456")
# Consume from a specific partition (e.g., Partition 0)
# Use mode="Earliest" to ensure we get messages published before we subscribed
sub_p0 = await mq.subscribe_partition(topic, 0, mode="Earliest")
print("Listening on Partition 0...")
try:
msg = await asyncio.wait_for(sub_p0.recv(), timeout=1.0)
print(f"Partition 0 received: {msg}")
except asyncio.TimeoutError:
print("No messages on Partition 0 for this run.")
if __name__ == "__main__":
asyncio.run(main())
4. Advanced Configuration (TTL & Queue Limits)
Control memory usage and message lifecycle using TopicOptions.
import asyncio
from tokio_memq import MessageQueue, TopicOptions
async def main():
mq = MessageQueue()
# Configure topic options
opts = TopicOptions()
opts.max_messages = 100 # Limit queue to 100 messages
opts.message_ttl_ms = 5000 # Messages expire after 5 seconds
opts.lru_enabled = True # Drop oldest messages when full
# Create subscriber with custom options
sub = await mq.subscriber_with_options("fast_logs", opts)
pub = mq.publisher("fast_logs")
# Publish a message
await pub.send("This message will self-destruct in 5s")
msg = await sub.recv()
print(f"Got: {msg}")
if __name__ == "__main__":
asyncio.run(main())
More Examples
Check the examples/ directory for ready-to-run scripts:
- basic_usage.py: Complete pub/sub workflow.
- consumer_group.py: Load balancing with consumer groups.
- async_iteration.py: Pythonic usage with
async forandsend(). - partitioned_topic.py: Working with partitions and Hash routing.
- advanced_config.py: Using TTL and LRU eviction.
- performance_test.py: Simple throughput benchmark.
- benchmark.py: Comprehensive latency and throughput scenarios.
API Reference
MessageQueue
The central manager for topics, publishers, and subscribers.
publisher(topic: str) -> Publisher: Get a publisher for a topic.subscriber(topic: str) -> Subscriber: Subscribe to a topic (auto-creates it).subscriber_with_options(topic: str, options: TopicOptions) -> Subscriber: Subscribe with specific configuration.subscriber_group(topic: str, consumer_id: str, mode: str = "LastOffset", offset: int = None) -> Subscriber: Join a consumer group.consumer_id: Unique ID for the consumer group member.mode:"Earliest","Latest","LastOffset", or"Offset".
create_partitioned_topic(topic: str, partition_count: int, options: TopicOptions = None): Create a topic withnpartitions.set_partition_routing(topic: str, strategy: str, key: str = None, fixed_id: int = None): Set routing logic.strategy:"RoundRobin","Random","Hash","Fixed".key: Required for"Hash"routing (e.g.,"message").fixed_id: Required for"Fixed"routing (target partition ID).
subscribe_partition(topic: str, partition_id: int, consumer_id: str = None, mode: str = "LastOffset", offset: int = None) -> Subscriber: Listen to a specific partition.list_partitioned_topics() -> List[str]: List active partitioned topics.delete_partitioned_topic(topic: str): Delete a topic.
Publisher
send(data: Any, key: str = None): Send a message (alias forpublish).data: JSON-serializable payload (dict, list, str, int, etc.).key: Routing key (used only if topic is partitioned with Hash routing).
publish(data: Any, key: str = None): Send a message.topic() -> str: Get the topic name.
Subscriber
recv() -> Any: Await the next message. Raises exception if connection is lost.try_recv() -> Any | None: Non-blocking receive. ReturnsNoneif no message available.current_offset() -> int: Get current offset.reset_offset(): Reset offset to 0.consumer_id -> str | None: (Property) Get the consumer ID if applicable.topic -> str: (Property) Get the topic name.- Async Iterator: Supports
async for msg in subscriber:syntax.
TopicOptions
max_messages(int): Max messages per topic/partition.message_ttl_ms(int): Message lifetime in milliseconds.lru_enabled(bool): If True, drops oldest message when full; otherwise rejects new messages.partitions(int): (Read-only) Number of partitions if applicable.
License
This project is licensed under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tokio_memq_python-0.1.3.tar.gz.
File metadata
- Download URL: tokio_memq_python-0.1.3.tar.gz
- Upload date:
- Size: 26.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6085303b3797226a7ea428e26c1cf31af42f06c4520139b6edbd131c2ec942d7
|
|
| MD5 |
2540168d411ab2a9058c4a4fcbc1190d
|
|
| BLAKE2b-256 |
a9b7ab924cdf4f19627e842bc7f180249b333d3b16c3dda775ab0649b4db1153
|
File details
Details for the file tokio_memq_python-0.1.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.4 MB
- Tags: PyPy, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e67e885bbdc316ab49b6e867009746acfe1f733dd19619510a850aed831f628d
|
|
| MD5 |
c32b6b78d99a29b97f2f174874375bbf
|
|
| BLAKE2b-256 |
8c2aa400644593dc95048ba1f7e9151746a5d92d0efd3416378844098bc460ed
|
File details
Details for the file tokio_memq_python-0.1.3-pp311-pypy311_pp73-manylinux_2_17_i686.manylinux2014_i686.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-pp311-pypy311_pp73-manylinux_2_17_i686.manylinux2014_i686.whl
- Upload date:
- Size: 1.5 MB
- Tags: PyPy, manylinux: glibc 2.17+ i686
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbd5f6cfec576b12b163d29f1e2aef7d8b94251532e7ac5d3f33272347b83b1e
|
|
| MD5 |
695333c55ebc4a84f827891d61ea6240
|
|
| BLAKE2b-256 |
f97331d990f7eb04e5272e282bc01ad1d43a5059bfe840eee75387099c6f2783
|
File details
Details for the file tokio_memq_python-0.1.3-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6095021d561479270e9c413dfc13a33f3ffe24ba548db3f3a7eb17aaccd799da
|
|
| MD5 |
8c69c7facd37b5743d82a167734937c9
|
|
| BLAKE2b-256 |
f428224a39c35eaddede23d080727d9735489aada3d5a72e4c9ec5e0229004a1
|
File details
Details for the file tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b188280f763a534b0f3c748068649aa3e963e071e0dcb4e9af769260f8d43ba0
|
|
| MD5 |
0a8b1bc2a58dab67bce220bfc0c4c2b7
|
|
| BLAKE2b-256 |
40c38b5ac6eff71b0cac0e9fa3240fa19ea7e01106ad55232e10ec9926fe5537
|
File details
Details for the file tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ s390x
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29302770ab5acfe73274675c68946718c4726d0164a6a315e0a646e20a42ccac
|
|
| MD5 |
a6c24eae5a79603ae8833a2ae9229d5d
|
|
| BLAKE2b-256 |
84fb867614b0cb76c5cdd907d3264691ea9a2a92552f68e6f01850cfe12d483c
|
File details
Details for the file tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ ppc64le
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9302fda4f65bd567f8542a54653ea923334dd4d85fb3ba7d47f96ebb143b9341
|
|
| MD5 |
64b34f529ff2423d311f2f9336d118e0
|
|
| BLAKE2b-256 |
3ce0b3f25fc9090df4ccb7af02c6155a6c84194c3c146ced4b116db9465964cc
|
File details
Details for the file tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_i686.manylinux2014_i686.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_i686.manylinux2014_i686.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ i686
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1babfa61d96d2e690de138748157501f3f43d086b972abb3e336eb06753b6515
|
|
| MD5 |
362ba21b0b9fc78aa5158345a6dc9653
|
|
| BLAKE2b-256 |
06b5489e8e6532f9024aaa3df1aa607cf0e7e2d1646a72c1eff807bb15cc8c53
|
File details
Details for the file tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
- Upload date:
- Size: 1.3 MB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ ARMv7l
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2ae8564dae95f96785142dc036866d847f26d70bb8913faa36b5ebda18ad027
|
|
| MD5 |
7cb4432dd71c5d6eefada100cc651971
|
|
| BLAKE2b-256 |
9c61754672cc8393cfd241dc245d7ffd68eed177b35c43afa507292d39706178
|
File details
Details for the file tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2f2d1d1a375a25f6fe8bd8848c03d0e7bb34e43202cac3a5f6aba7c15d49c2c
|
|
| MD5 |
e6eef99292e64c11a88b71fd9333f9da
|
|
| BLAKE2b-256 |
f79d2779f8bc0a8c5b0e282510632cc14229732c04e311ff545a5fe0f0eab00e
|
File details
Details for the file tokio_memq_python-0.1.3-cp38-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-cp38-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.2 MB
- Tags: CPython 3.8+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a4ef7606c0bc0c54cd55b6a11bc0af2c9dc1387f3619c0e44e19434a0b7664a3
|
|
| MD5 |
70c8978a30b5424e5cf937db5dcedf1c
|
|
| BLAKE2b-256 |
df35c81b6875d93dc24a71ab869bdb089c65cc349f9b2c901f254e6f54cebd4b
|
File details
Details for the file tokio_memq_python-0.1.3-cp38-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: tokio_memq_python-0.1.3-cp38-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.3 MB
- Tags: CPython 3.8+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c8167339b77a580f6038995ee1e90cef599a2e2cab9027bf0502a3d1ca39c87
|
|
| MD5 |
63785825b40edfed8af864f3a8a37c86
|
|
| BLAKE2b-256 |
b59eec94fd19402909869ceb4c1e177a11e2f18fabd49e0603d91a32f1f6ddd0
|