from fastapi import APIRouter, Depends, Request, Response from fastapi.responses import JSONResponse from sqlalchemy.orm import Session from app.core.response import error, ok from app.db.models import User from app.db.session import get_db from app.deps import get_current_user from app.schemas.models import AnalysisTaskCreateRequest, AnalysisTaskWebhook from app.services import analysis as analysis_service router = APIRouter(prefix="/api/analysis", tags=["Analysis"]) @router.post("/tasks", status_code=201) def create_task( body: AnalysisTaskCreateRequest, request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): idempotency_key = request.headers.get("Idempotency-Key") task, err, duplicate = analysis_service.create_analysis_task( db, current_user.id, body, idempotency_key ) if err == "child_not_found": return JSONResponse( status_code=404, content=error(10004, "child_not_found", request.state.request_id), ) if err == "video_not_found": return JSONResponse( status_code=404, content=error(10006, "video_not_found", request.state.request_id), ) if err == "duplicate" and duplicate: return JSONResponse( status_code=409, content=ok( analysis_service.task_to_dict(duplicate), message="duplicate_task", request_id=request.state.request_id, ), ) return ok( analysis_service.task_to_dict(task), message="created", request_id=request.state.request_id, ) @router.get("/tasks/{task_id}") def get_task( task_id: int, request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): task = analysis_service.get_task_for_user(db, current_user.id, task_id) if not task: return JSONResponse( status_code=404, content=error(10007, "task_not_found", request.state.request_id), ) return ok(analysis_service.task_to_dict(task), request_id=request.state.request_id) @router.post("/tasks/{task_id}/cancel") def cancel_task( task_id: int, request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): task = analysis_service.cancel_task(db, current_user.id, task_id) if not task: return JSONResponse( status_code=404, content=error(10007, "task_not_found", request.state.request_id), ) return ok( {"taskId": task_id, "status": task.status}, request_id=request.state.request_id, ) @router.post("/webhook", status_code=204) def analysis_webhook(body: AnalysisTaskWebhook, db: Session = Depends(get_db)): analysis_service.handle_webhook(db, body.task_id, body.status.value) return Response(status_code=204)