rackham-meeting-analyzer/backend/app/api/analyses.py
2025-11-03 08:15:51 -06:00

105 lines
2.9 KiB
Python

"""
Analyses API routes.
Handles fetching analysis results and PDF generation.
"""
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.responses import Response
from motor.motor_asyncio import AsyncIOMotorDatabase
from app.core.deps import get_db, require_auth
from app.models.analysis import AnalysisResponse
from app.services.pdf import render_pdf
from app.services.history import get_history
router = APIRouter()
@router.get("/{job_id}", response_model=AnalysisResponse)
async def get_analysis(
job_id: str,
user: dict = Depends(require_auth),
db: AsyncIOMotorDatabase = Depends(get_db)
):
"""Get the analysis results for a completed job"""
analysis = await db.analyses.find_one(
{"job_id": job_id, "user_id": user["_id"]}
)
if not analysis:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Analysis not found"
)
return AnalysisResponse(
_id=analysis["_id"],
job_id=analysis["job_id"],
data=analysis["data"],
created_at=analysis["created_at"]
)
@router.get("/{job_id}/pdf")
async def get_analysis_pdf(
job_id: str,
user: dict = Depends(require_auth),
db: AsyncIOMotorDatabase = Depends(get_db)
):
"""Generate and download PDF report for an analysis"""
# Get analysis
analysis = await db.analyses.find_one(
{"job_id": job_id, "user_id": user["_id"]}
)
if not analysis:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Analysis not found"
)
# Get job for filename
job = await db.jobs.find_one({"_id": job_id})
if not job:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Job not found"
)
# Generate PDF
try:
pdf_bytes = render_pdf(analysis["data"], job["filename"])
# Return PDF
return Response(
content=pdf_bytes,
media_type="application/pdf",
headers={
"Content-Disposition": f"attachment; filename=analysis_{job_id}.pdf"
}
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to generate PDF: {str(e)}"
)
@router.get("/")
async def get_analyses_history(
range: int = 30,
user: dict = Depends(require_auth),
db: AsyncIOMotorDatabase = Depends(get_db)
):
"""
Get history of analyses for the authenticated user.
Query param 'range' can be 30, 60, or 90 (days).
"""
if range not in [30, 60, 90]:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Range must be 30, 60, or 90 days"
)
summaries = await get_history(db, user["_id"], range)
return {"summaries": summaries}