|
- # api/routes/sessions.py
- from typing import Dict
-
- from fastapi import APIRouter, Depends, HTTPException
- from loguru import logger
-
- from ...datamodel import Message, Run, Session
- from ..deps import get_db
-
- router = APIRouter()
-
-
- @router.get("/")
- async def list_sessions(user_id: str, db=Depends(get_db)) -> Dict:
- """List all sessions for a user"""
- response = db.get(Session, filters={"user_id": user_id})
- return {"status": True, "data": response.data}
-
-
- @router.get("/{session_id}")
- async def get_session(session_id: int, user_id: str, db=Depends(get_db)) -> Dict:
- """Get a specific session"""
- response = db.get(Session, filters={"id": session_id, "user_id": user_id})
- if not response.status or not response.data:
- raise HTTPException(status_code=404, detail="Session not found")
- return {"status": True, "data": response.data[0]}
-
-
- @router.post("/")
- async def create_session(session: Session, db=Depends(get_db)) -> Dict:
- """Create a new session"""
- response = db.upsert(session)
- if not response.status:
- raise HTTPException(status_code=400, detail=response.message)
- return {"status": True, "data": response.data}
-
-
- @router.put("/{session_id}")
- async def update_session(session_id: int, user_id: str, session: Session, db=Depends(get_db)) -> Dict:
- """Update an existing session"""
- # First verify the session belongs to user
- existing = db.get(Session, filters={"id": session_id, "user_id": user_id})
- if not existing.status or not existing.data:
- raise HTTPException(status_code=404, detail="Session not found")
-
- # Update the session
- response = db.upsert(session)
- if not response.status:
- raise HTTPException(status_code=400, detail=response.message)
-
- return {"status": True, "data": response.data, "message": "Session updated successfully"}
-
-
- @router.delete("/{session_id}")
- async def delete_session(session_id: int, user_id: str, db=Depends(get_db)) -> Dict:
- """Delete a session"""
- db.delete(filters={"id": session_id, "user_id": user_id}, model_class=Session)
- return {"status": True, "message": "Session deleted successfully"}
-
-
- @router.get("/{session_id}/runs")
- async def list_session_runs(session_id: int, user_id: str, db=Depends(get_db)) -> Dict:
- """Get complete session history organized by runs"""
-
- try:
- # 1. Verify session exists and belongs to user
- session = db.get(Session, filters={"id": session_id, "user_id": user_id}, return_json=False)
- if not session.status:
- raise HTTPException(status_code=500, detail="Database error while fetching session")
- if not session.data:
- raise HTTPException(status_code=404, detail="Session not found or access denied")
-
- # 2. Get ordered runs for session
- runs = db.get(Run, filters={"session_id": session_id}, order="asc", return_json=False)
- if not runs.status:
- raise HTTPException(status_code=500, detail="Database error while fetching runs")
-
- # 3. Build response with messages per run
- run_data = []
- if runs.data: # It's ok to have no runs
- for run in runs.data:
- try:
- # Get messages for this specific run
- messages = db.get(Message, filters={"run_id": run.id}, order="asc", return_json=False)
- if not messages.status:
- logger.error(f"Failed to fetch messages for run {run.id}")
- # Continue processing other runs even if one fails
- messages.data = []
-
- run_data.append(
- {
- "id": str(run.id),
- "created_at": run.created_at,
- "status": run.status,
- "task": run.task,
- "team_result": run.team_result,
- "messages": messages.data or [],
- }
- )
- except Exception as e:
- logger.error(f"Error processing run {run.id}: {str(e)}")
- # Include run with error state instead of failing entirely
- run_data.append(
- {
- "id": str(run.id),
- "created_at": run.created_at,
- "status": "ERROR",
- "task": run.task,
- "team_result": None,
- "messages": [],
- "error": f"Failed to process run: {str(e)}",
- }
- )
-
- return {"status": True, "data": {"runs": run_data}}
-
- except HTTPException:
- raise # Re-raise HTTP exceptions
- except Exception as e:
- logger.error(f"Unexpected error in list_messages: {str(e)}")
- raise HTTPException(status_code=500, detail="Internal server error while fetching session data") from e
|