Files
boc/iom/api/event_bus.py
T
Bernt bae705aa97 ARCHITECTURE: NFC roadmap, edge AI, audit logging
- Add NFC ePassport roadmap (ICAO 9303, eIDAS)
- Add TensorFlow.js edge face detection (BlazeFace)
- Add structured audit logger (GDPR-compliant)
- Risk scoring support

Part of KYC Apple Native UX v1.1.0
2026-06-29 16:24:48 +00:00

151 lines
4.7 KiB
Python

"""
Event Bus for async communication between services
"""
from typing import Dict, List, Callable, Any
from dataclasses import dataclass
from datetime import datetime
from enum import Enum
import asyncio
import json
class EventType(str, Enum):
"""Event types"""
OBSERVATION_CREATED = "observation.created"
OBSERVATION_UPDATED = "observation.updated"
SIGNAL_GENERATED = "signal.generated"
DECISION_MADE = "decision.made"
OUTCOME_RECORDED = "outcome.recorded"
INTERVENTION_STARTED = "intervention.started"
INTERVENTION_COMPLETED = "intervention.completed"
MODEL_UPDATED = "model.updated"
PLATFORM_CHANGE = "platform.change"
SYNC_COMPLETED = "sync.completed"
ALERT_TRIGGERED = "alert.triggered"
@dataclass
class Event:
"""Platform event"""
event_id: str
event_type: EventType
payload: Dict[str, Any]
timestamp: str
source: str
correlation_id: Optional[str] = None
def to_dict(self) -> Dict:
return {
"event_id": self.event_id,
"event_type": self.event_type.value,
"payload": self.payload,
"timestamp": self.timestamp,
"source": self.source,
"correlation_id": self.correlation_id
}
class EventBus:
"""Event bus for async communication"""
def __init__(self):
self.subscribers: Dict[EventType, List[Callable]] = {}
self.event_history: List[Event] = []
self.max_history = 10000
def subscribe(self, event_type: EventType, handler: Callable):
"""Subscribe to an event type"""
if event_type not in self.subscribers:
self.subscribers[event_type] = []
self.subscribers[event_type].append(handler)
def unsubscribe(self, event_type: EventType, handler: Callable):
"""Unsubscribe from an event type"""
if event_type in self.subscribers:
if handler in self.subscribers[event_type]:
self.subscribers[event_type].remove(handler)
async def publish(self, event: Event):
"""Publish an event"""
# Store in history
self.event_history.append(event)
if len(self.event_history) > self.max_history:
self.event_history = self.event_history[-self.max_history:]
# Notify subscribers
handlers = self.subscribers.get(event.event_type, [])
# Run handlers concurrently
if handlers:
await asyncio.gather(
*[self._run_handler(handler, event) for handler in handlers],
return_exceptions=True
)
async def _run_handler(self, handler: Callable, event: Event):
"""Run a handler with error handling"""
try:
if asyncio.iscoroutinefunction(handler):
await handler(event)
else:
handler(event)
except Exception as e:
print(f"Event handler error: {e}")
def get_events(self, event_type: Optional[EventType] = None, limit: int = 100) -> List[Dict]:
"""Get recent events"""
events = self.event_history
if event_type:
events = [e for e in events if e.event_type == event_type]
return [e.to_dict() for e in events[-limit:]]
def get_stats(self) -> Dict:
"""Get event bus statistics"""
return {
"total_events": len(self.event_history),
"subscribers": {
event_type.value: len(handlers)
for event_type, handlers in self.subscribers.items()
},
"event_types": list(set(e.event_type.value for e in self.event_history))
}
# Global event bus
event_bus = EventBus()
# Example event handlers
async def on_observation_created(event: Event):
"""Handle observation created event"""
print(f"New observation: {event.payload.get('observation_id')}")
# Trigger signal generation
# Trigger sync to targets
# Update global model
async def on_decision_made(event: Event):
"""Handle decision made event"""
print(f"New decision: {event.payload.get('decision_type')}")
# Notify stakeholders
# Update decision knowledge
# Trigger autonomous actions if enabled
async def on_outcome_recorded(event: Event):
"""Handle outcome recorded event"""
print(f"New outcome: {event.payload.get('intervention_id')}")
# Update evidence engine
# Update global model
# Generate insights
# Broadcast to connected clients
# Register handlers
event_bus.subscribe(EventType.OBSERVATION_CREATED, on_observation_created)
event_bus.subscribe(EventType.DECISION_MADE, on_decision_made)
event_bus.subscribe(EventType.OUTCOME_RECORDED, on_outcome_recorded)