Initial commit
Some checks failed
CI/CD Pipeline / Code Quality & Linting (push) Has been cancelled
CI/CD Pipeline / Policy Validation (push) Has been cancelled
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-firm-connectors) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-forms) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-hmrc) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ingestion) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-normalize-map) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ocr) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-indexer) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-reason) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rpa) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (ui-review) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (ui-review) (push) Has been cancelled
CI/CD Pipeline / Generate SBOM (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Notifications (push) Has been cancelled
Some checks failed
CI/CD Pipeline / Code Quality & Linting (push) Has been cancelled
CI/CD Pipeline / Policy Validation (push) Has been cancelled
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-firm-connectors) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-forms) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-hmrc) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ingestion) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-normalize-map) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-ocr) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-indexer) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-reason) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (svc-rpa) (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (ui-review) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-coverage) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-extract) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-kg) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (svc-rag-retriever) (push) Has been cancelled
CI/CD Pipeline / Security Scanning (ui-review) (push) Has been cancelled
CI/CD Pipeline / Generate SBOM (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Notifications (push) Has been cancelled
This commit is contained in:
163
libs/events/examples/nats_example.py
Normal file
163
libs/events/examples/nats_example.py
Normal file
@@ -0,0 +1,163 @@
|
||||
"""Example usage of NATS.io event bus with JetStream."""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from libs.events import EventPayload, NATSEventBus, create_event_bus
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def example_handler(topic: str, payload: EventPayload) -> None:
|
||||
"""Example event handler."""
|
||||
logger.info(
|
||||
f"Received event on topic '{topic}': "
|
||||
f"ID={payload.event_id}, "
|
||||
f"Actor={payload.actor}, "
|
||||
f"Data={payload.data}"
|
||||
)
|
||||
|
||||
|
||||
async def main():
|
||||
"""Main example function."""
|
||||
# Method 1: Direct instantiation
|
||||
nats_bus = NATSEventBus(
|
||||
servers="nats://localhost:4222", # Can be a list for cluster
|
||||
stream_name="TAX_AGENT_EVENTS",
|
||||
consumer_group="tax-agent",
|
||||
)
|
||||
|
||||
# Method 2: Using factory
|
||||
# nats_bus = create_event_bus(
|
||||
# "nats",
|
||||
# servers="nats://localhost:4222",
|
||||
# stream_name="TAX_AGENT_EVENTS",
|
||||
# consumer_group="tax-agent",
|
||||
# )
|
||||
|
||||
try:
|
||||
# Start the event bus
|
||||
await nats_bus.start()
|
||||
logger.info("NATS event bus started")
|
||||
|
||||
# Subscribe to a topic
|
||||
await nats_bus.subscribe("user.created", example_handler)
|
||||
await nats_bus.subscribe("user.updated", example_handler)
|
||||
logger.info("Subscribed to topics")
|
||||
|
||||
# Publish some events
|
||||
for i in range(5):
|
||||
payload = EventPayload(
|
||||
data={"user_id": f"user-{i}", "name": f"User {i}"},
|
||||
actor="system",
|
||||
tenant_id="tenant-123",
|
||||
trace_id=f"trace-{i}",
|
||||
)
|
||||
|
||||
success = await nats_bus.publish("user.created", payload)
|
||||
if success:
|
||||
logger.info(f"Published event {i}")
|
||||
else:
|
||||
logger.error(f"Failed to publish event {i}")
|
||||
|
||||
# Wait a bit for messages to be processed
|
||||
await asyncio.sleep(2)
|
||||
|
||||
# Publish an update event
|
||||
update_payload = EventPayload(
|
||||
data={"user_id": "user-1", "name": "Updated User 1", "email": "user1@example.com"},
|
||||
actor="admin",
|
||||
tenant_id="tenant-123",
|
||||
)
|
||||
|
||||
await nats_bus.publish("user.updated", update_payload)
|
||||
logger.info("Published update event")
|
||||
|
||||
# Wait for processing
|
||||
await asyncio.sleep(2)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error in example: {e}")
|
||||
finally:
|
||||
# Stop the event bus
|
||||
await nats_bus.stop()
|
||||
logger.info("NATS event bus stopped")
|
||||
|
||||
|
||||
async def cluster_example():
|
||||
"""Example with NATS cluster configuration."""
|
||||
# Connect to a NATS cluster
|
||||
cluster_bus = NATSEventBus(
|
||||
servers=[
|
||||
"nats://nats1.example.com:4222",
|
||||
"nats://nats2.example.com:4222",
|
||||
"nats://nats3.example.com:4222",
|
||||
],
|
||||
stream_name="PRODUCTION_EVENTS",
|
||||
consumer_group="tax-agent-prod",
|
||||
)
|
||||
|
||||
try:
|
||||
await cluster_bus.start()
|
||||
logger.info("Connected to NATS cluster")
|
||||
|
||||
# Subscribe to multiple topics
|
||||
topics = ["document.uploaded", "document.processed", "tax.calculated"]
|
||||
for topic in topics:
|
||||
await cluster_bus.subscribe(topic, example_handler)
|
||||
|
||||
logger.info(f"Subscribed to {len(topics)} topics")
|
||||
|
||||
# Keep running for a while
|
||||
await asyncio.sleep(10)
|
||||
|
||||
finally:
|
||||
await cluster_bus.stop()
|
||||
|
||||
|
||||
async def error_handling_example():
|
||||
"""Example showing error handling."""
|
||||
|
||||
async def failing_handler(topic: str, payload: EventPayload) -> None:
|
||||
"""Handler that sometimes fails."""
|
||||
if payload.data.get("should_fail"):
|
||||
raise ValueError("Simulated handler failure")
|
||||
logger.info(f"Successfully processed event {payload.event_id}")
|
||||
|
||||
bus = NATSEventBus()
|
||||
|
||||
try:
|
||||
await bus.start()
|
||||
await bus.subscribe("test.events", failing_handler)
|
||||
|
||||
# Publish a good event
|
||||
good_payload = EventPayload(
|
||||
data={"message": "This will succeed"},
|
||||
actor="test",
|
||||
tenant_id="test-tenant",
|
||||
)
|
||||
await bus.publish("test.events", good_payload)
|
||||
|
||||
# Publish a bad event
|
||||
bad_payload = EventPayload(
|
||||
data={"message": "This will fail", "should_fail": True},
|
||||
actor="test",
|
||||
tenant_id="test-tenant",
|
||||
)
|
||||
await bus.publish("test.events", bad_payload)
|
||||
|
||||
await asyncio.sleep(2)
|
||||
|
||||
finally:
|
||||
await bus.stop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run the basic example
|
||||
asyncio.run(main())
|
||||
|
||||
# Uncomment to run other examples:
|
||||
# asyncio.run(cluster_example())
|
||||
# asyncio.run(error_handling_example())
|
||||
Reference in New Issue
Block a user