ragV98 commited on
Commit
0fe3764
·
1 Parent(s): af23d2f

pheww again

Browse files
Files changed (3) hide show
  1. app.py +30 -22
  2. routes/api/__init__.py +0 -0
  3. routes/api/descriptive.py +12 -13
app.py CHANGED
@@ -2,42 +2,50 @@
2
  import os
3
  import sys
4
  from fastapi import FastAPI
 
 
5
 
6
- # --- Crucial for finding your modules ---
7
- # Assuming app.py is at the project root level.
8
  # This ensures Python can find 'components' and 'routes' as packages.
9
  sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
10
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "components")))
11
- sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "routes"))) # Add the routes directory
12
- # Add routes/api to path if you are doing 'from routes.api import module' directly
13
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "routes", "api")))
14
 
15
  # Import your routers
16
- # These imports expect routes/api/ingest.py, routes/api/query.py, routes/api/headlines.py to exist
17
  from routes.api import ingest as ingest_router_module
18
- from routes.api import query as query_router_module # Assuming this exists
19
- from routes.api import headlines as headlines_router_module
 
20
 
 
 
21
 
22
- # NOTE: Settings.llm = None
23
- # This line is problematic if LlamaIndex components in your pipeline (like query engine)
24
- # rely on a global LLM setting. If you intend to use an LLM with LlamaIndex features,
25
- # you would set it here, e.g., `Settings.llm = OpenAI()`
26
- # For this current pipeline, the OpenAI client is initialized explicitly within
27
- # daily_feed.py and detailed_explainer.py, so setting Settings.llm here is not strictly needed
28
- # but also not harmful if it's just meant as a placeholder for a different use case.
29
- # I will leave it commented out as per your original request, but be aware of its implications.
30
- # Settings.llm = None
31
 
 
 
 
 
 
 
 
 
32
 
33
- app = FastAPI()
34
 
35
  @app.get("/")
36
  def greet():
 
37
  return {"welcome": "nuse ai"}
38
 
39
- # Include your routers
40
- # Use .router to access the APIRouter instance from the imported modules
41
- app.include_router(ingest_router_module.router, prefix="/api/ingest")
42
- app.include_router(query_router_module.router, prefix="/api/query") # Assuming query.py exists
43
- app.include_router(headlines_router_module.router, prefix="/api/headlines")
 
2
  import os
3
  import sys
4
  from fastapi import FastAPI
5
+ import logging
6
+ import redis # For optional top-level Redis connectivity check
7
 
8
+ # --- CRITICAL: Adjust sys.path to find your modules correctly ---
9
+ # Assuming 'app.py' is at the project root level.
10
  # This ensures Python can find 'components' and 'routes' as packages.
11
  sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
12
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "components")))
13
+ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "routes")))
14
+ # Add routes/api specifically, as you're importing directly from it
15
  sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "routes", "api")))
16
 
17
  # Import your routers
18
+ # These imports expect routes/api/ingest.py, routes/api/descriptive.py, routes/api/headlines.py to exist
19
  from routes.api import ingest as ingest_router_module
20
+ from routes.api import descriptive as descriptive_router_module
21
+ from routes.api import headlines as headlines_router_module
22
+ # query.py is ignored as per your instruction
23
 
24
+ # Configure basic logging for the application
25
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
26
 
27
+ app = FastAPI(
28
+ title="Nuse AI News Aggregator",
29
+ description="API for fetching, summarizing, and providing detailed explanations of news articles.",
30
+ version="1.0.0",
31
+ )
 
 
 
 
32
 
33
+ # Optional: App-level Redis client check
34
+ REDIS_URL = os.environ.get("UPSTASH_REDIS_URL", "redis://localhost:6379")
35
+ try:
36
+ _app_redis_client_test = redis.Redis.from_url(REDIS_URL, decode_responses=True)
37
+ _app_redis_client_test.ping()
38
+ logging.info("App-level Redis connection test successful.")
39
+ except Exception as e:
40
+ logging.critical(f"❌ FATAL ERROR: App-level Redis connection failed: {e}. Some functionalities may be impaired.")
41
 
 
42
 
43
  @app.get("/")
44
  def greet():
45
+ """Root endpoint for the API."""
46
  return {"welcome": "nuse ai"}
47
 
48
+ # Include your routers with specific prefixes and tags
49
+ app.include_router(ingest_router_module.router, prefix="/api/ingest", tags=["Data Ingestion & Summaries"])
50
+ app.include_router(descriptive_router_module.router, prefix="/api/descriptive", tags=["Detailed Explanations"])
51
+ app.include_router(headlines_router_module.router, prefix="/api/headlines", tags=["Headlines (Placeholder)"])
 
routes/api/__init__.py ADDED
File without changes
routes/api/descriptive.py CHANGED
@@ -1,14 +1,13 @@
1
- # routes/api/headlines.py
2
  from fastapi import APIRouter, HTTPException, status
3
  import logging
4
  from typing import Dict, Any
5
 
6
  # Import functions directly from the now standalone detailed_explainer
7
- # Ensure sys.path in app.py allows these imports to components/generators
8
  from components.generators.detailed_explainer import (
9
  generate_detailed_feed,
10
- cache_detailed_feed,
11
- get_cached_detailed_feed
12
  )
13
  # We also need to get the initial summaries, which are managed by daily_feed.py
14
  from components.generators.daily_feed import get_cached_daily_feed
@@ -24,10 +23,10 @@ async def generate_detailed_headlines_endpoint() -> Dict[str, Any]:
24
  This step requires initial summaries to be present in Redis cache (from daily_feed.py).
25
  The final detailed feed is then cached by this endpoint using its dedicated key.
