Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions backend/app/api/v1/routes.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from fastapi import APIRouter, HTTPException, BackgroundTasks
from fastapi import APIRouter, BackgroundTasks
from fastapi.responses import JSONResponse
from backend.app.models.report_models import ReportRequest, ReportResponse
from backend.app.services.report_service import generate_report, in_memory_reports, get_report_status_from_memory, get_report_data
from backend.app.core.orchestrator import create_orchestrator
from backend.app.core.logger import api_logger
from backend.app.core.exceptions import ReportNotFoundException, AgentExecutionException
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove unused import.

AgentExecutionException is imported but never used in this file. While ReportNotFoundException is correctly used on lines 57 and 88, AgentExecutionException appears to be unused.

Apply this diff:

-from backend.app.core.exceptions import ReportNotFoundException, AgentExecutionException
+from backend.app.core.exceptions import ReportNotFoundException
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from backend.app.core.exceptions import ReportNotFoundException, AgentExecutionException
from backend.app.core.exceptions import ReportNotFoundException
🤖 Prompt for AI Agents
In backend/app/api/v1/routes.py around line 7, the import statement includes
AgentExecutionException which is not used; edit the import to remove
AgentExecutionException so only ReportNotFoundException is imported (i.e.,
change the line to import only ReportNotFoundException from
backend.app.core.exceptions).

import asyncio

router = APIRouter()
Expand All @@ -28,13 +29,23 @@ async def dummy_agent_two(report_id: str, token_id: str) -> dict:
async def read_root():
return {"message": "Welcome to API v1"}

async def _run_agents_in_background(report_id: str, token_id: str):
try:
await orchestrator_instance.execute_agents_concurrently(report_id, token_id)
except Exception as e:
api_logger.error(f"Agent execution failed for report {report_id}: {e}")
# Here you might want to update the report status to 'failed' in in_memory_reports
# For now, we'll just log it.
if report_id in in_memory_reports:
in_memory_reports[report_id]["status"] = "failed"
in_memory_reports[report_id]["detail"] = f"Agent execution failed: {e}"

@router.post("/report/generate", response_model=ReportResponse)
async def generate_report_endpoint(request: ReportRequest, background_tasks: BackgroundTasks):
api_logger.info(f"Received report generation request for token_id: {request.token_id}")
report_response = await generate_report(request)
report_id = report_response.report_id
# Execute agents concurrently in a background task
background_tasks.add_task(orchestrator_instance.execute_agents_concurrently, report_id, request.token_id)
background_tasks.add_task(_run_agents_in_background, report_id, request.token_id)
return report_response

@router.get("/reports/{report_id}/status")
Expand All @@ -43,7 +54,7 @@ async def get_report_status(report_id: str):
report = get_report_status_from_memory(report_id)
if not report:
api_logger.error(f"Report with id {report_id} not found for status request.")
raise HTTPException(status_code=404, detail="Report not found")
raise ReportNotFoundException(detail="Report not found")
return {"report_id": report_id, "status": report["status"]}

@router.get("/reports/{report_id}/data")
Expand Down Expand Up @@ -74,4 +85,4 @@ async def get_report_data_endpoint(report_id: str):
},
)
api_logger.error(f"Report with id {report_id} not found or not completed for data request.")
raise HTTPException(status_code=404, detail="Report not found or not completed")
raise ReportNotFoundException(detail="Report not found or not completed")
10 changes: 10 additions & 0 deletions backend/app/core/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

from fastapi import HTTPException, status

class ReportNotFoundException(HTTPException):
def __init__(self, detail: str = "Report not found"):
super().__init__(status_code=status.HTTP_404_NOT_FOUND, detail=detail)

class AgentExecutionException(HTTPException):
def __init__(self, detail: str = "Agent execution failed"):
super().__init__(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=detail)
49 changes: 48 additions & 1 deletion backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,59 @@

load_dotenv()

from fastapi import FastAPI
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
from backend.app.core.config import settings
from backend.app.api.v1.routes import router as v1_router
from backend.app.core.exceptions import ReportNotFoundException, AgentExecutionException
from backend.app.core.logger import api_logger

app = FastAPI(title=settings.APP_NAME, debug=settings.DEBUG)

@app.exception_handler(ReportNotFoundException)
async def report_not_found_exception_handler(request: Request, exc: ReportNotFoundException):
api_logger.error(f"ReportNotFoundException: {exc.detail}")
return JSONResponse(
status_code=exc.status_code,
content={
"message": "Report not found",
"detail": exc.detail
},
)

@app.exception_handler(AgentExecutionException)
async def agent_execution_exception_handler(request: Request, exc: AgentExecutionException):
api_logger.error(f"AgentExecutionException: {exc.detail}")
return JSONResponse(
status_code=exc.status_code,
content={
"message": "Agent execution failed",
"detail": exc.detail
},
)

@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
api_logger.error(f"HTTPException: {exc.detail} (Status Code: {exc.status_code})")
return JSONResponse(
status_code=exc.status_code,
content={
"message": exc.detail,
"detail": exc.detail
},
)

@app.exception_handler(Exception)
async def generic_exception_handler(request: Request, exc: Exception):
api_logger.exception(f"Unhandled exception: {exc}")
return JSONResponse(
status_code=500,
content={
"message": "Internal Server Error",
"detail": "An unexpected error occurred."
}
)

app.include_router(v1_router, prefix="/api/v1")

@app.get("/health")
Expand Down