Message bus integration for HAI
Project description
H Message Bus
A message bus integration for HAI applications based on NATS.io
Overview
H Message Bus provides a robust, asynchronous messaging infrastructure built on NATS.io for HAI applications. It enables seamless communication between components through a publish-subscribe pattern, supporting both fire-and-forget messaging and request-response patterns.
Features
- Asynchronous Communication: Built for modern, non-blocking I/O operations
- Flexible Message Routing: Publish and subscribe to specific topics
- High Reliability: Automatic reconnection handling and configurable timeouts
- Simple API: Focus on core messaging functionality with minimal dependencies
Installation
pip install h_message_bus
Requirements
- Python 3.10+
- NATS.io server (can be run via Docker)
Topics
H Message Bus includes predefined topics following the convention: hai.[source].[destination].[action]
Available topics:
| Topic Constant | Topic String | Description |
|---|---|---|
Topic.AI_SEND_TG_CHAT_MESSAGE |
hai.ai.tg.chat.send |
AI sending message to Telegram chat |
Topic.AI_VECTORS_SAVE |
hai.ai.vectors.save |
AI saving data to vector database |
Topic.AI_VECTORS_QUERY |
hai.ai.vectors.query |
AI querying vector database |
Topic.TG_SEND_AI_CHAT_MESSAGE |
hai.tg.ai.chat.send |
Telegram sending message to AI |
You can use these predefined topics or create your own topic strings.
Quick Start
Start a NATS Server
The easiest way to get started is with Docker:
docker-compose up -d
Create a Publisher
import asyncio
import uuid
from h_message_bus import NatsConfig, NatsPublisherAdapter, HaiMessage, Topic
async def main():
# Configure NATS connection
config = NatsConfig(server="nats://localhost:4222")
# Create publisher adapter
publisher = NatsPublisherAdapter(config)
# Connect to NATS
await publisher.connect()
# Create and publish a message using a predefined topic
message = HaiMessage(
message_id=str(uuid.uuid4()),
sender="service-a",
topic=Topic.TG_SEND_AI_CHAT_MESSAGE,
payload={"text": "Hello AI, this is a message from Telegram", "chat_id": 12345}
)
# Publish message
await publisher.publish(message)
# Clean up
await publisher.close()
if __name__ == "__main__":
asyncio.run(main())
Create a Subscriber
import asyncio
from h_message_bus import NatsConfig, NatsSubscriberAdapter, HaiMessage, Topic
async def message_handler(message: HaiMessage):
print(f"Received message: {message.message_id}")
print(f"From: {message.sender}")
print(f"Topic: {message.topic}")
print(f"Payload: {message.payload}")
async def main():
# Configure NATS connection
config = NatsConfig(server="nats://localhost:4222")
# Create subscriber
subscriber = NatsSubscriberAdapter(config)
# Connect to NATS
await subscriber.connect()
# Subscribe to a topic
await subscriber.subscribe(Topic.TG_SEND_AI_CHAT_MESSAGE, message_handler)
# Keep the application running
try:
print("Subscriber running. Press Ctrl+C to exit.")
while True:
await asyncio.sleep(1)
except KeyboardInterrupt:
# Clean up
await subscriber.close()
if __name__ == "__main__":
asyncio.run(main())
Advanced Usage
Request-Response Pattern
import asyncio
import uuid
from h_message_bus import NatsConfig, NatsPublisherAdapter, HaiMessage, Topic
async def main():
config = NatsConfig(server="nats://localhost:4222")
publisher = NatsPublisherAdapter(config)
# Connect to NATS
await publisher.connect()
request_message = HaiMessage(
message_id=str(uuid.uuid4()),
sender="client-service",
topic=Topic.AI_VECTORS_QUERY,
payload={"query": "find similar documents", "limit": 10}
)
# Send request and wait for response (with timeout)
response = await publisher.request(request_message, timeout=5.0)
if response:
print(f"Received response: {response.payload}")
else:
print("Request timed out")
await publisher.close()
if __name__ == "__main__":
asyncio.run(main())
Creating a Service with Request Handler
import asyncio
import uuid
from h_message_bus import NatsConfig, NatsSubscriberAdapter, NatsPublisherAdapter, HaiMessage, Topic
async def request_handler(request: HaiMessage):
print(f"Received request: {request.message_id}")
print(f"Payload: {request.payload}")
# Process the request
result = {"status": "success", "data": {"result": 42}}
# Create a response message
return HaiMessage(
message_id=str(uuid.uuid4()),
sender="service-b",
topic=f"{request.topic}.response",
payload=result,
correlation_id=request.message_id
)
async def main():
# Configure NATS connection
config = NatsConfig(server="nats://localhost:4222")
# Create subscriber for handling requests
subscriber = NatsSubscriberAdapter(config)
publisher = NatsPublisherAdapter(config)
# Connect to NATS
await subscriber.connect()
await publisher.connect()
# Register request handler for vector database queries
await subscriber.subscribe_with_response(Topic.AI_VECTORS_QUERY, request_handler, publisher)
# Keep the application running
try:
print("Service running. Press Ctrl+C to exit.")
while True:
await asyncio.sleep(1)
except KeyboardInterrupt:
# Clean up
await subscriber.close()
await publisher.close()
if __name__ == "__main__":
asyncio.run(main())
Configuration Options
The NatsConfig class allows you to customize your NATS connection:
| Parameter | Description | Default |
|---|---|---|
server |
NATS server address | Required |
max_reconnect_attempts |
Maximum reconnection attempts | 10 |
reconnect_time_wait |
Time between reconnection attempts (seconds) | 2 |
connection_timeout |
Connection timeout (seconds) | 2 |
ping_interval |
Interval for ping frames (seconds) | 20 |
max_outstanding_pings |
Maximum unanswered pings before disconnect | 5 |
max_payload |
Maximum size of the payload in bytes | 1048576 (1MB) |
API Reference
Exported Classes
The following classes are exported directly from the package:
NatsConfig- Configuration for the NATS connectionHaiMessage- Message structure for HAI communicationNatsPublisherAdapter- Adapter for publishing messagesNatsSubscriberAdapter- Adapter for subscribing to messagesMessageProcessor- Processing incoming messagesNatsClientRepository- Low-level NATS client operationsTopic- Enumeration of predefined topic strings
HaiMessage Structure
The HaiMessage class is the core data structure used for all messaging:
class HaiMessage:
message_id: str # Unique identifier for the message
sender: str # Identifier of the sender
topic: str # The topic or channel for the message
payload: dict # Actual message data
correlation_id: str = None # Optional reference to a related message
timestamp: float = None # Optional message creation timestamp
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
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 Distribution
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 h_message_bus-0.0.38.tar.gz.
File metadata
- Download URL: h_message_bus-0.0.38.tar.gz
- Upload date:
- Size: 24.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a88c9ac19f7086362e2ffa1c32dbf3d284d64463c002ab1912895d14d0b9338a
|
|
| MD5 |
a09a7bd1b22724ec887665c4ff1eb52b
|
|
| BLAKE2b-256 |
b559fe3fa38ecacee7ae499e3c66421072f9a6128fd279b6a07754712bde7d02
|
File details
Details for the file h_message_bus-0.0.38-py3-none-any.whl.
File metadata
- Download URL: h_message_bus-0.0.38-py3-none-any.whl
- Upload date:
- Size: 58.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
708977d06f27fdda4a53892fc29d6e6cda3a9a6229c02c51f3406035a4e138ac
|
|
| MD5 |
a2b4239f90b813c4bce8785a4ea3d661
|
|
| BLAKE2b-256 |
703f1a40902e03da9bb4f5775d63f56479f2b10ac4e027ee48a0e8cf2fc63c37
|