reports.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks
  2. from fastapi.responses import FileResponse
  3. from sqlalchemy.orm import Session
  4. from typing import List
  5. import os
  6. from backend.app.core.database import get_db
  7. from backend.app.api import deps
  8. from backend.app.models import sql_models
  9. from backend.app.schemas import schemas
  10. from backend.app.services.report_service import ReportService
  11. router = APIRouter()
  12. def generate_report_task(report_id: int, db: Session):
  13. # BackgroundTasks creates a new thread, so we need a new DB session if the passed one is closed?
  14. # Actually, Depends(get_db) session is closed after request.
  15. # Better to create a new session or handle it carefully.
  16. # For simplicity here, we'll instantiate ReportService which needs a session.
  17. # But since this runs in background, we should probably handle session lifecycle manually
  18. # or rely on the fact that if we pass the db session, it might be closed.
  19. # best practice: create new session scope inside the background task.
  20. from backend.app.core.database import SessionLocal
  21. db_bg = SessionLocal()
  22. try:
  23. service = ReportService(db_bg, report_id)
  24. service.generate_pdf()
  25. finally:
  26. db_bg.close()
  27. @router.post("/", response_model=schemas.DutyReport)
  28. def create_report(
  29. report_in: schemas.DutyReportCreate,
  30. background_tasks: BackgroundTasks,
  31. db: Session = Depends(get_db),
  32. current_user: sql_models.User = Depends(deps.get_current_user)
  33. ):
  34. # Use current user name if reporter name is not provided
  35. if not report_in.reporter_name:
  36. report_in.reporter_name = current_user.username
  37. db_report = sql_models.DutyReport(
  38. reporter_name=report_in.reporter_name,
  39. start_time=report_in.start_time,
  40. end_time=report_in.end_time,
  41. status="pending"
  42. )
  43. db.add(db_report)
  44. db.commit()
  45. db.refresh(db_report)
  46. background_tasks.add_task(generate_report_task, db_report.id, db)
  47. return db_report
  48. @router.get("/", response_model=List[schemas.DutyReport])
  49. def read_reports(
  50. skip: int = 0,
  51. limit: int = 10,
  52. db: Session = Depends(get_db),
  53. current_user: sql_models.User = Depends(deps.get_current_user)
  54. ):
  55. reports = db.query(sql_models.DutyReport).order_by(sql_models.DutyReport.created_at.desc()).offset(skip).limit(limit).all()
  56. return reports
  57. @router.get("/{report_id}/download")
  58. def download_report(
  59. report_id: int,
  60. db: Session = Depends(get_db),
  61. current_user: sql_models.User = Depends(deps.get_current_user)
  62. ):
  63. report = db.query(sql_models.DutyReport).filter(sql_models.DutyReport.id == report_id).first()
  64. if not report:
  65. raise HTTPException(status_code=404, detail="Report not found")
  66. if report.status != "completed":
  67. raise HTTPException(status_code=400, detail="Report is not ready yet")
  68. if not report.file_path or not os.path.exists(report.file_path):
  69. raise HTTPException(status_code=404, detail="Report file not found")
  70. return FileResponse(report.file_path, filename=os.path.basename(report.file_path), media_type='application/pdf')