Files
bakery-ia/services/training/app/services/messaging.py
2025-07-19 16:59:37 +02:00

219 lines
7.5 KiB
Python

# services/training/app/services/messaging.py
"""
Training service messaging - Clean interface for training-specific events
Uses shared RabbitMQ infrastructure
"""
import structlog
from typing import Dict, Any, Optional
from shared.messaging.rabbitmq import RabbitMQClient
from shared.messaging.events import (
TrainingStartedEvent,
TrainingCompletedEvent,
TrainingFailedEvent
)
from app.core.config import settings
logger = structlog.get_logger()
# Single global instance
training_publisher = RabbitMQClient(settings.RABBITMQ_URL, "training-service")
async def setup_messaging():
"""Initialize messaging for training service"""
success = await training_publisher.connect()
if success:
logger.info("Training service messaging initialized")
else:
logger.warning("Training service messaging failed to initialize")
async def cleanup_messaging():
"""Cleanup messaging for training service"""
await training_publisher.disconnect()
logger.info("Training service messaging cleaned up")
# Training Job Events
async def publish_job_started(job_id: str, tenant_id: str, config: Dict[str, Any]) -> bool:
"""Publish training job started event"""
event = TrainingStartedEvent(
service_name="training-service",
data={
"job_id": job_id,
"tenant_id": tenant_id,
"config": config
}
)
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.started",
event_data=event.to_dict()
)
async def publish_job_progress(job_id: str, tenant_id: str, progress: int, step: str) -> bool:
"""Publish training job progress event"""
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.progress",
event_data={
"service_name": "training-service",
"event_type": "training.progress",
"data": {
"job_id": job_id,
"tenant_id": tenant_id,
"progress": progress,
"current_step": step
}
}
)
async def publish_job_completed(job_id: str, tenant_id: str, results: Dict[str, Any]) -> bool:
"""Publish training job completed event"""
event = TrainingCompletedEvent(
service_name="training-service",
data={
"job_id": job_id,
"tenant_id": tenant_id,
"results": results,
"models_trained": results.get("products_trained", 0),
"success_rate": results.get("summary", {}).get("success_rate", 0)
}
)
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.completed",
event_data=event.to_dict()
)
async def publish_job_failed(job_id: str, tenant_id: str, error: str) -> bool:
"""Publish training job failed event"""
event = TrainingFailedEvent(
service_name="training-service",
data={
"job_id": job_id,
"tenant_id": tenant_id,
"error": error
}
)
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.failed",
event_data=event.to_dict()
)
async def publish_job_cancelled(job_id: str, tenant_id: str) -> bool:
"""Publish training job cancelled event"""
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.cancelled",
event_data={
"service_name": "training-service",
"event_type": "training.cancelled",
"data": {
"job_id": job_id,
"tenant_id": tenant_id
}
}
)
# Product Training Events
async def publish_product_training_started(job_id: str, tenant_id: str, product_name: str) -> bool:
"""Publish single product training started event"""
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.product.started",
event_data={
"service_name": "training-service",
"event_type": "training.product.started",
"data": {
"job_id": job_id,
"tenant_id": tenant_id,
"product_name": product_name
}
}
)
async def publish_product_training_completed(job_id: str, tenant_id: str, product_name: str, model_id: str) -> bool:
"""Publish single product training completed event"""
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.product.completed",
event_data={
"service_name": "training-service",
"event_type": "training.product.completed",
"data": {
"job_id": job_id,
"tenant_id": tenant_id,
"product_name": product_name,
"model_id": model_id
}
}
)
# Model Events
async def publish_model_trained(model_id: str, tenant_id: str, product_name: str, metrics: Dict[str, float]) -> bool:
"""Publish model trained event"""
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.model.trained",
event_data={
"service_name": "training-service",
"event_type": "training.model.trained",
"data": {
"model_id": model_id,
"tenant_id": tenant_id,
"product_name": product_name,
"training_metrics": metrics
}
}
)
async def publish_model_updated(model_id: str, tenant_id: str, product_name: str, version: int) -> bool:
"""Publish model updated event"""
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.model.updated",
event_data={
"service_name": "training-service",
"event_type": "training.model.updated",
"data": {
"model_id": model_id,
"tenant_id": tenant_id,
"product_name": product_name,
"version": version
}
}
)
async def publish_model_validated(model_id: str, tenant_id: str, product_name: str, validation_results: Dict[str, Any]) -> bool:
"""Publish model validation event"""
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.model.validated",
event_data={
"service_name": "training-service",
"event_type": "training.model.validated",
"data": {
"model_id": model_id,
"tenant_id": tenant_id,
"product_name": product_name,
"validation_results": validation_results
}
}
)
async def publish_model_saved(model_id: str, tenant_id: str, product_name: str, model_path: str) -> bool:
"""Publish model saved event"""
return await training_publisher.publish_event(
exchange_name="training.events",
routing_key="training.model.saved",
event_data={
"service_name": "training-service",
"event_type": "training.model.saved",
"data": {
"model_id": model_id,
"tenant_id": tenant_id,
"product_name": product_name,
"model_path": model_path
}
}
)