File size: 2,746 Bytes
7e431a1 |
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 |
import logging
from fastapi import APIRouter, HTTPException
from fastapi.concurrency import run_in_threadpool
from app.schemas.payload import ExecutionRequest # Ensure this import matches your project structure
from app.services.rivergen import run_rivergen_flow
# 1. Setup Structured Logging
logger = logging.getLogger("api_execution")
router = APIRouter(tags=["Execution"])
@router.post(
"/execute",
response_model=dict, # Ideally, use a strict Pydantic model here if available
summary="Execute AI Flow",
description="Processes natural language prompts via the RiverGen Engine."
)
async def execute_prompt(request: ExecutionRequest):
"""
Primary endpoint to process natural language prompts against data sources.
Uses threadpooling to prevent blocking the async event loop.
"""
request_id = request.request_id or "unknown"
logger.info(f"๐ [API] Received execution request: {request_id}")
try:
# Convert Pydantic model to dict
payload = request.model_dump()
# ------------------------------------------------------------------
# โก CRITICAL FIX: Run Blocking Code in Threadpool
# ------------------------------------------------------------------
# Since 'run_rivergen_flow' is synchronous, we offload it to a worker thread.
result = await run_in_threadpool(run_rivergen_flow, payload)
# Check logical errors from the service layer
if result.get("status") == "error" or "error" in result:
error_msg = result.get("error", "Unknown processing error")
# ๐ ๏ธ IMPROVEMENT: Extract detailed Judge feedback if available
last_feedback = result.get("last_feedback", "")
if last_feedback:
detailed_detail = f"{error_msg} \n\n๐ REASON: {last_feedback}"
else:
detailed_detail = error_msg
logger.warning(f"โ ๏ธ [API] Logic Error for {request_id}: {error_msg}")
# Return 400 Bad Request with the detailed reason
raise HTTPException(status_code=400, detail=detailed_detail)
logger.info(f"โ
[API] Success for {request_id}")
return result
except HTTPException:
# Re-raise known HTTP exceptions so they propagate correctly
raise
except Exception as e:
# ๐ SECURITY FIX: Log the real error internally, hide raw traceback from user
logger.error(f"โ [API] System Crash for {request_id}: {str(e)}", exc_info=True)
raise HTTPException(
status_code=500,
detail=f"Internal Server Error. Please contact support with Request ID: {request_id}"
) |