Files
Uni-Lab-OS/docs/developer_guide/http_api.md
2025-11-26 19:03:31 +08:00

8.4 KiB
Raw Blame History

HTTP API 指南

本文档介绍如何通过 HTTP API 与 Uni-Lab-OS 进行交互,包括查询设备、提交任务和获取结果。

概述

Uni-Lab-OS 提供 RESTful HTTP API允许外部系统通过标准 HTTP 请求控制实验室设备。API 基于 FastAPI 构建,默认运行在 http://localhost:8002

基础信息

  • Base URL: http://localhost:8002/api/v1
  • Content-Type: application/json
  • 响应格式: JSON

通用响应结构

{
    "code": 0,
    "data": { ... },
    "message": "success"
}
字段 类型 说明
code int 状态码0 表示成功
data object 响应数据
message string 响应消息

快速开始

以下是一个完整的工作流示例:查询设备 → 获取动作 → 提交任务 → 获取结果。

步骤 1: 获取在线设备

curl -X GET "http://localhost:8002/api/v1/online-devices"

响应示例:

{
  "code": 0,
  "data": {
    "online_devices": {
      "host_node": {
        "device_key": "/host_node",
        "namespace": "",
        "machine_name": "本地",
        "uuid": "xxx-xxx-xxx",
        "node_name": "host_node"
      }
    },
    "total_count": 1,
    "timestamp": 1732612345.123
  },
  "message": "success"
}

步骤 2: 获取设备可用动作

curl -X GET "http://localhost:8002/api/v1/devices/host_node/actions"

响应示例:

{
  "code": 0,
  "data": {
    "device_id": "host_node",
    "actions": {
      "test_latency": {
        "type_name": "unilabos_msgs.action._empty_in.EmptyIn",
        "type_name_convert": "unilabos_msgs/action/_empty_in/EmptyIn",
        "action_path": "/devices/host_node/test_latency",
        "goal_info": "{}",
        "is_busy": false,
        "current_job_id": null
      },
      "create_resource": {
        "type_name": "unilabos_msgs.action._resource_create_from_outer_easy.ResourceCreateFromOuterEasy",
        "action_path": "/devices/host_node/create_resource",
        "goal_info": "{res_id: '', device_id: '', class_name: '', ...}",
        "is_busy": false,
        "current_job_id": null
      }
    },
    "action_count": 5
  },
  "message": "success"
}

动作状态字段说明:

字段 说明
type_name 动作类型的完整名称
action_path ROS2 动作路径
goal_info 动作参数模板
is_busy 动作是否正在执行
current_job_id 当前执行的任务 ID如果繁忙

步骤 3: 提交任务

curl -X POST "http://localhost:8002/api/v1/job/add" \
  -H "Content-Type: application/json" \
  -d '{"device_id":"host_node","action":"test_latency","action_args":{}}'

请求体:

{
  "device_id": "host_node",
  "action": "test_latency",
  "action_args": {}
}

请求参数说明:

字段 类型 必填 说明
device_id string 目标设备 ID
action string 动作名称
action_args object 动作参数(根据动作类型不同而变化)

响应示例:

{
  "code": 0,
  "data": {
    "jobId": "b6acb586-733a-42ab-9f73-55c9a52aa8bd",
    "status": 1,
    "result": {}
  },
  "message": "success"
}

任务状态码:

状态码 含义 说明
0 UNKNOWN 未知状态
1 ACCEPTED 任务已接受,等待执行
2 EXECUTING 任务执行中
3 CANCELING 任务取消中
4 SUCCEEDED 任务成功完成
5 CANCELED 任务已取消
6 ABORTED 任务中止(设备繁忙或执行失败)

步骤 4: 查询任务状态和结果

curl -X GET "http://localhost:8002/api/v1/job/b6acb586-733a-42ab-9f73-55c9a52aa8bd/status"

响应示例(执行中):

{
  "code": 0,
  "data": {
    "jobId": "b6acb586-733a-42ab-9f73-55c9a52aa8bd",
    "status": 2,
    "result": {}
  },
  "message": "success"
}

响应示例(执行完成):

{
  "code": 0,
  "data": {
    "jobId": "b6acb586-733a-42ab-9f73-55c9a52aa8bd",
    "status": 4,
    "result": {
      "error": "",
      "suc": true,
      "return_value": {
        "avg_rtt_ms": 103.99,
        "avg_time_diff_ms": 7181.55,
        "max_time_error_ms": 7210.57,
        "task_delay_ms": -1,
        "raw_delay_ms": 33.19,
        "test_count": 5,
        "status": "success"
      }
    }
  },
  "message": "success"
}

注意: 任务结果在首次查询后会被自动删除,请确保保存返回的结果数据。

API 端点列表

设备相关

端点 方法 说明
/api/v1/online-devices GET 获取在线设备列表
/api/v1/devices GET 获取设备配置
/api/v1/devices/{device_id}/actions GET 获取指定设备的可用动作
/api/v1/devices/{device_id}/actions/{action_name}/schema GET 获取动作参数 Schema
/api/v1/actions GET 获取所有设备的可用动作

任务相关

端点 方法 说明
/api/v1/job/add POST 提交新任务
/api/v1/job/{job_id}/status GET 查询任务状态和结果

资源相关

端点 方法 说明
/api/v1/resources GET 获取资源列表

常见动作示例

test_latency - 延迟测试

测试系统延迟,无需参数。

curl -X POST "http://localhost:8002/api/v1/job/add" \
  -H "Content-Type: application/json" \
  -d '{"device_id":"host_node","action":"test_latency","action_args":{}}'

create_resource - 创建资源

在设备上创建新资源。

curl -X POST "http://localhost:8002/api/v1/job/add" \
  -H "Content-Type: application/json" \
  -d '{
    "device_id": "host_node",
    "action": "create_resource",
    "action_args": {
        "res_id": "my_plate",
        "device_id": "host_node",
        "class_name": "Plate",
        "parent": "deck",
        "bind_locations": {"x": 0, "y": 0, "z": 0}
    }
}'

错误处理

设备繁忙

当设备正在执行其他任务时,提交新任务会返回 status: 6ABORTED

{
  "code": 0,
  "data": {
    "jobId": "xxx",
    "status": 6,
    "result": {}
  },
  "message": "success"
}

此时应等待当前任务完成后重试,或使用 /devices/{device_id}/actions 检查动作的 is_busy 状态。

参数错误

{
    "code": 2002,
    "data": { ... },
    "message": "device_id is required"
}

轮询策略

推荐的任务状态轮询策略:

import requests
import time

def wait_for_job(job_id, timeout=60, interval=0.5):
    """等待任务完成并返回结果"""
    start_time = time.time()

    while time.time() - start_time < timeout:
        response = requests.get(f"http://localhost:8002/api/v1/job/{job_id}/status")
        data = response.json()["data"]

        status = data["status"]
        if status in (4, 5, 6):  # SUCCEEDED, CANCELED, ABORTED
            return data

        time.sleep(interval)

    raise TimeoutError(f"Job {job_id} did not complete within {timeout} seconds")

# 使用示例
response = requests.post(
    "http://localhost:8002/api/v1/job/add",
    json={"device_id": "host_node", "action": "test_latency", "action_args": {}}
)
job_id = response.json()["data"]["jobId"]
result = wait_for_job(job_id)
print(result)

相关文档