171 lines
5.5 KiB
Python
171 lines
5.5 KiB
Python
"""
|
||
任务参数API
|
||
包含任务输入参数相关的API接口
|
||
"""
|
||
from typing import Dict, Any, List, Optional
|
||
from fastapi import APIRouter, HTTPException, Depends, Query, Path, Request
|
||
from pydantic import BaseModel, Field
|
||
from config.task_config import (
|
||
TaskInputParamConfig,
|
||
TaskInputParamType,
|
||
SystemParamKey
|
||
)
|
||
from services.task_param_service import TaskParamService
|
||
from core.exceptions import TianfengTaskError
|
||
from api.models import (
|
||
ApiResponse, TaskInputParamModel, TaskInputParamsUpdateRequest
|
||
)
|
||
import logging
|
||
import json
|
||
|
||
# 创建日志记录器
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# 创建路由器
|
||
router = APIRouter(tags=["任务参数管理"])
|
||
|
||
# 创建服务实例
|
||
task_param_service = TaskParamService()
|
||
|
||
@router.get("/task/input-params/fields", response_model=ApiResponse)
|
||
async def get_task_param_types():
|
||
"""获取任务输入参数表单字段定义"""
|
||
try:
|
||
# 从配置中获取表单字段定义
|
||
form_fields = TaskInputParamConfig.get_input_params_form_fields()
|
||
|
||
return {
|
||
"code": 200,
|
||
"message": "获取任务输入参数表单字段定义成功",
|
||
"data": {
|
||
"form_fields": form_fields
|
||
}
|
||
}
|
||
except Exception as e:
|
||
raise HTTPException(status_code=500, detail=f"获取任务输入参数表单字段定义失败: {str(e)}")
|
||
|
||
@router.get("/task/{task_id}/input-params", response_model=ApiResponse)
|
||
async def get_task_input_params(
|
||
task_id: str = Path(..., description="任务ID"),
|
||
instance_id: str = Query(None, description="任务实例ID,不传则使用最新实例")
|
||
):
|
||
"""
|
||
获取任务输入参数配置
|
||
|
||
返回任务输入参数的配置信息,包括系统默认参数和用户自定义参数
|
||
"""
|
||
try:
|
||
# 使用任务参数服务获取参数
|
||
params, found_instance_id = task_param_service.get_task_input_params(task_id, instance_id)
|
||
|
||
return {
|
||
"code": 200,
|
||
"message": "获取任务输入参数成功",
|
||
"data": {
|
||
"task_id": task_id,
|
||
"instance_id": found_instance_id,
|
||
"params": params
|
||
}
|
||
}
|
||
except Exception as e:
|
||
raise HTTPException(status_code=500, detail=f"获取任务输入参数失败: {str(e)}")
|
||
|
||
def safe_process_default_value(param_dict: Dict[str, Any]) -> None:
|
||
"""
|
||
安全处理参数的default_value值,确保其是JSON可序列化的
|
||
|
||
Args:
|
||
param_dict: 参数字典,将被原地修改
|
||
"""
|
||
# 如果没有default_value键,不处理
|
||
if "default_value" not in param_dict:
|
||
return
|
||
|
||
default_value = param_dict["default_value"]
|
||
param_type = param_dict.get("param_type", "")
|
||
|
||
# None值保持不变
|
||
if default_value is None:
|
||
return
|
||
|
||
# 只对json和array类型做特殊处理
|
||
if param_type not in ["json", "array"]:
|
||
return
|
||
|
||
# 如果已经是字符串,尝试解析为JSON对象
|
||
if isinstance(default_value, str):
|
||
try:
|
||
param_dict["default_value"] = json.loads(default_value)
|
||
except json.JSONDecodeError:
|
||
# 解析失败保持原字符串
|
||
pass
|
||
|
||
@router.post("/task/{task_id}/input-params", response_model=ApiResponse)
|
||
async def update_task_input_params(
|
||
task_id: str = Path(..., description="任务ID"),
|
||
request: List[TaskInputParamModel] = None,
|
||
instance_id: str = Query(None, description="任务实例ID,不传则使用最新实例或创建新实例")
|
||
):
|
||
"""
|
||
更新任务输入参数配置
|
||
|
||
批量保存用户自定义的任务输入参数配置,只有点击"完成"按钮后才会生效
|
||
|
||
请求示例:
|
||
```json
|
||
[
|
||
{
|
||
"param_name": "robotId",
|
||
"label": "机器人ID",
|
||
"param_type": "string",
|
||
"required": true,
|
||
"default_value": "",
|
||
"description": "执行任务的机器人ID"
|
||
},
|
||
{
|
||
"param_name": "timeout",
|
||
"label": "超时时间",
|
||
"param_type": "integer",
|
||
"required": false,
|
||
"default_value": 3600,
|
||
"description": "任务执行的超时时间(秒)"
|
||
}
|
||
]
|
||
```
|
||
"""
|
||
try:
|
||
# 将Pydantic模型转换为字典列表,并安全处理default_value
|
||
params = []
|
||
for param in request:
|
||
param_dict = param.dict(exclude_none=True)
|
||
safe_process_default_value(param_dict)
|
||
params.append(param_dict)
|
||
|
||
# 使用任务参数服务更新参数
|
||
updated_count, found_instance_id, has_changes = task_param_service.update_task_input_params(task_id, params, instance_id)
|
||
|
||
# 根据是否有变动返回不同的消息
|
||
message = "更新任务输入参数成功" if has_changes else "任务输入参数无变动"
|
||
|
||
return {
|
||
"code": 200,
|
||
"message": message,
|
||
"data": {
|
||
"task_id": task_id,
|
||
"instance_id": found_instance_id,
|
||
"updated_params_count": updated_count,
|
||
"has_changes": has_changes
|
||
}
|
||
}
|
||
except ValueError as e:
|
||
return {
|
||
"code": 400,
|
||
"message": str(e),
|
||
"data": None
|
||
}
|
||
except Exception as e:
|
||
import traceback
|
||
error_detail = f"更新任务输入参数失败: {str(e)}\n{traceback.format_exc()}"
|
||
raise HTTPException(status_code=500, detail=error_detail)
|
||
|