45 lines
1.8 KiB
Python
45 lines
1.8 KiB
Python
"""Start processing (background) and poll status/progress."""
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException
|
|
from sqlalchemy.orm import Session as OrmSession
|
|
|
|
from ...db import models
|
|
from ...services.jobs import run_processing
|
|
from ..deps import db_dep, get_session_or_404, session_dict
|
|
|
|
router = APIRouter(prefix="/api/sessions", tags=["processing"])
|
|
|
|
|
|
@router.post("/{session_id}/process")
|
|
def start_processing(session_id: int, background: BackgroundTasks,
|
|
db: OrmSession = Depends(db_dep)) -> dict:
|
|
s = get_session_or_404(session_id, db)
|
|
if s.month_end_date is None:
|
|
raise HTTPException(400, "Set the month-end date before processing.")
|
|
valid_files = db.query(models.SessionFile).filter(
|
|
models.SessionFile.session_id == session_id).all()
|
|
if not valid_files:
|
|
raise HTTPException(400, "Upload at least one file before processing.")
|
|
if any(f.status == "invalid" for f in valid_files):
|
|
raise HTTPException(400, "One or more files failed validation; fix them before processing.")
|
|
if s.status == "processing":
|
|
raise HTTPException(409, "Already processing.")
|
|
s.status = "processing"
|
|
s.progress_stage = "Queued"
|
|
s.progress_pct = 0.0
|
|
s.error = ""
|
|
db.commit()
|
|
background.add_task(run_processing, session_id)
|
|
return {"started": True, "session_id": session_id}
|
|
|
|
|
|
@router.get("/{session_id}/status")
|
|
def status(session_id: int, db: OrmSession = Depends(db_dep)) -> dict:
|
|
s = get_session_or_404(session_id, db)
|
|
return {
|
|
"status": s.status, "stage": s.progress_stage, "pct": s.progress_pct,
|
|
"rows_done": s.progress_rows_done, "rows_total": s.progress_rows_total,
|
|
"eta_seconds": s.eta_seconds, "error": s.error, "session": session_dict(s),
|
|
}
|