from fastapi import FastAPI, Header, HTTPException from pydantic import BaseModel from app.config import settings from app.summarizer import summarize from app.transcript import SkipVideo, extract_video_id, fetch_transcript app = FastAPI(title="News Summary Bot") class SummarizeRequest(BaseModel): video_url: str title: str = "" channel_name: str = "" @app.post("/summarize") async def summarize_video( req: SummarizeRequest, x_api_secret: str = Header(default=""), ): if settings.api_secret and x_api_secret != settings.api_secret: raise HTTPException(status_code=401, detail="Unauthorized") title = req.title or "제목 없음" channel_name = req.channel_name or "" base = {"video_url": req.video_url, "title": title, "channel_name": channel_name} try: video_id = extract_video_id(req.video_url) transcript = fetch_transcript(video_id) summary = summarize(transcript, title) except SkipVideo as e: return {**base, "status": "skipped", "reason": str(e)} except Exception as e: return { **base, "status": "error", "error_type": type(e).__name__, "error_message": str(e), } # Discord embed description용 통합 요약 parts = [] if summary.get("oneliner"): parts.append(f"💡 **{summary['oneliner']}**") if summary.get("main_points"): parts.append(f"\n📌 **주요 내용**\n{summary['main_points']}") if summary.get("conclusion"): parts.append(f"\n🎯 **결론**\n> {summary['conclusion']}") if summary.get("market_impact"): parts.append(f"\n📈 **시장 영향**\n{summary['market_impact']}") if summary.get("sectors"): parts.append(f"\n🏭 **관련 섹터**\n{summary['sectors']}") if summary.get("watchlist"): parts.append(f"\n👀 **주목 종목**\n{summary['watchlist']}") if summary.get("outlook"): parts.append(f"\n🔮 **전망**\n{summary['outlook']}") summary["summary"] = "\n".join(parts) return {**base, "status": "ok", **summary} @app.get("/health") async def health(): return {"status": "ok"}