diff --git a/services/music-render/main.py b/services/music-render/main.py new file mode 100644 index 0000000..743b48a --- /dev/null +++ b/services/music-render/main.py @@ -0,0 +1,88 @@ +"""music-render FastAPI entry — health + lifespan + sync forward endpoints. + +NAS music-lab이 sync helpers(lyrics, credits, timestamped, style-boost)를 +httpx로 forward해서 이 endpoint들을 호출. +""" +from __future__ import annotations + +import asyncio +import logging +from contextlib import asynccontextmanager + +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel + +import worker +from providers.sync_ops import ( + generate_lyrics, get_credits, + get_timestamped_lyrics, generate_style_boost, +) + +logging.basicConfig(level=logging.INFO, format="%(asctime)s %(name)s %(levelname)s %(message)s") +logger = logging.getLogger(__name__) + + +@asynccontextmanager +async def lifespan(app: FastAPI): + worker_task = asyncio.create_task(worker.worker_loop()) + logger.info("music-render lifespan 시작") + try: + yield + finally: + worker_task.cancel() + try: + await worker_task + except asyncio.CancelledError: + pass + logger.info("music-render lifespan 종료") + + +app = FastAPI(lifespan=lifespan) + + +@app.get("/health") +def health(): + return {"ok": True, "service": "music-render"} + + +# ── Sync forward endpoints ────────────────────────────────────────────── +# NAS music-lab의 /api/music/lyrics 등 sync helpers가 이 endpoint들로 forward. + +class LyricsRequest(BaseModel): + prompt: str + + +@app.post("/api/music-render/sync/lyrics") +def sync_lyrics(req: LyricsRequest): + result = generate_lyrics(req.prompt) + if not result: + raise HTTPException(502, "가사 생성 실패") + return result + + +@app.get("/api/music-render/sync/credits") +def sync_credits(): + result = get_credits() + if result is None: + raise HTTPException(502, "크레딧 조회 실패") + return result + + +@app.get("/api/music-render/sync/timestamped-lyrics") +def sync_timestamped_lyrics(task_id: str, suno_id: str): + result = get_timestamped_lyrics(task_id, suno_id) + if not result: + raise HTTPException(502, "타임스탬프 가사 조회 실패") + return result + + +class StyleBoostRequest(BaseModel): + content: str + + +@app.post("/api/music-render/sync/style-boost") +def sync_style_boost(req: StyleBoostRequest): + result = generate_style_boost(req.content) + if not result: + raise HTTPException(502, "스타일 부스트 생성 실패") + return result