from fastapi import APIRouter, HTTPException, Request import time from src.ingestion.newsapi_client import fetch_news from src.api.models import AnalyzeRequest, AnalyzeResponse, IngestRequest, IngestResponse router = APIRouter() _cache: dict = {} CACHE_TTL_SECONDS = 300 @router.get("/health") def health(): return {"status": "ok"} @router.post("/analyze", response_model=AnalyzeResponse) def analyze(request: Request, payload: AnalyzeRequest): if not payload.topic.strip(): raise HTTPException(status_code=400, detail="Topic cannot be empty.") cache_key = (payload.topic.lower().strip(), payload.top_k) now = time.time() if cache_key in _cache: cached = _cache[cache_key] if now - cached["timestamp"] < CACHE_TTL_SECONDS: print(f"Cache hit for: {payload.topic}") return cached["data"] pipeline = request.app.state.pipeline if pipeline is None: raise HTTPException(status_code=503, detail="Pipeline not initialized.") try: raw = pipeline.analyze(payload.topic, top_k=payload.top_k) except Exception as e: raise HTTPException(status_code=500, detail=f"Pipeline error: {str(e)}") sorted_results = sorted(raw["results"], key=lambda x: x["confidence"], reverse=True) response = AnalyzeResponse( topic=raw["topic"], total_articles=len(sorted_results), results=sorted_results, summary=raw["summary"] ) _cache[cache_key] = {"data": response, "timestamp": now} return response @router.post("/ingest", response_model=IngestResponse) def ingest(request: Request, payload: IngestRequest): try: articles = fetch_news(topic=payload.topic, page_size=payload.page_size) except RuntimeError as exc: raise HTTPException(status_code=503, detail=str(exc)) if not articles: raise HTTPException(status_code=404, detail=f"No articles found for topic: {payload.topic}") vector_store = request.app.state.pipeline.vector_store vector_store.store_articles(articles) _cache.clear() return IngestResponse( topic=payload.topic, articles_fetched=len(articles), articles_stored=len(articles), status="success" )