from contextlib import asynccontextmanager from fastapi import FastAPI, Request, status from fastapi.responses import JSONResponse import logging from app.api.uis import router as uis_router from app.core.exceptions import CallEventAlreadyExistsError, DatabaseError, ValidationError # Настройка логирования logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) app = FastAPI( title="Ingest Service API", description="Микросервис для приема событий звонков", version="1.0.0", ) # Exception handlers @app.exception_handler(CallEventAlreadyExistsError) async def call_event_exists_handler(request: Request, exc: CallEventAlreadyExistsError): """Обработчик для дубликатов событий звонков""" logger.warning(f"Duplicate call event: {exc.message}", extra=exc.details) return JSONResponse( status_code=status.HTTP_409_CONFLICT, content={ "error": "duplicate_call_event", "message": exc.message, "details": exc.details } ) @app.exception_handler(DatabaseError) async def database_error_handler(request: Request, exc: DatabaseError): """Обработчик для ошибок БД""" logger.error(f"Database error: {exc.message}", extra=exc.details) return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={ "error": "database_error", "message": "Internal database error occurred", "details": exc.details } ) @app.exception_handler(ValidationError) async def validation_error_handler(request: Request, exc: ValidationError): """Обработчик для ошибок валидации""" logger.warning(f"Validation error: {exc.message}", extra=exc.details) return JSONResponse( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, content={ "error": "validation_error", "message": exc.message, "details": exc.details } ) @app.exception_handler(Exception) async def general_exception_handler(request: Request, exc: Exception): """Общий обработчик для неперехваченных исключений""" logger.error(f"Unhandled exception: {str(exc)}", exc_info=True) return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content={ "error": "internal_server_error", "message": "An unexpected error occurred" } ) # Health check endpoint @app.get("/health", tags=["Health"]) async def health_check(): """Проверка состояния сервиса""" return {"status": "healthy", "service": "ingest-service"} app.include_router(uis_router, prefix="/v1/uis", tags=["UIS Webhooks"])