Files
news-summary-bot/app/main.py
sm4640 b34bc1f582
All checks were successful
news-summary-bot-cicd / build_push_deploy (push) Successful in 11m18s
Feat: [4.0.0] 뉴스 요약에 주식 시장 영향 분석 기능 추가
요약 프롬프트에 증권 애널리스트 역할을 통합하여 API 1회 호출로
시장 영향, 관련 섹터, 주목 종목, 전망을 함께 생성.
모든 필드는 단순 문자열로 유지하여 파싱 안정성 확보.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 15:30:22 +09:00

68 lines
2.1 KiB
Python

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"}