"""뉴스 감성 분석 API 엔드포인트 - GET /api/v1/news/score/{stock_code} : 종목별 뉴스 감성 점수 - GET /api/v1/news/score/market : 시장 전체 뉴스 감성 점수 - GET /api/v1/news/summary/{stock_code} : 종목 뉴스 요약 (점수 + 기사 목록) - GET /api/v1/news/recent : 최근 수집된 뉴스 목록 (DB 조회) """ import logging from typing import Optional from fastapi import APIRouter, Query from sqlalchemy import select, desc from app.core.database import AsyncSessionLocal from app.models.models import News logger = logging.getLogger(__name__) router = APIRouter() @router.get("/score/market") async def get_market_score(): """시장 전체 뉴스 감성 점수 조회. Returns: {"score": float, "source": "market"} """ from app.services.news_sentiment import get_market_news_score score = await get_market_news_score() return {"score": score, "source": "market"} @router.get("/score/{stock_code}") async def get_stock_score(stock_code: str): """종목별 뉴스 감성 점수 조회. Args: stock_code: 종목 코드 (예: 005930) Returns: {"stock_code": str, "score": float} """ from app.services.news_sentiment import get_stock_news_score score = await get_stock_news_score(stock_code) return {"stock_code": stock_code, "score": score} @router.get("/summary/{stock_code}") async def get_stock_summary(stock_code: str): """종목 뉴스 요약 (점수 + 기사 목록 + 감성 분포). Args: stock_code: 종목 코드 Returns: {"stock_code", "score", "article_count", "latest_articles", "sentiment_distribution"} """ from app.services.news_sentiment import get_stock_news_summary return await get_stock_news_summary(stock_code) @router.get("/recent") async def get_recent_news( stock_code: Optional[str] = Query(None, description="종목 코드 필터 (선택)"), limit: int = Query(20, ge=1, le=100, description="조회 개수"), ): """DB에 저장된 최근 뉴스 목록 조회. Args: stock_code: 특정 종목 필터 (선택) limit: 조회 개수 (기본 20, 최대 100) Returns: {"news": [...], "count": int} """ try: async with AsyncSessionLocal() as session: query = select(News).order_by(desc(News.published_at)) if stock_code: query = query.where(News.stock_codes.any(stock_code)) query = query.limit(limit) result = await session.execute(query) rows = result.scalars().all() news_list = [ { "id": row.id, "title": row.title, "source": row.source, "url": row.url, "stock_codes": row.stock_codes, "sentiment": row.sentiment, "sentiment_score": float(row.sentiment_score) if row.sentiment_score else None, "published_at": row.published_at.isoformat() if row.published_at else None, "created_at": row.created_at.isoformat() if row.created_at else None, } for row in rows ] return {"news": news_list, "count": len(news_list)} except Exception as e: logger.error(f"[NEWS_API] 최근 뉴스 조회 오류: {e}") return {"news": [], "count": 0, "error": str(e)}