主题
异步任务
妙图所有图像处理接口均为异步任务。提交请求后立即返回 taskId,结果通过轮询获取。
任务生命周期
提交请求
│
▼
[PENDING / 4] ── 任务进入队列,等待处理资源
│
▼
[PROCESSING / 0] ── 任务正在处理中
│
├─→ [SUCCESS / 1] ── 处理完成,按 resultType 读取结果 ✓
├─→ [FAILURE / 2] ── 处理失败 ✗
└─→ [CANCELLED / 3] ── 任务被取消终态(停止轮询):1(成功)、2(失败)、3(已取消)。
status 值 | 名称 | 是否终态 | 含义 |
|---|---|---|---|
| 4 | PENDING | 否 | 任务已进入队列,等待处理 |
| 0 | PROCESSING | 否 | 任务正在处理中 |
| 1 | SUCCESS | 是 | 处理完成;根据 resultType 从 imageUrls、textResult、exrUrls 等字段读取结果 |
| 2 | FAILURE | 是 | 处理失败,可查看 resultMetadata 获取原因 |
| 3 | CANCELLED | 是 | 任务已取消 |
查询任务接口
http
GET /tasks/{taskId}
Authorization: Bearer tsk_live_你的令牌响应示例(处理中):
json
{
"code": 0,
"msg": "",
"data": {
"taskId": "img-abc123",
"taskType": "text2image",
"status": 0,
"progress": 0.6,
"resultType": "image",
"imageUrls": [],
"imagePreviewUrls": [],
"videoUrls": [],
"videoPreviewUrls": [],
"textResult": null,
"resultMetadata": null,
"createTime": 1748736000000,
"updateTime": 1748736010000
}
}响应示例(成功):
json
{
"code": 0,
"msg": "",
"data": {
"taskId": "img-abc123",
"taskType": "text2image",
"status": 1,
"progress": 1.0,
"resultType": "image",
"imageUrls": ["https://s3.magiqsight.com/private/..."],
"imagePreviewUrls": ["https://s3.magiqsight.com/private/..."],
"videoUrls": [],
"videoPreviewUrls": [],
"exrUrls": [],
"exrPreviewUrls": [],
"textResult": null,
"resultMetadata": null,
"createTime": 1748736000000,
"updateTime": 1748736018000
}
}响应字段说明
成功轮询到 status = 1 后,先看 resultType 再取结果:
image:多数图像任务,结果在imageUrls,预览在imagePreviewUrlstext:例如to-svg,结果在textResultexr:例如to-grayscale,结果在exrUrls,预览在exrPreviewUrls
| 字段 | 类型 | 说明 |
|---|---|---|
taskId | string | 任务唯一标识,当前版本为内部任务 ID |
taskType | string | 任务类型,如 text2image、matting |
status | integer | 任务状态(见上方状态表) |
progress | number | 进度,0.0 ~ 1.0(仅供参考,不保证精确) |
resultType | string | 结果类型:image(大多数图像任务)、text(to-svg 任务,SVG 内容在 textResult)、exr(to-grayscale 任务,结果在 exrUrls 和 exrPreviewUrls) |
imageUrls | string[] | 完整分辨率结果图 URL 列表(status=1 且 resultType=image 时有值) |
imagePreviewUrls | string[] | 压缩预览图 URL,分辨率低于 imageUrls,可能先于完整图就绪 |
videoUrls | string[] | 视频结果 URL(resultType=video 时) |
videoPreviewUrls | string[] | 视频预览 URL 列表 |
exrUrls | string[] | EXR 图像 URL 列表(resultType=exr 时,如 to-grayscale) |
exrPreviewUrls | string[] | EXR 预览图 URL 列表(PNG 格式) |
textResult | string | 文本结果;resultType=text 时有值,例如 to-svg 返回 SVG XML 字符串 |
resultMetadata | string | 附加元数据;失败时通常用于描述错误原因 |
createTime | integer | 任务创建时间(Unix 毫秒时间戳) |
updateTime | integer | 任务最近更新时间(Unix 毫秒时间戳) |
轮询建议
推荐轮询参数
- 间隔:2 秒
- 超时:5 分钟(150 次以内)
- 终止条件:
status为 1、2 或 3
轮询代码示例
Shell(Bash):
bash
TASK_ID="img-abc123"
MAX_POLLS=150
for i in $(seq 1 $MAX_POLLS); do
RESP=$(curl -s \
-H "Authorization: Bearer $TUSEN_API_TOKEN" \
"https://magiqsight.com/openapi/v1/tasks/$TASK_ID")
STATUS=$(echo "$RESP" | python3 -c \
"import sys,json; print(json.load(sys.stdin)['data']['status'])")
echo "Poll $i: status=$STATUS"
case $STATUS in
1)
echo "成功!"
echo "$RESP" | python3 -c "import sys,json; data=json.load(sys.stdin)['data']; rt=data.get('resultType'); print('resultType=', rt); print('result=', {'image': data.get('imageUrls'), 'text': data.get('textResult'), 'exr': data.get('exrUrls')}.get(rt, data))"
break ;;
2) echo "失败!"; echo "$RESP"; break ;;
3) echo "已取消"; break ;;
*) sleep 2 ;;
esac
donePython:
python
import time, requests
API_BASE = "https://magiqsight.com/openapi/v1"
TOKEN = "tsk_live_替换为你的令牌"
TASK_ID = "img-abc123"
headers = {"Authorization": f"Bearer {TOKEN}"}
for attempt in range(150):
resp = requests.get(f"{API_BASE}/tasks/{TASK_ID}", headers=headers)
resp.raise_for_status()
data = resp.json()["data"]
status = data["status"]
print(f"Poll {attempt + 1}: status={status}, progress={data.get('progress')}")
if status == 1:
result_type = data.get("resultType")
if result_type == "image":
print("成功!图像 URL:", data.get("imageUrls", []))
elif result_type == "text":
print("成功!文本结果:", data.get("textResult"))
elif result_type == "exr":
print("成功!EXR URL:", data.get("exrUrls", []))
else:
print("成功!完整返回:", data)
break
elif status in (2, 3):
print("终止。状态:", status, "元数据:", data.get("resultMetadata"))
break
time.sleep(2)
else:
print("轮询超时(5 分钟),任务仍未完成")查询不属于当前用户的任务
若 taskId 不属于当前令牌所属用户,接口返回 HTTP 403。这是预期的安全行为,任务结果不跨用户共享。
关于 requestId 和 X-Request-Id
提交图像任务时可以传入 requestId(请求体字段)或 X-Request-Id 请求头。该值:
- 随提交响应一起返回(在
data.requestId中)。若调用方未提供,服务端会自动生成一个 UUID 并返回。 - 用于计费去重记录(不保证幂等重放)。
- 用于联系支持时定位请求(请在工单中提供
taskId和requestId)。
建议使用 UUID v4 或其他唯一字符串:
bash
REQUEST_ID=$(python3 -c "import uuid; print(uuid.uuid4())")
curl -X POST \
-H "Authorization: Bearer $TUSEN_API_TOKEN" \
-H "X-Request-Id: $REQUEST_ID" \
-H "Content-Type: application/json" \
-d '{"positive": "a mountain landscape"}' \
"https://magiqsight.com/openapi/v1/image/text2image"