TraceStudio-dev/docs/server/api.md
Boshuang Zhao 5790ec164f add web v2
2026-01-10 19:08:49 +08:00

8.4 KiB
Raw Permalink Blame History

TraceStudio — 后端 API 文档server 视角)

本文件以实现代码为准,汇总了当前后端提供的 HTTP API可用于生成 OpenAPI 或 mock server。所有路径以服务器根地址为前缀路由通常被挂载在 /api 下(例如最终完整路径为 /api/files/list)。

概览

  • Backend stack: FastAPIPython 3.11+、Polars、自定义节点加载/执行框架。
  • 安全约定: 所有文件路径会经过 sanitize_path / is_safe_path 校验以防目录遍历;自定义节点文件名通过 NodeValidator.is_safe_filename 验证。

DataFrame 序列化说明

  • 字段约定: 后端在返回计算结果中会将 polars.DataFrame 序列化为一个带 __type: DataFrame 的对象以便前端预览与分页请求。
  • 结构示例:
{
  "__type": "DataFrame",
  "columns": ["col1", "col2"],
  "preview": [{"col1": 1, "col2": "a"}, ...],
  "rows": 1234
}

此格式用于 /node/preview 返回和 /graph/execute 中每个节点 outputs 的预览。preview 的长度受服务端限制(通常为 10 或 20

全局错误处理约定

  • 成功返回一般为 JSON 对象并包含 successstatus: "success"
  • 失败时使用 HTTP 错误码400/403/404/500并在 body 中提供 detail 字段;/graph/execute 在 500 时会返回更详细的 traceback 对象。

--

1) 文件与文件管理Files

