价格文档账号

HTTP 接口

danio 的 HTTP 接口:地址、令牌与权限、错误格式、事件流、OpenAPI 描述,以及常用接口。

danio 自己的界面、命令行、Blender 扩展、插件,以及加入工作区的设备,调用的是同一套 HTTP 接口。你写的脚本也可以用它。

接口都在 /api/v1/ 下,数据用 JSON。每个接口的参数、返回值和所需权限,都在 OpenAPI 描述里,本页只讲约定和最常用的接口。

地址

地址谁用令牌
http://127.0.0.1:7421这台电脑上的程序。端口被占用时往上找,:ui设置 → 接口 里显示实际地址本机令牌
主机的工作区地址,默认端口 7420其他电脑上的设备和脚本。主机要先对其他设备开放这个端口工作区令牌

端口的设置见本机配置。

令牌和权限

请求带上令牌:

Authorization: Bearer <令牌>
令牌能做什么从哪来
本机令牌这台电脑的引擎能做的一切,包括只在本机的接口设置 → 本机令牌 里看;也可以用 DANIO_TOKEN 固定
集成令牌只有你选的权限级别工作区详情的 插件与集成 页,或 danio workspace token add <名称> --access <级别> --integration
设备令牌设备加入工作区、渲染用,也带一个权限级别添加设备时生成,见令牌

集成令牌只在生成时显示一次,用 轮换 换新,旧的立即失效。

工作区权限有 9 项,权限级别是它们的组合:

权限能做什么
workspace.view查看项目、任务、进度、预览、设备、用量
output.download下载成片和各镜头的片段
job.submit提交任务;更新、暂停、继续、取消、重渲、删除自己提交的任务
job.manage控制所有人的任务,改队列顺序和镜头分配
project.edit新建、修改、删除项目
device.manage添加设备、批准加入申请、改设备的权限和设置、拉黑
storage.manage存储、资源包、回收
plugin.manage插件和集成令牌
workspace.manage工作区设置、备份、接管

级别 无 没有权限,:ui查看 有前两项,:ui工作站 再加 job.submit 和 project.edit,:ui管理 是全部。

OpenAPI 里每个接口的 x-required-permission 写着它要哪一项。除了上面 9 项,还有四种写法:

写法含义
public不要令牌,设备加入时用
token任何带有效令牌的请求
device只有设备令牌
local只有本机令牌

权限不够时返回 403,错误码是 forbidden,说明缺哪一项。GET /api/v1/me 返回当前令牌的身份和权限。

错误

出错时返回 application/problem+json:

{
  "type": "urn:danio:error:version-conflict",
  "title": "Conflict",
  "status": 409,
  "detail": "…"
}

type 是稳定的错误码,程序按它判断;detail 给人看,语言跟请求的 Accept-Language,没写这个头或以 zh 开头是中文,其余是英文。校验不过的字段列在 errors 里;提交检查没通过时,原因列在 checks 里。

错误码状态什么时候
invalid-request400请求本身不对
unauthorized401没带令牌,或令牌无效
forbidden403权限不够,或这个来源不被允许
not-found404找不到
conflict409和现状冲突
version-conflict409有人先更新了任务
precondition-failed412If-Match 对不上
validation-failed422字段没通过校验
check-failed422提交的检查没通过
too-many-requests429请求太多
render-limit403同时渲染的设备数已达工作区的上限
lease-ended409设备领的段已结束
lease-taken409设备领的段已交给别的设备
internal500danio 内部出错

重试和并发

  • 提交任务(POST /api/v1/jobs)、更新任务(POST /api/v1/jobs/{id}/versions)和比对草稿(POST /api/v1/jobs/{id}/versions/draft)可以带 Idempotency-Key,自己取一个值。24 小时内用同一个键重试,返回第一次的结果,不会重复登记。只有成功的结果会被记住,失败后重试会重新执行。
  • 同样这三个接口可以带 X-Danio-Request,自己取一个 ID。提交进度事件 submit.progress 带着它,你可以认出哪条是自己的。
  • 更新任务时带 baseVersion。已有更新的版本时返回 409,错误码 version-conflict,请基于最新版本重新比对。
  • 项目的读取返回 ETag,修改(PATCH /api/v1/projects/{id})时用 If-Match 带回去。别人先改过就返回 412。

列表

GET /api/v1/jobs 和 GET /api/v1/projects 分页:用 limit 指定每页多少条,返回里的 next 填进下一次请求的 cursor。next 为空就是最后一页。任务列表还能用 project(项目 ID)、name(任务名,只在项目内唯一)和 blend(Blend 文件 ID)过滤。

路径里的 {id} 只接受 ID。按名称找,用查询参数。

事件流

GET /api/v1/events 是 Server-Sent Events 长连接,需要 workspace.view:

curl -N -H "Authorization: Bearer $TOKEN" http://127.0.0.1:7421/api/v1/events

每个事件有 id、event(类型)和 data(JSON)。id 是字符串,不要当数字比较。连接每 15 秒发一行 : ping 注释,用来保活。

