"""AI Service - FastAPI 애플리케이션""" import logging import asyncio import uvicorn from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from contextlib import asynccontextmanager from app.config import get_settings from app.api.v1 import suggestions from app.services.eventhub_service import start_eventhub_listener # 로깅 설정 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) settings = get_settings() @asynccontextmanager async def lifespan(app: FastAPI): """애플리케이션 생명주기 관리""" logger.info("=" * 60) logger.info(f"AI Service (Python) 시작 - Port: {settings.port}") logger.info(f"Claude Model: {settings.claude_model}") logger.info(f"Redis: {settings.redis_host}:{settings.redis_port}") logger.info("=" * 60) # Event Hub 리스너 시작 (백그라운드 태스크) logger.info("Event Hub 리스너 백그라운드 시작...") asyncio.create_task(start_eventhub_listener()) yield logger.info("AI Service 종료") # FastAPI 애플리케이션 app = FastAPI( title=settings.app_name, version="1.0.0", description=""" ## 실시간 AI 제안사항 서비스 (Python) 회의 중 실시간으로 텍스트를 분석하여 AI 제안사항을 생성하고 SSE(Server-Sent Events)로 스트리밍합니다. ### 주요 기능 - 🎯 실시간 회의 분석 - 🤖 Claude AI 기반 제안사항 생성 - 📡 SSE 스트리밍 - ⚡ Redis 캐시 연동 ### 인증 현재 버전은 인증이 필요하지 않습니다. """, lifespan=lifespan, docs_url="/swagger-ui.html", # Spring Boot 스타일 redoc_url="/redoc", openapi_url="/v3/api-docs", # Spring Boot 스타일 OpenAPI JSON openapi_tags=[ { "name": "AI Suggestions", "description": "AI 제안사항 실시간 스트리밍 API" }, { "name": "Health", "description": "서비스 상태 확인" } ] ) # CORS 설정 (개발 환경: 모든 origin 허용) app.add_middleware( CORSMiddleware, allow_origins=["*"], # 개발 환경에서 모든 origin 허용 allow_credentials=False, # allow_origins=["*"]일 때는 False여야 함 allow_methods=["*"], allow_headers=["*"], ) # 라우터 등록 app.include_router( suggestions.router, prefix="/api/v1/ai/suggestions", tags=["AI Suggestions"] ) @app.get("/") async def root(): """루트 엔드포인트""" return { "service": settings.app_name, "version": "1.0.0", "status": "running", "endpoints": { "test": "/api/v1/ai/suggestions/test", "stream": "/api/v1/ai/suggestions/meetings/{meeting_id}/stream" } } @app.get("/health", tags=["Health"]) async def health_check(): """ 헬스 체크 엔드포인트 Kubernetes liveness/readiness probe에서 사용 """ return { "status": "healthy", "service": settings.app_name, "port": settings.port } if __name__ == "__main__": uvicorn.run( "main:app", host=settings.host, port=settings.port, reload=True, # 개발 모드 log_level=settings.log_level.lower() )