""" 新闻 API - 提供新闻查询接口 """ from fastapi import APIRouter, HTTPException, Query from typing import Dict, List, Optional, Any from app.news_agent.news_agent import get_news_agent from app.news_agent.news_db_service import get_news_db_service from app.utils.logger import logger router = APIRouter(prefix="/api/news", tags=["新闻管理"]) @router.get("/articles") async def get_articles( category: Optional[str] = Query(None, description="分类过滤 (crypto/stock)"), limit: int = Query(50, ge=1, le=200, description="返回数量限制"), hours: int = Query(24, ge=1, le=168, description="查询最近多少小时") ) -> Dict[str, Any]: """ 获取新闻文章列表 Args: category: 分类过滤 limit: 返回数量限制 hours: 查询最近多少小时 Returns: 文章列表 """ try: db_service = get_news_db_service() articles = db_service.get_latest_articles( category=category, limit=limit, hours=hours ) return { 'success': True, 'articles': articles, 'count': len(articles) } except Exception as e: logger.error(f"获取新闻文章失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.get("/stats") async def get_news_stats( hours: int = Query(24, ge=1, le=168, description="统计最近多少小时") ) -> Dict[str, Any]: """ 获取新闻统计信息 Args: hours: 统计最近多少小时 Returns: 统计数据 """ try: news_agent = get_news_agent() agent_stats = news_agent.get_stats() db_service = get_news_db_service() db_stats = db_service.get_stats(hours=hours) return { 'success': True, 'agent': agent_stats, 'database': db_stats } except Exception as e: logger.error(f"获取新闻统计失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.post("/fetch") async def manual_fetch( category: Optional[str] = Query(None, description="分类过滤 (crypto/stock)") ) -> Dict[str, Any]: """ 手动触发新闻抓取 Args: category: 分类过滤 Returns: 抓取结果 """ try: news_agent = get_news_agent() result = await news_agent.manual_fetch(category) return { 'success': True, **result } except Exception as e: logger.error(f"手动抓取新闻失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.get("/high-priority") async def get_high_priority_articles( limit: int = Query(20, ge=1, le=100, description="返回数量限制"), min_priority: float = Query(40.0, description="最低优先级分数"), hours: int = Query(24, ge=1, le=168, description="查询最近多少小时") ) -> Dict[str, Any]: """ 获取高优先级文章 Args: limit: 返回数量限制 min_priority: 最低优先级分数 hours: 查询最近多少小时 Returns: 高优先级文章列表 """ try: db_service = get_news_db_service() articles = db_service.get_high_priority_articles( limit=limit, min_priority=min_priority, hours=hours ) return { 'success': True, 'articles': [article.to_dict() for article in articles], 'count': len(articles) } except Exception as e: logger.error(f"获取高优先级文章失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.get("/sources") async def get_news_sources() -> Dict[str, Any]: """ 获取新闻源配置 Returns: 新闻源列表 """ try: from app.news_agent.sources import CRYPTO_NEWS_SOURCES, STOCK_NEWS_SOURCES # 只返回基本信息,隐藏敏感配置 crypto_sources = [ { 'name': s['name'], 'category': s['category'], 'enabled': s['enabled'] } for s in CRYPTO_NEWS_SOURCES ] stock_sources = [ { 'name': s['name'], 'category': s['category'], 'enabled': s['enabled'] } for s in STOCK_NEWS_SOURCES ] return { 'success': True, 'crypto': crypto_sources, 'stock': stock_sources, 'total': len(crypto_sources) + len(stock_sources) } except Exception as e: logger.error(f"获取新闻源失败: {e}") raise HTTPException(status_code=500, detail=str(e))