hgzero/ai-python/main.py
Minseo-Jo c9d24ce1af feat: AI 서비스 AKS 배포 준비 및 API 경로 수정
## API 경로 변경
- /api/v1/ai → /api/ai 로 경로 단순화
- 최종 엔드포인트: /api/ai/suggestions/meetings/{meetingId}/stream

## Docker 컨테이너화
- Dockerfile 작성 (Python 3.11 slim 기반)
- .dockerignore 추가
- 헬스 체크 포함

## Kubernetes 배포
- Deployment 및 Service 매니페스트 작성
- Replica: 1, Port: 8087
- Liveness/Readiness Probe 설정
- 리소스 제한: CPU 250m-1000m, Memory 512Mi-1024Mi

## Secret 및 ConfigMap
- ai-secret: Claude API Key
- azure-secret: Event Hub Connection String (AI Listen Policy)
- redis-config/redis-secret: Redis 연결 정보

## Ingress 설정
- /api/ai/suggestions 경로 추가 (ai-service:8087)
- 기존 /api/ai 경로 유지 (ai:8080)

## 배포 문서
- DEPLOYMENT.md: 상세한 AKS 배포 가이드
  - Docker 이미지 빌드 및 푸시
  - Secret/ConfigMap 생성
  - 배포 및 검증
  - 트러블슈팅

## ACR 이미지
- acrdigitalgarage02.azurecr.io/hgzero/ai-service:latest

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 17:08:28 +09:00

129 lines
3.3 KiB
Python

"""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/ai/suggestions",
tags=["AI Suggestions"]
)
@app.get("/")
async def root():
"""루트 엔드포인트"""
return {
"service": settings.app_name,
"version": "1.0.0",
"status": "running",
"endpoints": {
"test": "/api/ai/suggestions/test",
"stream": "/api/ai/suggestions/meetings/{meeting_id}/stream",
"swagger": "/swagger-ui.html"
}
}
@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()
)