creative_studio/backend/app/api/v1/async_tasks.py
2026-02-03 01:12:39 +08:00

199 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
异步任务 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
]