说明: 文件相关接口分布在 server/file_manager.pyrouter prefix /api/files)与 server/app/api/endpoints_upload.py(被挂载到 /api,内部路径为 /files/*),两套接口在功能上有重叠,前端可以任选其一,推荐使用 /api/files/* 族。

  • GET /api/files/list — 列出目录

    • Query: pathstring, 可空,空或 / 表示根),username(可选,用于确保用户目录存在)
    • Response: `{ "path": "...", "items": [ {name,path,type,size,modified,extension}, ... ] }
    • Errors: 400路径不是目录、403路径非法、404路径不存在、500读取失败
  • POST /api/files/upload — 上传文件multipart

    • Form: file (multipart file)
    • Query: path(目标目录)、username(可选)
    • Response: { "success": true, "file": FileInfo, "message": "..." }
    • Notes: 如果同名文件已存在会自动加后缀避免覆盖(除非使用专门的 save/force 接口)。
  • POST /api/files/action — 文件基本操作

    • Body: FileAction 模型 { action, path, target?, new_name? }
    • 支持操作: move, delete, mkdir, rename
    • Response: 视操作返回 { success: true, ... } 或详细信息
  • GET /api/files/download — 下载

    • Query: path(必需)
    • Response: 返回 FileResponse (streamed)
  • GET /api/files/info — 获取文件/文件夹信息

    • Query: path(必需)
    • Response: FileInfo(或 { exists: false }

模型参考 (FileInfo, FileAction)

class FileInfo(BaseModel):
    name: str
    path: str
    type: str  # 'file' | 'folder'
    size: Optional[int]
    modified: Optional[str]
    extension: Optional[str]

class FileAction(BaseModel):
    action: str  # 'move'|'delete'|'mkdir'|'rename'
    path: str
    target: Optional[str]
    new_name: Optional[str]

实现状态: 已实现(路径清理、权限检查、用户目录创建、重命名/删除/移动、下载流)。

--

2) 图/节点Graph & Node

  • GET /api/plugins — 获取可用节点插件

    • Response: { "plugins": { class_name: metadata }, "total": N, "categories": [...] }
    • Notes: metadata 包含 display_name, category, description, inputs, outputs, param_schema, class_name 等。
  • POST /api/node/preview — 预览单个节点执行结果

    • Body: NodePreviewRequest { node: NodeSchema, limit: int = 10 }
    • NodeSchema 支持 dataparams 两种字段(兼容历史 payload
    • Response 示例:
{
  "class_name": "MyNode",
  "status": "success",
  "columns": ["a","b"],
  "preview": [{"a":1,"b":2}],
  "context": {...}
}
  • POST /api/graph/execute — 执行完整图
    • Body: GraphExecuteRequest { nodes: [NodeSchema], edges: [EdgeSchema], settings?: {} }
    • Response (成功示例):
{
  "status": "success",
  "message": "成功执行 3 个节点",
  "execution_time": 0.123,
  "results": {
    "node1": { "status": "ok", "outputs": {"out": {"__type":"DataFrame", ...}}, "error": null }
  },
  "stats": { "total_nodes": 3, "total_edges": 2, "execution_order": ["node1","node2"] }
}
  • 返回格式说明: results 为 node_id 映射;每个节点包含 status, outputs, error。如果输出为 DataFrame按上文序列化规则返回。

模型摘要 (NodeSchema, EdgeSchema, GraphExecuteRequest)

class NodeSchema(BaseModel):
    id: str
    type: str
    class_name: Optional[str]
    function: Optional[str]
    data: Optional[Dict[str,Any]]
    params: Optional[Dict[str,Any]]

class EdgeSchema(BaseModel):
    id: Optional[str]
    source: str
    target: str
    dimension_mode: str
    source_port: Optional[str]
    target_port: Optional[str]

class GraphExecuteRequest(BaseModel):
    nodes: List[NodeSchema]
    edges: List[EdgeSchema]
    settings: Optional[Dict[str,Any]]

实现状态: 已实现。注意:后端兼容旧/新 executor 返回格式(可能是 node_infos/node_results 或 node_id->info 映射)。/nodes/save 接口为占位,尚需实现持久化策略。

--

3) 自定义节点管理Custom Nodes

  • 前缀: /api/custom-nodes/*

  • GET /api/custom-nodes/list — 列出自定义节点文件(含验证状态)

  • POST /api/custom-nodes/validate — 验证节点代码(不保存)

    • Body: { code: str, filename?: str }
    • Response: { success: true, validation: { valid: bool, errors: [...] } }
  • GET /api/custom-nodes/read/{filename} — 读取节点源码

    • Response: { success: true, filename, code, size, modified }
  • POST /api/custom-nodes/save — 保存并加载节点

    • Body: { filename, code, force?: bool }
    • 行为: 验证代码后保存,支持备份与强制覆盖,保存后调用 loader 加载节点并返回 load_result
  • POST /api/custom-nodes/action — 对节点执行 load/unload/delete/rename

  • GET /api/custom-nodes/download/{filename} — 下载节点文件

  • POST /api/custom-nodes/upload — 上传节点文件(会验证并加载)

  • GET /api/custom-nodes/loaded — 返回运行时已加载类及其 metadata

  • POST /api/custom-nodes/reload-all — 重新加载所有自定义节点

  • GET /api/custom-nodes/example — 返回示例节点代码(供编辑器使用)

模型参考 (NodeValidateRequest, NodeSaveRequest, NodeActionRequest)

实现状态: 功能齐全(验证、保存、备份、加载/卸载、列出、下载)。注意:保存/上传过程会在保存前使用 validate_node_code 做静态验证并在失败时阻止加载。

--

4) 用户管理相关(简要)

  • GET /api/users/list — 返回 { users: [...], count: N }
  • POST /api/users/add — 接受 { username, display_name? },会验证用户名格式、写入 users DB 并创建用户工作区。

实现状态: 已实现(基础用户 CRUD 含创建与列表)。

--

5) 其他/占位接口

  • POST /api/nodes/save — 当前仅作占位,返回 success: true需要后续实现节点保存到文件或 DB 的策略。

--

对前端/集成测试的建议

  • 使用 NodeSchema 中的 class_name 作为后端加载的实现类标识;如果客户端只提供 data/params 中的 meta.class_name,后端也会兼容读取。
  • 推荐按 __type: DataFrame 约定解析节点输出并在前端提供 DataFrame 视图组件columns + preview + rows
  • 自定义节点上传必须在后端验证通过后才加载,前端应展示 validation 结果并要求用户确认覆盖。

--

如需我把上述模型转换为可直接导入的 OpenAPI specopenapi.json)以便一键生成 mock server 或 SDK请回复确认我会在下一步生成并附上简化 schema 片段。


引用实现: server/file_manager.py 参考实现: server/app/api/endpoints_upload.py, server/app/api/endpoints_graph.py, server/app/api/endpoints_custom_nodes.py