feat: Drama Studio 프로젝트 초기 구조 설정
- 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>
This commit is contained in:
163
audio-studio-api/app/main.py
Normal file
163
audio-studio-api/app/main.py
Normal file
@ -0,0 +1,163 @@
|
||||
"""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"},
|
||||
)
|
||||
Reference in New Issue
Block a user