- FastAPI 백엔드 (audio-studio-api) - Next.js 프론트엔드 (audio-studio-ui) - Qwen3-TTS 엔진 (audio-studio-tts) - MusicGen 서비스 (audio-studio-musicgen) - Docker Compose 개발/운영 환경 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
164 lines
4.0 KiB
Python
164 lines
4.0 KiB
Python
"""Drama Studio API Server
|
|
|
|
AI 라디오 드라마 제작 - TTS, 보이스, 효과음, 배경음악, 드라마 생성 API
|
|
"""
|
|
|
|
import logging
|
|
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.responses import JSONResponse
|
|
|
|
from app.database import db
|
|
from app.routers import voices, tts, recordings, sound_effects, music, drama
|
|
|
|
# 로깅 설정
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# ========================================
|
|
# 앱 생명주기
|
|
# ========================================
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
"""앱 시작/종료 시 실행"""
|
|
# 시작 시 DB 연결
|
|
logger.info("Drama Studio API 서버 시작...")
|
|
try:
|
|
await db.connect()
|
|
logger.info("데이터베이스 연결 완료")
|
|
except Exception as e:
|
|
logger.error(f"데이터베이스 연결 실패: {e}")
|
|
raise
|
|
|
|
yield
|
|
|
|
# 종료 시 DB 연결 해제
|
|
await db.disconnect()
|
|
logger.info("Drama Studio API 서버 종료")
|
|
|
|
|
|
# ========================================
|
|
# FastAPI 앱
|
|
# ========================================
|
|
|
|
app = FastAPI(
|
|
title="Drama Studio API",
|
|
description="""
|
|
Drama Studio API - AI 라디오 드라마 제작 플랫폼
|
|
|
|
## 기능
|
|
|
|
### Voice (보이스 관리)
|
|
- 프리셋 보이스 목록 조회
|
|
- Voice Clone (목소리 복제)
|
|
- Voice Design (AI 음성 생성)
|
|
- 사용자 보이스 라이브러리
|
|
|
|
### TTS (음성 합성)
|
|
- 텍스트를 음성으로 변환
|
|
- 다양한 언어 지원 (한국어, 영어, 일본어 등)
|
|
|
|
### Recording (녹음)
|
|
- 녹음 업로드 및 품질 검증
|
|
- Voice Clone용 레퍼런스 관리
|
|
|
|
### Sound Effects (효과음)
|
|
- Freesound 검색 및 다운로드
|
|
- 로컬 효과음 라이브러리
|
|
|
|
### Drama (드라마 생성)
|
|
- 스크립트 기반 라디오 드라마 생성
|
|
- 자동 TTS/BGM/효과음 합성
|
|
- 타임라인 기반 오디오 믹싱
|
|
""",
|
|
version="0.1.0",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
# CORS 설정
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["*"], # 개발 환경용, 프로덕션에서는 제한 필요
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
|
|
# ========================================
|
|
# 라우터 등록
|
|
# ========================================
|
|
|
|
app.include_router(voices.router)
|
|
app.include_router(tts.router)
|
|
app.include_router(recordings.router)
|
|
app.include_router(sound_effects.router)
|
|
app.include_router(music.router)
|
|
app.include_router(drama.router)
|
|
|
|
|
|
# ========================================
|
|
# 기본 엔드포인트
|
|
# ========================================
|
|
|
|
@app.get("/")
|
|
async def root():
|
|
"""API 루트"""
|
|
return {
|
|
"name": "Drama Studio API",
|
|
"version": "0.1.0",
|
|
"docs": "/docs",
|
|
}
|
|
|
|
|
|
@app.get("/health")
|
|
async def health_check():
|
|
"""헬스체크"""
|
|
try:
|
|
# MongoDB 연결 확인
|
|
await db.client.admin.command("ping")
|
|
mongo_status = "healthy"
|
|
except Exception as e:
|
|
mongo_status = f"unhealthy: {str(e)}"
|
|
|
|
try:
|
|
# Redis 연결 확인
|
|
await db.redis.ping()
|
|
redis_status = "healthy"
|
|
except Exception as e:
|
|
redis_status = f"unhealthy: {str(e)}"
|
|
|
|
status = "healthy" if mongo_status == "healthy" and redis_status == "healthy" else "degraded"
|
|
|
|
return JSONResponse(
|
|
status_code=200 if status == "healthy" else 503,
|
|
content={
|
|
"status": status,
|
|
"services": {
|
|
"mongodb": mongo_status,
|
|
"redis": redis_status,
|
|
},
|
|
}
|
|
)
|
|
|
|
|
|
# ========================================
|
|
# 에러 핸들러
|
|
# ========================================
|
|
|
|
@app.exception_handler(Exception)
|
|
async def global_exception_handler(request, exc):
|
|
"""전역 예외 핸들러"""
|
|
logger.error(f"Unhandled exception: {exc}", exc_info=True)
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content={"detail": "Internal server error"},
|
|
)
|