199 lines
5.2 KiB
Python
199 lines
5.2 KiB
Python
"""
|
||
异步任务 API 路由
|
||
|
||
提供异步任务的创建、查询、取消等操作
|
||
"""
|
||
from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks
|
||
from typing import List, Optional, Dict, Any
|
||
|
||
from app.models.task import (
|
||
AsyncTask,
|
||
TaskCreateRequest,
|
||
TaskResponse,
|
||
TaskType,
|
||
TaskStatus
|
||
)
|
||
from app.core.task_manager import get_task_manager, TaskManager
|
||
from app.utils.logger import get_logger
|
||
|
||
logger = get_logger(__name__)
|
||
|
||
router = APIRouter(prefix="/tasks", tags=["异步任务"])
|
||
|
||
|
||
@router.post("/", response_model=TaskResponse, status_code=status.HTTP_201_CREATED)
|
||
async def create_task(
|
||
request: TaskCreateRequest,
|
||
task_manager: TaskManager = Depends(get_task_manager)
|
||
):
|
||
"""
|
||
创建新的异步任务
|
||
|
||
创建后任务会立即返回任务ID,需要通过轮询 /tasks/{task_id} 来获取任务状态和结果
|
||
"""
|
||
task = task_manager.create_task(
|
||
task_type=request.type,
|
||
params=request.params,
|
||
project_id=request.project_id
|
||
)
|
||
|
||
return TaskResponse(
|
||
id=task.id,
|
||
type=task.type,
|
||
status=task.status,
|
||
progress=task.progress,
|
||
params=task.params,
|
||
result=task.result,
|
||
error=task.error,
|
||
project_id=task.project_id,
|
||
created_at=task.created_at,
|
||
updated_at=task.updated_at
|
||
)
|
||
|
||
|
||
@router.get("/{task_id}", response_model=TaskResponse)
|
||
async def get_task(
|
||
task_id: str,
|
||
task_manager: TaskManager = Depends(get_task_manager)
|
||
):
|
||
"""获取任务详情"""
|
||
task = task_manager.get_task(task_id)
|
||
if not task:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_404_NOT_FOUND,
|
||
detail=f"任务不存在: {task_id}"
|
||
)
|
||
|
||
return TaskResponse(
|
||
id=task.id,
|
||
type=task.type,
|
||
status=task.status,
|
||
progress=task.progress,
|
||
params=task.params,
|
||
result=task.result,
|
||
error=task.error,
|
||
project_id=task.project_id,
|
||
created_at=task.created_at,
|
||
updated_at=task.updated_at
|
||
)
|
||
|
||
|
||
@router.get("/", response_model=List[TaskResponse])
|
||
async def list_tasks(
|
||
task_type: Optional[TaskType] = None,
|
||
project_id: Optional[str] = None,
|
||
status: Optional[TaskStatus] = None,
|
||
task_manager: TaskManager = Depends(get_task_manager)
|
||
):
|
||
"""
|
||
列出任务
|
||
|
||
支持按类型、项目ID、状态筛选
|
||
"""
|
||
tasks = []
|
||
|
||
if task_type:
|
||
tasks = task_manager.get_tasks_by_type(task_type)
|
||
elif project_id:
|
||
tasks = task_manager.get_tasks_by_project(project_id)
|
||
else:
|
||
# 返回所有任务(最多100个)
|
||
tasks = list(task_manager._tasks.values())[:100]
|
||
|
||
# 状态筛选
|
||
if status:
|
||
tasks = [t for t in tasks if t.status == status]
|
||
|
||
logger.info(f"list_tasks: task_type={task_type}, status={status}, found={len(tasks)} tasks")
|
||
|
||
result = [
|
||
TaskResponse(
|
||
id=t.id,
|
||
type=t.type,
|
||
status=t.status,
|
||
progress=t.progress,
|
||
params=t.params,
|
||
result=t.result,
|
||
error=t.error,
|
||
project_id=t.project_id,
|
||
created_at=t.created_at,
|
||
updated_at=t.updated_at
|
||
)
|
||
for t in tasks
|
||
]
|
||
|
||
# Log first task for debugging
|
||
if result:
|
||
logger.info(f"list_tasks: first task id={result[0].id}, status={result[0].status}, params keys={list(result[0].params.keys()) if result[0].params else 'none'}")
|
||
|
||
return result
|
||
|
||
|
||
@router.post("/{task_id}/cancel", response_model=TaskResponse)
|
||
async def cancel_task(
|
||
task_id: str,
|
||
task_manager: TaskManager = Depends(get_task_manager)
|
||
):
|
||
"""取消任务"""
|
||
success = task_manager.cancel_task(task_id)
|
||
if not success:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_404_NOT_FOUND,
|
||
detail=f"任务不存在: {task_id}"
|
||
)
|
||
|
||
task = task_manager.get_task(task_id)
|
||
return TaskResponse(
|
||
id=task.id,
|
||
type=task.type,
|
||
status=task.status,
|
||
progress=task.progress,
|
||
params=task.params,
|
||
result=task.result,
|
||
error=task.error,
|
||
project_id=task.project_id,
|
||
created_at=task.created_at,
|
||
updated_at=task.updated_at
|
||
)
|
||
|
||
|
||
@router.delete("/{task_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||
async def delete_task(
|
||
task_id: str,
|
||
task_manager: TaskManager = Depends(get_task_manager)
|
||
):
|
||
"""删除任务"""
|
||
success = task_manager.delete_task(task_id)
|
||
if not success:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_404_NOT_FOUND,
|
||
detail=f"任务不存在: {task_id}"
|
||
)
|
||
|
||
return None
|
||
|
||
|
||
@router.get("/project/{project_id}", response_model=List[TaskResponse])
|
||
async def get_project_tasks(
|
||
project_id: str,
|
||
task_manager: TaskManager = Depends(get_task_manager)
|
||
):
|
||
"""获取项目的所有任务"""
|
||
tasks = task_manager.get_tasks_by_project(project_id)
|
||
|
||
return [
|
||
TaskResponse(
|
||
id=t.id,
|
||
type=t.type,
|
||
status=t.status,
|
||
progress=t.progress,
|
||
params=t.params,
|
||
result=t.result,
|
||
error=t.error,
|
||
project_id=t.project_id,
|
||
created_at=t.created_at,
|
||
updated_at=t.updated_at
|
||
)
|
||
for t in tasks
|
||
]
|