from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from contextlib import asynccontextmanager import os from app.routers import download, process, bgm, jobs, fonts from app.config import settings @asynccontextmanager async def lifespan(app: FastAPI): # Startup os.makedirs(settings.DOWNLOAD_DIR, exist_ok=True) os.makedirs(settings.PROCESSED_DIR, exist_ok=True) os.makedirs(settings.BGM_DIR, exist_ok=True) # Check BGM status on startup bgm_files = [] if os.path.exists(settings.BGM_DIR): bgm_files = [f for f in os.listdir(settings.BGM_DIR) if f.endswith(('.mp3', '.wav', '.m4a', '.ogg'))] if len(bgm_files) == 0: print("[Startup] No BGM files found. Upload BGM via /api/bgm/upload or download from Pixabay/Mixkit") else: names = ', '.join(bgm_files[:3]) suffix = f'... (+{len(bgm_files) - 3} more)' if len(bgm_files) > 3 else '' print(f"[Startup] Found {len(bgm_files)} BGM files: {names}{suffix}") yield # Shutdown app = FastAPI( title="Shorts Maker API", description="중국 쇼츠 영상을 한글 자막으로 변환하는 서비스", version="1.0.0", lifespan=lifespan, ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Static files for processed videos app.mount("/static/downloads", StaticFiles(directory="data/downloads"), name="downloads") app.mount("/static/processed", StaticFiles(directory="data/processed"), name="processed") app.mount("/static/bgm", StaticFiles(directory="data/bgm"), name="bgm") # Routers app.include_router(download.router, prefix="/api/download", tags=["Download"]) app.include_router(process.router, prefix="/api/process", tags=["Process"]) app.include_router(bgm.router, prefix="/api/bgm", tags=["BGM"]) app.include_router(jobs.router, prefix="/api/jobs", tags=["Jobs"]) app.include_router(fonts.router, prefix="/api/fonts", tags=["Fonts"]) @app.get("/api/health") async def health_check(): return {"status": "healthy", "service": "shorts-maker"}