26
  """
27
- logging.info("API Call: POST /api/headlines/generate-detailed initiated.")
28
  try:
29
  # Step 1: Retrieve the cached initial summaries
30
- initial_summaries = get_cached_daily_feed() # This gets data from "initial_news_summary_cache"
31
 
32
  if not initial_summaries:
33
  logging.warning("No initial summaries found in cache to generate detailed explanations from.")
@@ -49,16 +48,16 @@ async def generate_detailed_headlines_endpoint() -> Dict[str, Any]:
49
  # This function (cache_detailed_feed) internally uses its own Redis client and DETAILED_FEED_CACHE_KEY
50
  cache_detailed_feed(detailed_feed)
51
 
52
- logging.info("API Call: POST /api/headlines/generate-detailed completed successfully.")
53
 
54
  total_items = sum(len(topic_summaries) for topic_summaries in detailed_feed.values())
55
 
56
  return {"status": "success", "message": "Detailed headlines generated and cached.", "items": total_items}
57
 
58
  except HTTPException as he:
59
- raise he # Re-raise FastAPI's HTTPExceptions
60
  except Exception as e:
61
- logging.error(f"Error in /api/headlines/generate-detailed: {e}", exc_info=True)
62
  raise HTTPException(
63
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
64
  detail=f"An unexpected error occurred during detailed feed generation: {e}"
@@ -70,7 +69,7 @@ async def get_detailed_headlines_endpoint() -> Dict[str, Dict[int, Dict[str, Any
70
  Retrieves the most recently cached *fully detailed* news feed.
71
  Returns 404 if no detailed feed is found in cache.
72
  """
73
- logging.info("API Call: GET /api/headlines/get-detailed initiated.")
74
  try:
75
  # Retrieve the cached detailed feed using the function from detailed_explainer
76
  cached_detailed_feed = get_cached_detailed_feed()
@@ -79,16 +78,16 @@ async def get_detailed_headlines_endpoint() -> Dict[str, Dict[int, Dict[str, Any
79
  logging.info("No full detailed news feed found in cache.")
80
  raise HTTPException(
81
  status_code=status.HTTP_404_NOT_FOUND,
82
- detail="No detailed news feed found in cache. Please run /api/headlines/generate-detailed first."
83
  )
84
 
85
- logging.info("API Call: GET /api/headlines/get-detailed completed successfully.")
86
  return cached_detailed_feed
87
 
88
  except HTTPException as he:
89
  raise he
90
  except Exception as e:
91
- logging.error(f"Error in /api/headlines/get-detailed: {e}", exc_info=True)
92
  raise HTTPException(
93
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
94
  detail=f"An unexpected error occurred while retrieving cached detailed feed: {e}"
 
1
+ # routes/api/descriptive.py
2
  from fastapi import APIRouter, HTTPException, status
3
  import logging
4
  from typing import Dict, Any
5
 
6
  # Import functions directly from the now standalone detailed_explainer
 
7
  from components.generators.detailed_explainer import (
8
  generate_detailed_feed,
9
+ cache_detailed_feed, # Function to cache the detailed feed
10
+ get_cached_detailed_feed # Function to retrieve the detailed feed
11
  )
12
  # We also need to get the initial summaries, which are managed by daily_feed.py
13
  from components.generators.daily_feed import get_cached_daily_feed
 
23
  This step requires initial summaries to be present in Redis cache (from daily_feed.py).
24
  The final detailed feed is then cached by this endpoint using its dedicated key.
25
  """
26
+ logging.info("API Call: POST /api/descriptive/generate-detailed initiated.")
27
  try:
28
  # Step 1: Retrieve the cached initial summaries
29
+ initial_summaries = get_cached_daily_feed() # From daily_feed.py
30
 
31
  if not initial_summaries:
32
  logging.warning("No initial summaries found in cache to generate detailed explanations from.")
 
48
  # This function (cache_detailed_feed) internally uses its own Redis client and DETAILED_FEED_CACHE_KEY
49
  cache_detailed_feed(detailed_feed)
50
 
51
+ logging.info("API Call: POST /api/descriptive/generate-detailed completed successfully.")
52
 
53
  total_items = sum(len(topic_summaries) for topic_summaries in detailed_feed.values())
54
 
55
  return {"status": "success", "message": "Detailed headlines generated and cached.", "items": total_items}
56
 
57
  except HTTPException as he:
58
+ raise he
59
  except Exception as e:
60
+ logging.error(f"Error in /api/descriptive/generate-detailed: {e}", exc_info=True)
61
  raise HTTPException(
62
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
63
  detail=f"An unexpected error occurred during detailed feed generation: {e}"
 
69
  Retrieves the most recently cached *fully detailed* news feed.
70
  Returns 404 if no detailed feed is found in cache.
71
  """
72
+ logging.info("API Call: GET /api/descriptive/get-detailed initiated.")
73
  try:
74
  # Retrieve the cached detailed feed using the function from detailed_explainer
75
  cached_detailed_feed = get_cached_detailed_feed()
 
78
  logging.info("No full detailed news feed found in cache.")
79
  raise HTTPException(
80
  status_code=status.HTTP_404_NOT_FOUND,
81
+ detail="No detailed news feed found in cache. Please run /api/descriptive/generate-detailed first."
82
  )
83
 
84
+ logging.info("API Call: GET /api/descriptive/get-detailed completed successfully.")
85
  return cached_detailed_feed
86
 
87
  except HTTPException as he:
88
  raise he
89
  except Exception as e:
90
+ logging.error(f"Error in /api/descriptive/get-detailed: {e}", exc_info=True)
91
  raise HTTPException(
92
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
93
  detail=f"An unexpected error occurred while retrieving cached detailed feed: {e}"