File size: 2,243 Bytes
208266a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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"
    )