from __future__ import annotations from pathlib import Path from typing import Any, Dict from fastapi import Depends, FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse, HTMLResponse, JSONResponse from fastapi.staticfiles import StaticFiles from starlette.middleware.sessions import SessionMiddleware from asr.config import ensure_runtime_dirs from asr.router import router as asr_router from asr.router import ws_router as asr_ws_router from core.auth import SESSION_SECRET_KEY, require_login from core.auth import router as auth_router from tts.router import router as tts_router app = FastAPI(title="ASR/TTS Gateway", docs_url="/docs", redoc_url="/redoc") app.add_middleware( SessionMiddleware, secret_key=SESSION_SECRET_KEY, same_site="lax", https_only=False, # 아직 전용 도메인/TLS가 없어 내부 IP:포트(http)로 접근하기 때문 max_age=14 * 24 * 3600, ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) UI_DIR = Path("/app/ui") app.include_router(auth_router, prefix="/auth", tags=["auth"]) app.include_router(asr_router, prefix="/asr", tags=["asr"], dependencies=[Depends(require_login)]) app.include_router(asr_ws_router, prefix="/asr", tags=["asr"]) # 인증은 핸들러 내부에서 세션으로 직접 체크 app.include_router(tts_router, prefix="/tts", tags=["tts"], dependencies=[Depends(require_login)]) @app.on_event("startup") def startup() -> None: ensure_runtime_dirs() if UI_DIR.exists(): app.mount("/ui", StaticFiles(directory=str(UI_DIR), html=True), name="ui") app.mount("/assets", StaticFiles(directory=str(UI_DIR / "assets")), name="assets") @app.get("/health") def health() -> Dict[str, Any]: return {"status": "ok", "ui_installed": UI_DIR.exists(), "api": "/docs"} @app.get("/", response_class=HTMLResponse, dependencies=[Depends(require_login)]) def root() -> Any: index = UI_DIR / "index.html" if index.exists(): return FileResponse(index) return JSONResponse({"status": "ok", "message": "UI not installed", "api": "/docs"})