Skip to content

异步任务

妙图所有图像处理接口均为异步任务。提交请求后立即返回 taskId,结果通过轮询获取。


任务生命周期

提交请求


[PENDING / 4]  ── 任务进入队列,等待处理资源


[PROCESSING / 0]  ── 任务正在处理中

  ├─→ [SUCCESS / 1]  ── 处理完成,按 resultType 读取结果 ✓
    ├─→ [FAILURE / 2]  ── 处理失败 ✗
    └─→ [CANCELLED / 3] ── 任务被取消

终态(停止轮询):1(成功)、2(失败)、3(已取消)。

status名称是否终态含义
4PENDING任务已进入队列,等待处理
0PROCESSING任务正在处理中
1SUCCESS处理完成;根据 resultTypeimageUrlstextResultexrUrls 等字段读取结果
2FAILURE处理失败,可查看 resultMetadata 获取原因
3CANCELLED任务已取消

查询任务接口

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,预览在 imagePreviewUrls
  • text:例如 to-svg,结果在 textResult
  • exr:例如 to-grayscale,结果在 exrUrls,预览在 exrPreviewUrls
字段类型说明
taskIdstring任务唯一标识,当前版本为内部任务 ID
taskTypestring任务类型,如 text2imagematting
statusinteger任务状态(见上方状态表)
progressnumber进度,0.0 ~ 1.0(仅供参考,不保证精确)
resultTypestring结果类型:image(大多数图像任务)、textto-svg 任务,SVG 内容在 textResult)、exrto-grayscale 任务,结果在 exrUrlsexrPreviewUrls
imageUrlsstring[]完整分辨率结果图 URL 列表(status=1resultType=image 时有值)
imagePreviewUrlsstring[]压缩预览图 URL,分辨率低于 imageUrls,可能先于完整图就绪
videoUrlsstring[]视频结果 URL(resultType=video 时)
videoPreviewUrlsstring[]视频预览 URL 列表
exrUrlsstring[]EXR 图像 URL 列表(resultType=exr 时,如 to-grayscale
exrPreviewUrlsstring[]EXR 预览图 URL 列表(PNG 格式)
textResultstring文本结果;resultType=text 时有值,例如 to-svg 返回 SVG XML 字符串
resultMetadatastring附加元数据;失败时通常用于描述错误原因
createTimeinteger任务创建时间(Unix 毫秒时间戳)
updateTimeinteger任务最近更新时间(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
done

Python:

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 并返回。
  • 用于计费去重记录(不保证幂等重放)。
  • 用于联系支持时定位请求(请在工单中提供 taskIdrequestId)。

建议使用 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"

妙图设计 API Beta