from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import JSONResponse from api.contracts.task_schemas import ( BrowserTaskAcceptedResponse, BrowserTaskHistoryResponse, BrowserTaskRequest, BrowserTaskResultResponse, BrowserTaskStatusResponse, ) from api.mappers.task_record_mapper import TaskRecordMapper from api.routes.dependencies import get_task_service from api.services.protocols import TaskServiceProtocol router = APIRouter(prefix="/api/browser", tags=["browser-tasks"]) @router.post("/tasks", response_model=BrowserTaskAcceptedResponse, status_code=202) async def create_task( payload: BrowserTaskRequest, service: TaskServiceProtocol = Depends(get_task_service), ) -> BrowserTaskAcceptedResponse: rec = await service.submit_task(task=payload.task.strip(), timeout=payload.timeout, metadata=payload.metadata) return TaskRecordMapper.to_task_accepted(rec) @router.get("/tasks/{task_id}", response_model=BrowserTaskStatusResponse) async def get_task_status(task_id: str, service: TaskServiceProtocol = Depends(get_task_service)) -> BrowserTaskStatusResponse: rec = await service.get_task(task_id) if rec is None: raise HTTPException(status_code=404, detail="Task not found") return TaskRecordMapper.to_task_status(rec) @router.get("/tasks/{task_id}/result", response_model=BrowserTaskResultResponse) async def get_task_result( task_id: str, service: TaskServiceProtocol = Depends(get_task_service), ) -> JSONResponse | BrowserTaskResultResponse: rec = await service.get_task(task_id) if rec is None: raise HTTPException(status_code=404, detail="Task not found") if TaskRecordMapper.is_active_status(rec.status): pending = TaskRecordMapper.to_pending_task_result(rec) return JSONResponse(status_code=202, content=pending.model_dump(mode="json")) return TaskRecordMapper.to_task_result(rec) @router.get("/tasks/{task_id}/history", response_model=BrowserTaskHistoryResponse) async def get_task_history( task_id: str, service: TaskServiceProtocol = Depends(get_task_service), ) -> JSONResponse | BrowserTaskHistoryResponse: rec = await service.get_task(task_id) if rec is None: raise HTTPException(status_code=404, detail="Task not found") if TaskRecordMapper.is_active_status(rec.status): pending = TaskRecordMapper.to_pending_task_history(rec) return JSONResponse(status_code=202, content=pending.model_dump(mode="json")) return TaskRecordMapper.to_task_history(rec)