断线重连时,带上最后收到的 Last-Event-ID,danio 补发错过的事件。它保留最近 1024 个事件;补不上时(danio 重启过,或断开太久)先发一个 reset 事件,这时请重新读取状态。

OpenAPI 里列出的事件:

事件什么时候
submit.progress提交的进度。request 字段是你在 X-Danio-Request 里给的 ID
render.progress这台电脑渲染的进度和状态变化
queue.changed排队变了:有任务加入,或顺序变了
device.room设备磁盘空间不足、已满或已恢复
workspace.devices设备列表变了:有设备加入、离开,或改了设置、名称、权限、拉黑
workspace.join-request局域网里有设备申请加入
workspace.license授权导入或移除了
notice这台设备的窗口程序要弹的提示
window.showdanio 窗口要打开某一页
reset错过的事件补不上,请重新读取状态

流里还会有别的事件。不认识的事件类型,忽略就行。

OpenAPI 描述

完整的接口描述是 OpenAPI 3.1 的 JSON,有两种拿法:

# 命令行输出,默认中文
danio openapi > openapi.json

# 英文
danio openapi --lang en > openapi.json

# 从运行中的 danio 取,带任意有效令牌
curl -H "Authorization: Bearer $TOKEN" \
  "http://127.0.0.1:7421/api/openapi.json?lang=en" -o openapi.json

lang 可以是 zh-CN 或 en。不写时按 Accept-Language 选,规则和错误信息一样。

命令行输出里的 info.version 是 dev,运行中的 danio 给的是它自己的版本。

设置 → 接口 里的 接口文档 在界面里打开同一份描述,能直接浏览。

用 OpenAPI 的通用工具就能生成客户端,如 openapi-typescript、openapi-python-client。

常用接口

下表的权限是用工作区令牌调用时需要的。本机令牌不受限制。完整的列表和参数看 OpenAPI。

状态和身份

接口权限作用
GET /api/v1/healthtoken引擎是否在运行,返回版本和启动时间
GET /api/v1/metoken当前令牌的身份和权限
GET /api/v1/workspaceworkspace.view这台电脑当主机的工作区:名称、设置、监听的地址

项目和任务

接口权限作用
GET /api/v1/projectsworkspace.view项目列表
POST /api/v1/projectsproject.edit新建项目
GET /api/v1/projects/{id}workspace.view项目,返回 ETag
PATCH /api/v1/projects/{id}project.edit修改项目的设置,带 If-Match
GET /api/v1/jobsworkspace.view任务列表,新的在前
POST /api/v1/jobsjob.submit提交任务,一个场景一个任务
GET /api/v1/jobs/{id}workspace.view任务详情
DELETE /api/v1/jobs/{id}job.submit删除任务
POST /api/v1/jobs/{id}/pausejob.submit暂停,已渲染的帧保留
POST /api/v1/jobs/{id}/resumejob.submit继续
POST /api/v1/jobs/{id}/canceljob.submit取消
POST /api/v1/jobs/{id}/versions/draftjob.submit和最新版本比对,出更新的草稿
POST /api/v1/jobs/{id}/versionsjob.submit更新任务,生成新版本
GET /api/v1/jobs/{id}/previewworkspace.view一帧的预览,JPEG,frame 不写为最新一帧
GET /api/v1/jobs/{id}/filmsworkspace.view各版本的成片
GET /api/v1/jobs/{id}/filmoutput.download下载成片,version 不写为当前版本;还没生成时返回 404

设备和令牌

接口权限作用
GET /api/v1/devicesworkspace.view设备列表
PATCH /api/v1/devices/{id}device.manage改名称、权限,拉黑或解除拉黑
DELETE /api/v1/devices/{id}device.manage移除设备
GET /api/v1/tokensdevice.manage令牌列表
POST /api/v1/tokensdevice.manage生成令牌,完整的令牌只在这次返回
POST /api/v1/tokens/{id}/rotatedevice.manage轮换集成令牌
DELETE /api/v1/tokens/{id}device.manage作废令牌

插件

接口权限作用
GET /api/v1/pluginsplugin.manage插件列表
POST /api/v1/pluginsplugin.manage安装插件,装好后是停用的
POST /api/v1/plugins/{id}/enableplugin.manage启用,要带上它声明的权限
POST /api/v1/plugins/{id}/disableplugin.manage停用
PUT /api/v1/plugins/{id}/settingsplugin.manage改设置
GET /api/v1/jobs/{id}/handoversworkspace.view成片交给插件的情况
POST /api/v1/jobs/{id}/handovers/{plugin}/retryjob.submit重新交给插件

例子

列出任务,再暂停其中一个:

curl -H "Authorization: Bearer $TOKEN" "http://192.168.1.20:7420/api/v1/jobs?limit=20"

curl -X POST -H "Authorization: Bearer $TOKEN" \
  http://192.168.1.20:7420/api/v1/jobs/<任务 ID>/pause

这里的 192.168.1.20:7420 换成你主机的工作区地址。