Qwen-Image 图片生成 API
图片生成 API 基于 Qwen-Image,提供异步图片生成、任务管理、参考图上传和服务配置查询能力。支持文生图和参考图生图(最多 10 张参考图),可开启提示词智能优化,输出保留透明通道的 PNG 图片。
创建任务后,使用任务 ID 轮询生成状态,成功后通过结果 URL 下载 PNG 图片。
接口总览
共包含 8 个接口,其中积分套餐查询与 MiniMax H3 共用:
| 功能 | 方法 | 路径 |
|---|---|---|
| 查询服务配置与价格 | GET | /image/v1/config |
| 创建图片生成任务 | POST | /image/v1/tasks |
| 查询单个任务 | GET | /image/v1/tasks/{task_id} |
| 查询任务列表 | GET | /image/v1/tasks |
| 取消任务 | POST | /image/v1/tasks/{task_id}/cancel |
| 删除任务 | DELETE | /image/v1/tasks/{task_id} |
| 获取参考图上传地址 | POST | /image/v1/upload_urls |
| 登记参考图素材 | POST | /image/v1/assets |
| 查询积分套餐包 | GET | /minimax/v2/query/point_packages |
接入信息
请求地址
https://cp.compshare.cn身份认证
使用与 MiniMax H3 相同的模型 API Key,以 sk-ml- 开头:
- 进入优云智算视频工作台 。
- 点击左侧工具栏中的 API 按钮,打开 API 密钥窗口。
- 创建或复制模型 API Key,并在调用时携带以下请求头:
Authorization: Bearer <YOUR_API_KEY>图片任务和参考图素材归属于 API Key 对应的顶级组织。同组织的工作台用户和模型 API Key 共享这些资源及积分余额。组织归属由平台鉴权确定,请求中无需填写账号或组织 ID。
公共请求约定
| 名称 | 必填 | 描述 |
|---|---|---|
| Authorization | 是 | Bearer <YOUR_API_KEY> |
| Content-Type | 条件必填 | 携带 JSON 请求体时必须为 application/json |
| Accept | 否 | 建议设置为 application/json |
| Idempotency-Key | 条件必填 | 创建图片生成任务时必填,去除首尾空白后为 1~128 个字符 |
- 请求和成功响应使用本文定义的
snake_case字段;不支持的请求体字段会报错。 - 时间戳均为 Unix 秒级时间戳;文件大小单位为字节。
- 同一组织的模型 API 调用,重复使用相同幂等键创建任务时会返回已创建的任务,不会重复创建或重复扣费。请求超时后应使用原键重试;创建新任务时使用新的键,建议使用 UUID。
- 图片生成采用轮询查询模式。任务创建成功响应为 JSON,生成结果为 PNG 文件。
推荐调用流程
- 查询服务配置与价格,确认
available=true且积分余额足够。 - 需要参考图时,先完成「获取上传地址 → PUT 上传文件 → 登记素材」,取得
asset_id。 - 创建图片生成任务,保存返回的
task_id。 - 每隔 3 秒查询一次任务,直到状态为
succeeded、failed、cancelled或blocked。 - 成功后从
task.output_url下载 PNG 图片。
查询服务配置与价格
GET https://cp.compshare.cn/image/v1/config无查询参数和请求体。返回当前图片生成服务的可用状态、价格和功能开关。
curl 'https://cp.compshare.cn/image/v1/config' \
-H 'Authorization: Bearer <YOUR_API_KEY>'响应参数
| 名称 | 类型 | 描述 |
|---|---|---|
| available | Boolean | 当前可否创建图片生成任务 |
| unavailable_reason | String | 不可用时的说明,可用时为空字符串 |
| price_version | String | 当前价格版本;价格未配置时为 null |
| prices | Object | 各分辨率档位价格,1K、2K 两个键;未配置的档位为 null |
| prices.1K.base | Integer | 1K 每张图片的基础积分 |
| prices.1K.per_reference | Integer | 1K 每张参考图额外增加的积分 |
| prices.2K.base | Integer | 2K 每张图片的基础积分 |
| prices.2K.per_reference | Integer | 2K 每张参考图额外增加的积分 |
| moderation_available | Boolean | 提示词审核服务是否可用;为 false 时整体 available=false |
| reference_moderation_available | Boolean | 参考图审核是否可用;为 false 时含参考图的任务不可创建 |
| prompt_optimization_available | Boolean | 提示词智能优化是否可用 |
| prompt_optimization_default_enabled | Boolean | 平台配置的优化默认开关,API 调用以请求中的 optimize_prompt 为准 |
{
"available": true,
"unavailable_reason": "",
"price_version": "3",
"prices": {
"1K": {"base": 6, "per_reference": 2},
"2K": null
},
"moderation_available": true,
"reference_moderation_available": true,
"prompt_optimization_available": true,
"prompt_optimization_default_enabled": false
}prices 中档位为 null 表示该档位暂未开放,创建对应分辨率的任务会被拒绝。
计费规则
积分费用按任务(每张图片)计算:
单张积分费用 = base + per_reference × 参考图张数- 纯文生图按
base计费;每多一张参考图加收per_reference。例如 1K 档位携带 2 张参考图时,单张费用为6 + 2 × 2 = 10积分。 - 创建任务时预占积分,成功后扣除,失败、取消或审核拦截后释放。
- 图片与 MiniMax H3、语音共用组织积分余额;余额查询见查询积分余额。
- 价格由平台动态调整,以接口返回值为准。
创建图片生成任务
POST https://cp.compshare.cn/image/v1/tasks每次请求创建一个任务,输出一张 PNG 图片。请求头必须包含 Idempotency-Key。
请求参数
| 名称 | 类型 | 必填 | 描述 | 示例值 |
|---|---|---|---|---|
| prompt | String | 是 | 原始提示词,最多 7000 个 Unicode 字符;不能只有空白,原始文字始终原样保存 | 一只戴着宇航头盔的猫,月球表面,电影感 |
| optimize_prompt | Boolean | 否 | 是否开启提示词智能优化,默认 false;实际生成文本通过任务的 effective_prompt 返回 | true |
| aspect_ratio | String | 否 | 宽高比:1:1、4:3、3:4、3:2、2:3、16:9、9:16;默认 1:1 | 16:9 |
| resolution | String | 否 | 分辨率档位:1K 或 2K,默认 2K | 2K |
| reference_images | Array of Object | 否 | 参考图,最多 10 张,按传入顺序生效,结构见下表 | [{"asset_id":"<ASSET_ID>"}] |
参考图引用
| 名称 | 类型 | 必填 | 描述 |
|---|---|---|---|
| reference_images[].asset_id | String | 是 | 通过登记参考图素材接口获取的素材 ID |
输出尺寸
输出像素尺寸由宽高比和分辨率档位决定,参考图尺寸和提示词中的尺寸描述均不会改变输出规格:
| 宽高比 | 1K(宽 × 高) | 2K(宽 × 高) |
|---|---|---|
| 1:1 | 1024 × 1024 | 2048 × 2048 |
| 4:3 | 1200 × 896 | 2400 × 1792 |
| 3:4 | 896 × 1200 | 1792 × 2400 |
| 3:2 | 1264 × 848 | 2528 × 1696 |
| 2:3 | 848 × 1264 | 1696 × 2528 |
| 16:9 | 1376 × 768 | 2752 × 1536 |
| 9:16 | 768 × 1376 | 1536 × 2752 |
文生图示例
curl -X POST 'https://cp.compshare.cn/image/v1/tasks' \
-H 'Authorization: Bearer <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: image-text-001' \
-d '{
"prompt": "一只戴着宇航头盔的猫,漂浮在月球表面,地球在背景中升起,电影感光影",
"optimize_prompt": true,
"aspect_ratio": "16:9",
"resolution": "1K"
}'参考图生图示例
curl -X POST 'https://cp.compshare.cn/image/v1/tasks' \
-H 'Authorization: Bearer <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: image-reference-001' \
-d '{
"prompt": "将图 1 中的角色放入图 2 的场景,保持角色服装不变,水彩风格",
"aspect_ratio": "1:1",
"resolution": "1K",
"reference_images": [
{"asset_id": "<ASSET_ID_1>"},
{"asset_id": "<ASSET_ID_2>"}
]
}'响应参数
| 名称 | 类型 | 描述 |
|---|---|---|
| task_id | String | 任务 ID,用于查询、取消和删除任务 |
{"task_id": "019xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}创建时由平台自动携带当前价格版本。提交与计费之间价格发生调整时,请求会被拒绝且不会创建任务;使用原 Idempotency-Key 重试即可按新价格提交。
查询单个任务
GET https://cp.compshare.cn/image/v1/tasks/{task_id}路径参数 task_id 为创建接口返回的任务 ID,无请求体。
curl 'https://cp.compshare.cn/image/v1/tasks/<TASK_ID>' \
-H 'Authorization: Bearer <YOUR_API_KEY>'响应参数
| 名称 | 类型 | 描述 |
|---|---|---|
| task | Object | 任务详情 |
| task.task_id | String | 任务 ID |
| task.status | String | 任务状态,见下文任务状态表 |
| task.can_cancel | Boolean | 当前是否可取消 |
| task.input | Object | 规范化后的生成参数,包含生效的默认值 |
| task.input.prompt | String | 用户原始提示词,包括换行和首尾空白 |
| task.input.optimize_prompt | Boolean | 是否开启了提示词优化 |
| task.input.aspect_ratio | String | 宽高比 |
| task.input.resolution | String | 分辨率档位,1K 或 2K |
| task.input.width | Integer | 输出宽度,单位为像素 |
| task.input.height | Integer | 输出高度,单位为像素 |
| task.input.output_format | String | 固定为 png |
| task.input.reference_images | Array of Object | 有序参考图数组,无参考图时为 [] |
| task.input.reference_images[].asset_id | String | 素材 ID |
| task.input.reference_images[].url | String | 参考图访问地址 |
| task.input.reference_images[].name | String | 文件名 |
| task.input.reference_images[].width | Integer | 图片宽度,单位为像素 |
| task.input.reference_images[].height | Integer | 图片高度,单位为像素 |
| task.input.reference_images[].size | Integer | 文件大小,单位为字节 |
| task.effective_prompt | String | 实际用于生成的提示词;关闭优化时与原始提示词相同,优化进行中时可能暂不返回 |
| task.prompt_optimization | Object | 提示词优化信息 |
| task.prompt_optimization.id | String | 优化记录 ID,未开启时不返回 |
| task.prompt_optimization.status | String | disabled 未开启、waiting_moderation、not_started、pending、running 优化中、succeeded 已生效、fallback 已回退为原文、cancelled 已取消 |
| task.prompt_optimization.message | String | 优化结果说明,无说明时不返回 |
| task.point_cost | Integer | 本任务的积分费用 |
| task.point_status | String | reserved 已预占、consumed 已扣除、released 已释放 |
| task.output_url | String | 生成图片的下载 URL,成功前不返回 |
| task.output_size | Integer | 生成图片大小,单位为字节,未生成时不返回 |
| task.error_code | String | 稳定错误码,见下文错误处理;无错误时不返回 |
| task.error_message | String | 失败或审核拦截原因,无错误时不返回 |
| task.moderation_scope | String | 审核范围:original_prompt 纯文本、original_prompt_and_references 含参考图 |
| task.moderation_stage | String | 审核期间为 text 或 references,表示当前审核阶段 |
| task.created_at | Integer | 创建时间 |
| task.started_at | Integer | 开始执行时间,尚未开始时不返回 |
| task.finished_at | Integer | 结束时间,尚未结束时不返回 |
响应示例
{
"task": {
"task_id": "019xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "succeeded",
"can_cancel": false,
"input": {
"prompt": "一只戴着宇航头盔的猫,漂浮在月球表面",
"optimize_prompt": true,
"aspect_ratio": "16:9",
"resolution": "1K",
"width": 1376,
"height": 768,
"output_format": "png",
"reference_images": []
},
"effective_prompt": "一只戴着宇航头盔的猫,漂浮在月球表面,地球在背景中缓缓升起,电影感光影,细节丰富",
"prompt_optimization": {"id": "<OPTIMIZATION_ID>", "status": "succeeded"},
"point_cost": 6,
"point_status": "consumed",
"output_url": "https://example.com/generated/output.png",
"output_size": 3200000,
"created_at": 1789459200,
"started_at": 1789459203,
"finished_at": 1789459250
}
}生成图片长期保留,可在控制台素材库中管理;主动删除任务后,结果文件会被删除。output_url 支持跨域读取,可直接用于浏览器预览和下载,下载原始文件即可获得完整透明通道。
查询任务列表
GET https://cp.compshare.cn/image/v1/tasks查询参数
| 名称 | 类型 | 必填 | 描述 | 示例值 |
|---|---|---|---|---|
| offset | Integer | 否 | 从 0 开始的偏移量,默认 0 | 0 |
| limit | Integer | 否 | 每页数量,范围 1~100,默认 20 | 20 |
| task_id | String | 否 | 精确筛选任务 ID | <TASK_ID> |
| statuses | String(可重复) | 否 | 按任务状态筛选,多次传入表示匹配任一状态 | queued |
| start_time | Integer | 否 | 创建时间下界,包含边界;0 或省略表示不限制 | 1789459200 |
| end_time | Integer | 否 | 创建时间上界,包含边界;0 或省略表示不限制;同时指定时须不小于 start_time | 1789545600 |
| sort | String | 否 | latest 最新优先(默认)或 oldest 最早优先 | latest |
已删除的任务不出现在列表中。
curl 'https://cp.compshare.cn/image/v1/tasks?offset=0&limit=20&statuses=queued&statuses=generating' \
-H 'Authorization: Bearer <YOUR_API_KEY>'响应参数
| 名称 | 类型 | 描述 |
|---|---|---|
| items | Array of Object | 当前页任务,元素字段与单任务查询的 task 相同 |
| total | Integer | 符合全部筛选条件的任务总数 |
| status_counts | Object | 各状态任务数;应用组织、任务 ID 和时间筛选,但不受 statuses 和分页影响;没有任务的状态可能不返回 |
例如,当前筛选没有排队或生成中的任务,但有 3 个已成功任务时:
{"items": [], "total": 0, "status_counts": {"succeeded": 3}}取消任务
POST https://cp.compshare.cn/image/v1/tasks/{task_id}/cancel路径参数 task_id 为待取消任务 ID,无请求体。仅 moderating、prompt_queued、prompt_optimizing、queued 状态可取消(即任务的 can_cancel=true),取消后释放该任务预占的积分。已经开始生成或已经结束的任务会返回业务错误。
curl -X POST 'https://cp.compshare.cn/image/v1/tasks/<TASK_ID>/cancel' \
-H 'Authorization: Bearer <YOUR_API_KEY>'成功响应中的 cancelled=true 表示取消成功:
{"task_id": "019xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "cancelled": true}删除任务
DELETE https://cp.compshare.cn/image/v1/tasks/{task_id}路径参数 task_id 为待删除任务 ID,无请求体。任务必须处于 succeeded、failed 或 cancelled,且积分已经结算;审核拦截的 blocked 任务不开放删除。删除后任务不再出现在查询结果中,生成文件会被删除,已消费积分不会因删除而退回。
curl -X DELETE 'https://cp.compshare.cn/image/v1/tasks/<TASK_ID>' \
-H 'Authorization: Bearer <YOUR_API_KEY>'成功响应中的 deleted=true 表示删除成功:
{"task_id": "019xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "deleted": true}获取参考图上传地址
POST https://cp.compshare.cn/image/v1/upload_urls文件要求
- 支持 JPG、JPEG、PNG、WebP,文件扩展名和
content_type必须匹配。 - 单个文件上限为 30 MiB(31457280 字节)。
- 上传原始图片,平台不进行缩放或裁剪,透明通道完整保留。
| 文件扩展名 | content_type |
|---|---|
.jpg、.jpeg | image/jpeg |
.png | image/png |
.webp | image/webp |
请求参数
| 名称 | 类型 | 必填 | 描述 | 示例值 |
|---|---|---|---|---|
| file_name | String | 是 | 参考图文件名 | reference.png |
| content_type | String | 是 | 文件 MIME 类型 | image/png |
| file_size | Integer | 是 | 实际文件大小,必须大于 0 | 240000 |
curl -X POST 'https://cp.compshare.cn/image/v1/upload_urls' \
-H 'Authorization: Bearer <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{"file_name":"reference.png","content_type":"image/png","file_size":240000}'响应参数
| 名称 | 类型 | 描述 |
|---|---|---|
| object_key | String | 上传对象标识,登记素材时原样传入 |
| upload_url | String | 用于 PUT 上传的地址 |
| authorization | String | PUT 上传时必须携带的 Authorization 请求头值 |
| bucket | String | 存储桶名称,PUT 上传时作为 bucket 请求头传入 |
| region | String | 存储地域,PUT 上传时作为 ufile_indicated_region 请求头传入 |
{
"object_key": "ai-image/production/uploads/<OWNER>/<UPLOAD_ID>/staging/ai-image-xxxx.png",
"upload_url": "https://example.com/upload/ai-image-xxxx.png",
"authorization": "UCloud <PUBLIC_KEY>:<SIGNATURE>",
"bucket": "<BUCKET>",
"region": "<REGION>"
}上传文件
使用返回的 upload_url 执行 PUT,Content-Type 必须与申请时一致,并携带返回的签名请求头:
curl --fail-with-body -X PUT '<UPLOAD_URL>' \
-H 'Content-Type: image/png' \
-H 'Authorization: <AUTHORIZATION>' \
-H 'bucket: <BUCKET>' \
-H 'ufile_indicated_region: <REGION>' \
--data-binary '@reference.png'上传使用返回的临时签名,无需携带模型 API Key。上传成功后再登记素材。
登记参考图素材
POST https://cp.compshare.cn/image/v1/assets在 PUT 上传成功后调用,平台校验上传记录、实际文件大小、MIME 类型和图片真实宽高,再生成用于图片任务的 asset_id。
请求参数
| 名称 | 类型 | 必填 | 描述 | 示例值 |
|---|---|---|---|---|
| object_key | String | 是 | 获取上传地址接口返回的对象标识 | <OBJECT_KEY> |
| file_name | String | 是 | 与申请上传时相同的文件名 | reference.png |
| content_type | String | 是 | 与申请上传时相同的 MIME 类型 | image/png |
| file_size | Integer | 是 | 与申请上传时相同的实际文件大小 | 240000 |
| width | Integer | 是 | 图片实际宽度,单位为像素,须与图片真实宽高一致 | 1024 |
| height | Integer | 是 | 图片实际高度,单位为像素,须与图片真实宽高一致 | 768 |
curl -X POST 'https://cp.compshare.cn/image/v1/assets' \
-H 'Authorization: Bearer <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"object_key": "<OBJECT_KEY>",
"file_name": "reference.png",
"content_type": "image/png",
"file_size": 240000,
"width": 1024,
"height": 768
}'响应参数
| 名称 | 类型 | 描述 |
|---|---|---|
| reference | Object | 参考图信息 |
| reference.asset_id | String | 素材 ID,创建任务时作为 reference_images[].asset_id 使用 |
| reference.url | String | 登记后素材的访问地址 |
| reference.name | String | 文件名 |
| reference.width | Integer | 图片宽度,单位为像素 |
| reference.height | Integer | 图片高度,单位为像素 |
| reference.size | Integer | 文件大小,单位为字节 |
{
"reference": {
"asset_id": "<ASSET_ID>",
"url": "https://example.com/reference/reference.png",
"name": "reference.png",
"width": 1024,
"height": 768,
"size": 240000
}
}登记后的素材进入组织共享素材库,长期保留,可在控制台素材库中管理和删除;上传参考图不消耗图片生成积分,但占用组织共享存储容量。
查询积分套餐包
GET https://cp.compshare.cn/minimax/v2/query/point_packages复用 MiniMax H3 的积分套餐查询接口,查询当前组织已经领取或购买的积分套餐;无查询参数和请求体。
curl 'https://cp.compshare.cn/minimax/v2/query/point_packages' \
-H 'Authorization: Bearer <YOUR_API_KEY>'响应字段说明参见 MiniMax H3 视频任务 API — 查询积分套餐包和查询积分余额。
任务状态与错误处理
任务状态
| 状态 | 含义 | 调用方处理 |
|---|---|---|
moderating | 提示词与参考图审核中 | 继续轮询,或调用取消接口 |
prompt_queued | 提示词优化排队中 | 继续轮询,或调用取消接口 |
prompt_optimizing | 提示词优化执行中 | 继续轮询,或调用取消接口 |
queued | 生成排队中 | 继续轮询,或调用取消接口 |
generating | 图片生成中 | 继续轮询 |
uploading | 结果上传中 | 继续轮询 |
succeeded | 生成成功 | 从 output_url 下载图片 |
failed | 生成失败 | 查看 error_code 和 error_message;需重新生成时使用新的幂等键 |
cancelled | 已取消 | 停止轮询 |
blocked | 审核拦截,未进入生成 | 查看 error_code 和 error_message,调整提示词或参考图后使用新的幂等键重新提交 |
新任务的初始状态为 moderating:先审核原始提示词,任务含参考图时继续审核全部参考图,通过后进入提示词优化(如开启)或生成队列。
常见错误码
| error_code | 含义 | 处理建议 |
|---|---|---|
prompt_moderation_blocked | 提示词未通过审核 | 调整提示词后重新提交 |
prompt_moderation_unassessable | 提示词无法评估 | 调整提示词后重新提交 |
prompt_moderation_failed、prompt_moderation_timeout | 审核服务异常或超时 | 使用新的幂等键重新提交 |
reference_moderation_blocked | 参考图未通过审核 | 更换参考图后重新提交 |
reference_moderation_unassessable | 参考图无法评估 | 更换参考图后重新提交 |
reference_moderation_failed、reference_moderation_timeout | 参考图审核异常或超时 | 使用新的幂等键重新提交 |
失败、取消和审核拦截的任务预占积分会自动释放,可在积分流水中查看对应记录。
请求错误
鉴权失败返回 HTTP 401;OpenAPI 参数格式错误返回 HTTP 400;下游服务连接或响应解析失败返回 HTTP 502。参数格式错误示例:
{
"type": "error",
"error": {
"type": "bad_request_error",
"message": "Idempotency-Key is required and must contain 1 to 128 characters",
"http_code": "400"
},
"request_id": "<REQUEST_ID>"
}业务后端的错误会保留原 HTTP 状态和响应体,常见字段为 RetCode、Message、request_uuid。即使 HTTP 状态为 200,只要 RetCode 非零,也表示请求失败。下游 HTTP 错误也可能返回非 JSON 内容。
| 情况 | 处理建议 |
|---|---|
| 提示词、宽高比、分辨率或参考图参数不符合要求 | 根据 Message 修正请求 |
| 积分不足 | 查询可用积分并补充积分 |
| 组织存储空间已满 | 清理不需要的任务和文件后重试 |
| 价格版本已调整 | 使用原 Idempotency-Key 重试,自动按新价格提交 |
| 任务或素材不存在 | 检查 ID、所属组织及资源是否已删除 |
| 上传信息不匹配 | 确认文件名、MIME 类型、文件大小、宽高与申请上传时一致 |
| 取消时任务已经开始执行 | 查询最新任务状态 |
| 删除尚未结束或积分未结算的任务 | 等待任务结束后再删除 |
| 创建请求超时或连接中断 | 保留并复用原 Idempotency-Key 重试 |
完整调用示例
以下 Python 示例使用标准库完成「查配置与价格 → 创建任务 → 轮询 → 下载」。先设置环境变量 COMPSHARE_API_KEY。
import json
import os
import time
import uuid
from pathlib import Path
from urllib.request import Request, urlopen
BASE_URL = "https://cp.compshare.cn"
API_KEY = os.environ["COMPSHARE_API_KEY"]
def api(method, path, body=None, idempotency_key=None):
headers = {"Authorization": f"Bearer {API_KEY}", "Accept": "application/json"}
data = None
if body is not None:
headers["Content-Type"] = "application/json"
data = json.dumps(body, ensure_ascii=False).encode("utf-8")
if idempotency_key:
headers["Idempotency-Key"] = idempotency_key
request = Request(BASE_URL + path, data=data, headers=headers, method=method)
# 非 2xx 响应由 urlopen 抛出 HTTPError;2xx 响应仍需检查业务错误。
with urlopen(request, timeout=60) as response:
result = json.load(response)
if result.get("RetCode", 0) != 0 or "error" in result:
raise RuntimeError(result)
return result
config = api("GET", "/image/v1/config")
if not config["available"]:
raise RuntimeError(config.get("unavailable_reason") or "图片生成当前不可用")
price = (config["prices"].get("1K") or {}).get("base")
if price is None:
raise RuntimeError("1K 档位价格未配置")
# 保存此键;若创建请求超时,应使用同一键和相同请求重试。
idempotency_key = str(uuid.uuid4())
print("Idempotency-Key:", idempotency_key)
result = api("POST", "/image/v1/tasks", {
"prompt": "一只戴着宇航头盔的猫,漂浮在月球表面,地球在背景中升起,电影感光影",
"optimize_prompt": True,
"aspect_ratio": "16:9",
"resolution": "1K",
}, idempotency_key=idempotency_key)
task_id = result["task_id"]
print("task_id:", task_id)
deadline = time.monotonic() + 1200
while time.monotonic() < deadline:
task = api("GET", f"/image/v1/tasks/{task_id}")["task"]
if task["status"] == "succeeded":
# 下载公共结果地址时无需携带模型 API Key。
with urlopen(task["output_url"], timeout=60) as image:
Path("image.png").write_bytes(image.read())
print("已保存 image.png,消耗积分:", task["point_cost"])
break
if task["status"] in {"failed", "cancelled", "blocked"}:
raise RuntimeError(task.get("error_message") or task["status"])
time.sleep(3)
else:
raise TimeoutError(f"轮询超时,可继续查询任务 {task_id}")