File size: 4,475 Bytes
af23d2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# routes/api/headlines.py
from fastapi import APIRouter, HTTPException, status
import logging
from typing import Dict, Any

# Import functions directly from the now standalone detailed_explainer
# Ensure sys.path in app.py allows these imports to components/generators
from components.generators.detailed_explainer import (
    generate_detailed_feed,
    cache_detailed_feed,
    get_cached_detailed_feed
)
# We also need to get the initial summaries, which are managed by daily_feed.py
from components.generators.daily_feed import get_cached_daily_feed

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

router = APIRouter()

@router.post("/generate-detailed") # Endpoint for triggering detailed generation
async def generate_detailed_headlines_endpoint() -> Dict[str, Any]:
    """
    Generates detailed explanations for the latest cached summaries.
    This step requires initial summaries to be present in Redis cache (from daily_feed.py).
    The final detailed feed is then cached by this endpoint using its dedicated key.
    """
    logging.info("API Call: POST /api/headlines/generate-detailed initiated.")
    try:
        # Step 1: Retrieve the cached initial summaries
        initial_summaries = get_cached_daily_feed() # This gets data from "initial_news_summary_cache"
        
        if not initial_summaries:
            logging.warning("No initial summaries found in cache to generate detailed explanations from.")
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="No initial news summaries found in cache. Please run the ingestion/summarization process first (e.g., /api/ingest/run)."
            )

        # Step 2: Generate detailed explanations (this is an async call to detailed_explainer)
        detailed_feed = await generate_detailed_feed(initial_summaries)

        if not detailed_feed:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Failed to generate detailed explanations. Check server logs for errors during LLM calls or content retrieval."
            )

        # Step 3: Cache the final detailed feed using the function from detailed_explainer
        # This function (cache_detailed_feed) internally uses its own Redis client and DETAILED_FEED_CACHE_KEY
        cache_detailed_feed(detailed_feed) 

        logging.info("API Call: POST /api/headlines/generate-detailed completed successfully.")
        
        total_items = sum(len(topic_summaries) for topic_summaries in detailed_feed.values())
        
        return {"status": "success", "message": "Detailed headlines generated and cached.", "items": total_items}

    except HTTPException as he:
        raise he # Re-raise FastAPI's HTTPExceptions
    except Exception as e:
        logging.error(f"Error in /api/headlines/generate-detailed: {e}", exc_info=True)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"An unexpected error occurred during detailed feed generation: {e}"
        )

@router.get("/get-detailed") # Endpoint for retrieving detailed headlines
async def get_detailed_headlines_endpoint() -> Dict[str, Dict[int, Dict[str, Any]]]:
    """
    Retrieves the most recently cached *fully detailed* news feed.
    Returns 404 if no detailed feed is found in cache.
    """
    logging.info("API Call: GET /api/headlines/get-detailed initiated.")
    try:
        # Retrieve the cached detailed feed using the function from detailed_explainer
        cached_detailed_feed = get_cached_detailed_feed()

        if not cached_detailed_feed:
            logging.info("No full detailed news feed found in cache.")
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="No detailed news feed found in cache. Please run /api/headlines/generate-detailed first."
            )
        
        logging.info("API Call: GET /api/headlines/get-detailed completed successfully.")
        return cached_detailed_feed

    except HTTPException as he:
        raise he
    except Exception as e:
        logging.error(f"Error in /api/headlines/get-detailed: {e}", exc_info=True)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"An unexpected error occurred while retrieving cached detailed feed: {e}"
        )