任务生命周期
Tripo API 的生成类接口均采用异步任务模式。提交请求后返回 task_id,通过轮询查询任务状态和结果。
状态机
queued → running → success
→ failed
→ cancelled
状态说明
| 状态 | 说明 | progress |
|---|---|---|
queued |
任务已创建,排队等待处理 | 0 |
running |
任务正在处理中 | 0–100 |
success |
任务完成,output 字段可用 |
100 |
failed |
任务失败,通常是服务端问题,请联系支持 | — |
banned |
输入内容违反内容政策 | — |
expired |
任务已过期,输出文件不再可用 | — |
cancelled |
任务已被取消 | — |
任务流程
1. 创建任务 (POST /v3/generation/*)
↓
2. 返回 task_id
↓
3. 轮询状态 (GET /v3/tasks/{task_id})
↓
4a. status=success → 获取 output 中的下载链接
4b. status=failed → 检查错误信息,联系支持
4c. status=banned → 修改输入内容后重新提交
积分冻结模型
Tripo 采用「冻结-扣除」的积分模型,确保用户不会为失败的任务付费:
| 阶段 | 积分变化 | 说明 |
|---|---|---|
| 创建任务 | 冻结对应积分 | 从可用余额中预扣,进入冻结状态 |
| 任务成功 | 冻结积分转为已消耗 | 正式扣除 |
| 任务失败 | 冻结积分退回 | 退还到可用余额 |
| 任务取消 | 冻结积分退回 | 退还到可用余额 |
查询当前余额和冻结积分:
Bash
-cmd">curl -X GET https://openapi.tripo3d.ai/v3/account/balance \
-H "Authorization: Bearer {api_key}"
JSON
{
"code": 0,
"data": {
"balance": 10000,
"frozen": 200
}
}
轮询建议
- 轮询间隔:每 1–2 秒查询一次
- 使用
progress字段展示进度:值为 0–100 的整数 - 设置超时:建议设置最大轮询时间(如 5 分钟),超时后提示用户稍后查看
- 批量任务使用
POST /v3/tasks/list:减少请求次数
Python 轮询示例
Python
import time
import requests
def wait_for_task(task_id, api_key, interval=2, timeout=300):
url = f"https://openapi.tripo3d.ai/v3/tasks/{task_id}"
headers = {"Authorization": f"Bearer {api_key}"}
start = time.time()
while time.time() - start < timeout:
response = requests.get(url, headers=headers)
task = response.json()["data"]
status = task["status"]
progress = task.get("progress", 0)
print(f"[{task_id}] {status} ({progress}%)")
if status == "success":
return task["output"]
if status in ("failed", "cancelled", "banned"):
raise Exception(f"任务终止: {status}")
time.sleep(interval)
raise TimeoutError(f"任务 {task_id} 超时")
JavaScript 轮询示例
JavaScript
async function waitForTask(taskId, apiKey, interval = 2000, timeout = 300000) {
const url = `https://openapi.tripo3d.ai/v3/tasks/${taskId}`;
const headers = { "Authorization": `Bearer ${apiKey}` };
const start = Date.now();
while (Date.now() - start < timeout) {
const response = await fetch(url, { headers });
const { data: task } = await response.json();
const { status, progress = 0 } = task;
console.log(`[${taskId}] ${status} (${progress}%)`);
if (status === "success") return task.output;
if (["failed", "cancelled", "banned"].includes(status)) {
throw new Error(`任务终止: ${status}`);
}
await new Promise(resolve => setTimeout(resolve, interval));
}
throw new Error(`任务 ${taskId} 超时`);
}