接入托管 ComfyUI 工作流 API 服务
ComfyUI 是一套生图领域常用的工作流(workflow)编排工具,可以方便灵活的设计图片处理工作流。无问芯穹 GenStudio 提供了 ComfyUI 工作流托管服务,用户托管工作流后,可以在业务中通过 API 调用该工作流。平台负责维护工作流的运行环境,优化算力资源、推理效率。
NOTE
- 如需总体了解云端全托管 ComfyUI 工作流的解决方案,请参考迁移到云端全托管 ComfyUI 工作流。
- 关于 API 端点的路径、参数等细节,详见 ComfyUI HTTP API 参考文档。
- 由于合规要求,本功能仅对企业级用户开放。
前置条件
请确保您已经在 GenStudio ComfyUI 托管服务上传并发布了您的工作流。如尚未将您的托管工作流发布为 API 服务,请依次完成以下操作。
此外,建议通过工作流详情页的「试运行」功能在线上完成验证,预览出图效果,保证工作流可正常运行。「试运行」抽屉界面还提供对应的 API 请求体示例(CURL)。
学习目标
本文介绍了如何接入 GenStudio ComfyUI 服务通信的 API 端点,以及 API 的主调用流程。
您将了解:
- 完整体验文生图的 API 调用流程(CURL)。
- 完整体验图生图的 API 调用流程(CURL)。
- 如何在获取托管工作流 API 的输入参数类型和范围。
- 如何在业务流程中修改工作流参数。
- 如何在获取结果图片时指定质量与格式。
ComfyUI API 服务入门
ComfyUI 托管工作流上线后即发布为 API 服务,支持通过 HTTP API 和 WebSocket 方式调用。
API 端点
GenStudio ComfyUI 服务提供了封装原始 ComfyUI HTTP 端点的新端点。以下是端点映射与 HTTP API 参考文档链接:
原始 ComfyUI 端点 | 描述 | API 端点 |
---|---|---|
POST /prompt | 提交任务(文生图示例) | POST /api/maas/comfy_task_api/prompt |
GET /history/ | 获取任务排队信息和生图结果 | POST /api/maas/comfy_task_api/get_task_info |
POST /upload/image | 上传图像 | POST /api/maas/comfy_task_api/upload/image |
/ws | 实时获取任务进度和生图结果 | /maas/api/comfy_task_ws_api/get_task_progress |
GenStudio 的 API Base URL 为 https://cloud.infini-ai.com
。
为了保障服务的稳定性及合理使用,我们对 GenStudio API 服务进行了频率限制。参见 API 频率限制。
API 鉴权设置
使用 API 服务,首先需要完成身份验证。请按照以下步骤获取您的 API 密钥:
- 复制已有的 API 密钥,或自助创建 API Key。
- 点击复制按钮获取密钥。您可能需要完成二次验证。
您将获取到一个格式为 sk-
前缀的 API 密钥,例如 sk-axbx5xcx9xAxbZyx
。在后续的 CURL 请求中,请注意在 header 中传入自己的 API 密钥。
--header 'Authorization: Bearer sk-xxxxxxxxxxxxxxxx'
API 入参范围
由于 API 服务中的「生图任务接口」(/api/maas/comfy_task_api/prompt
)定义是 基于用户上传的 ComfyUI 工作流文件动态生成的,因此,该 API 的接口定义(Schema),包括接受哪些参数、参数的数据类型、有效值范围等等,都 直接取决于用户工作流文件内部的节点配置和连接方式。
由于无法为生图任务接口提供统一的 OpenAPI 规范,为了帮助用户了解自己工作流的 API 输入要求,平台会基于您的工作流验证结果,自动生成详细的参数 Schema,即「入参范围」,其中展示工作流中各个节点的有效参数范围,例如 ckpt_name
的参数支持的 Checkpoint 列表,seed
或 的取值范围等。
您可在托管工作流的详情页获取入参范围。在通过代码集成 API 服务时,可以通过编程方式处理该数据,提取节点入参的类型、范围等。
平台会在每个可传入的参数的 spec
键下返回可接受的入参范围和默认值。
"spec": {
"default": 20,
"min": 1,
"max": 10000
}
DANGER
「入参范围」仅提供数据参考,并非 ComfyUI API 请求 Body 体。
文生图任务
如果使用 GenStudio 托管图生图工作流,API 调用流程如下:
- 提交生图请求,将文生图任务加入队列。
- 轮询任务状态,直到任务完成或失败。状态 3 表示全部图片生成结束。
- 下载当前 Workflow 生成的所有图像。
NOTE
首次体验时,可直接下载示例工作流后进行上传,无需上传自己的工作流。
在下面的流程中,我们将使用示例工作流,通过 API 提交一个文生图任务,并获取生成的图像。
文生图示例 Workflow
示例使用以下设置:
- 工作流 API JSON: ComfyUI 导出的文生图工作流
- 模型:majicMIX realistic 麦橘写实_v7.safetensors
- 采样器名称:ddim
- 调度器:karras
- 步骤:20
- cfg:7
- API 更改后的正面提示:Spiderman in a red suit standing in middle of a crowded place, skyscrapers in the background, cinematic, neon colors, realistic look
- API 更改后的负面提示:ugly, deformed
查看示例工作流 JSON 内容
{
"3": {
"inputs": {
"seed": 1,
"steps": 20,
"cfg": 7,
"sampler_name": "ddim",
"scheduler": "karras",
"denoise": 1,
"model": [
"4",
0
],
"positive": [
"6",
0
],
"negative": [
"7",
0
],
"latent_image": [
"5",
0
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"4": {
"inputs": {
"ckpt_name": "majicMIX realistic 麦橘写实_v7.safetensors"
},
"class_type": "CheckpointLoaderSimple",
"_meta": {
"title": "Load Checkpoint"
}
},
"5": {
"inputs": {
"width": 512,
"height": 512,
"batch_size": 1
},
"class_type": "EmptyLatentImage",
"_meta": {
"title": "Empty Latent Image"
}
},
"6": {
"inputs": {
"text": "a girl",
"clip": [
"4",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"7": {
"inputs": {
"text": "",
"clip": [
"4",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"4",
2
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"9": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
}
}
提交文生图任务
使用 API 提交文生图任务,需要使用 POST /api/maas/comfy_task_api/prompt 接口。JSON 请求体中的 workflow_id
为工作流 ID。prompt
对象中包含在当前请求中修改的节点参数。
DANGER
JSON 请求体中 prompt
参数的值需要根据工作流的节点 ID 和可修改参数自行构建。
- 请勿在
prompt
参数中直接传入 ComfyUI 导出的 Workflow API JSON 文件。 - 请勿在
prompt
参数中直接传入 GenStudio Workflow 「查看参数」的内容。
CURL 请求可直接从试运行工作流界面中拷贝,示例如下:
curl --request POST \
--url https://cloud.infini-ai.com/api/maas/comfy_task_api/prompt \
--header 'Accept: application/json' \
--header 'Authorization: Bearer sk-xxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"workflow_id": "wf-c73diz7kadp6ffgn",
"prompt": {
"3": {
"inputs": {
"seed": 423710630168223,
"steps": 20,
"cfg": 7,
"sampler_name": "ddim",
"scheduler": "karras",
"denoise": 1
}
},
"4": {
"inputs": {
"ckpt_name": "majicMIX realistic 麦橘写实_v7.safetensors"
}
},
"5": {
"inputs": {
"width": 512,
"height": 512,
"batch_size": 1
}
},
"6": {
"inputs": {
"text": "Rabbit in a red suit standing in middle of a crowded place, skyscrapers in the background, cinematic, neon colors, realistic look"
}
},
"7": {
"inputs": {
"text": "ugly, deformed"
}
}
}
}'
200 OK 响应示例的结构如下:
{
"code": 0,
"msg": "Success",
"data": {
"prompt_id": "cft-c73egpxvlvg76yjd",
"prompt_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiJ0ZS1iOTA1NzU0NDI3MzUyMjYxIiwidGFza19pZCI6ImNmdC1jNzZ1anllemdlcDVwY2FsIiwiaXNzIjoiaW5maW5pIiwiZXhwIjoxNzI4Njk5OTYzfQ.yrWt9_tyKYH_0lZHuFG8l76ddFGgDMV68ZqdZtRAUHA"
}
}
prompt_id
是提交任务后返回的唯一 ID,用于获取任务状态和结果。
prompt_token
用于在实时获取任务进度的 WebSocket API 中进行认证,Token 生成后 24 小时有效。
获取文生图任务状态和结果
使用 API 获取任务排队信息和生图结果,需要使用 POST /api/maas/comfy_task_api/get_task_info 接口。
CURL 请求正文示例如下:
curl --request POST \
--url https://cloud.infini-ai.com/api/maas/comfy_task_api/get_task_info \
--header 'Accept: application/json' \
--header 'Authorization: Bearer 123' \
--header 'Content-Type: application/json' \
--data '{
"comfy_task_ids": [
"cft-c73egpxvlvg76yjd"
],
"url_expire_period": 1000
}'
comfy_task_ids
可接受一个任务 ID 数组。由于生图任务是异步生成,需要轮询获取任务状态和结果。
在上面的示例中,我们只传入一个任务 ID(上一步返回的 prompt_id
)。设置 url_expire_period
为 1000,表示结果图片链接有效期为 1000 秒。
如果 200 OK 响应结果中某个任务 ID 的 "status": 3
,表示生图已成功并可通过返回的 OSS URL 获取生图结果。响应示例如下:
{
"code": 0,
"msg": "Success",
"data": {
"comfy_task_info": [
{
"comfy_task_id": "cft-c73egpxvlvg76yjd",
"status": 3,
"queue_size": 0,
"current_position": 0,
"errMsg": "",
"files": {
"9": [
"https://infini-imagegen.oss-cn-beijing.aliyuncs.com/te-b905754427352261%2Fac-c66h4ddlwutmbinv%2Fcft-c73egpxvlvg76yjd%2Fbb5c49b3-e1a8-4a46-b2ab-51aa47d9bbfc.png?Expires=1726642626\u0026OSSAccessKeyId=LTAI5tBgzFapTV38XHKZjHPa\u0026Signature=c2K4wQKbirfirwL0bgX%2FNDSF4iA%3D"
]
},
"final_files": [
"https://infini-imagegen.oss-cn-beijing.aliyuncs.com/te-b905754427352261%2Fac-c66h4ddlwutmbinv%2Fcft-c76ujyezgep5pcal%2F83f2227c-9c1a-4e6a-813b-1359e2d1867e.png?Expires=1728615208&OSSAccessKeyId=LTAI5tBgzFapTV38XHKZjHPa&Signature=V1XbMwpAYXBt8eD1FN690kKcnVk%3D"
],
"progress_num": 100
}
]
}
}
status
字段为任务状态,取值范围:1-排队中,2-生成中,3-生成成功,4-生成失败,5-权限不足。
files
字段为任务结果,其中 9
是示例工作流 中的出图的节点 ID,它的值为一个数组,数组中的每个元素是一个图片链接。final_files
字段为最终结果。progress_num
字段为任务进度,取值范围:0-100。
NOTE
关于 API 请求和响应字段的具体描述,请查看 API 接口文档 POST /api/maas/comfy_task_api/get_task_info
在使用 curl 下载文件时,URL 必须经过解码处理,因为有时 URL 包含特殊字符或编码字符,可能会导致请求失败。以下是代码示例:
# URL
url_encoded='https://infini-imagegen.oss-cn-beijing.aliyuncs.com/te-b905754427352261%2Fac-c66h4ddlwutmbinv%2Fcft-c7zd47xvlvmke3o7%2Fa2b701fd-5d4e-4aa3-b11d-ba0feb0152da.png?Expires=1725513702\u0026OSSAccessKeyId=LTAI5tBgzFapTV38XHKZjHPa\u0026Signature=%2FvJhgJceci%2FbL8nHk%2Bx%2F%2BqIroqQ%3D'
# 解码
decoded_url=$(printf '%b' "$url_encoded")
# 下载
curl -o myfile.png "$decoded_url"
以下是结果图片:
图生图任务
如果使用 GenStudio 托管图生图工作流,API 调用流程如下:
- 准备需要输入的图片。
- 调用 ComfyUI API 服务的图片上传接口,将图片上传至 GenStudio 服务,供后续提交任务时引用;
- 或者您可以自备 OSS 图片链接(阿里云/亚马逊),提交任务时直接为
LoadImage
/LoadImageMask
节点传入 OSS 图片链接。
- 提交生图请求,将图生图任务加入队列。
- 轮询任务状态,直到任务完成或失败。状态 3 表示全部图片生成结束。
- 下载当前 Workflow 生成的所有图像。
下面我们将使用示例工作流,以文生图的生成结果作为输入,通过 API 提交一个图生图任务,并获取修改后的图像。
图生图示例 Workflow
示例使用以下设置:
- 工作流 API JSON: ComfyUI 导出的图生图工作流
- 模型:majicMIX realistic 麦橘写实_v7.safetensors
- 采样器名称:ddim
- 调度器:karras
- 步骤:30
- cfg:9
- API 更改后的正面提示:Spiderwoman dressed entirely in monochromatic, pure black suit standing in middle of a crowded place, skyscrapers in the background, cinematic, neon colors, realistic look
- API 更改后的负面提示:ugly, deformed, red, reddish, blue
上传图片至 GenStudio(可选)
TIP
GenStudio 支持直接为 LoadImage
/ LoadImageMask
节点传入 OSS 图片链接。支持阿里云 OSS 与亚马逊 S3。如果您的输入图片已自行上传至第三方 OSS,则无需单独调用上传图片接口。请跳过本节,执行下一步骤。
向上传图片接口发送 CURL 请求,其中 --form
是 curl 命令中用于发送 multipart/form-data
格式数据的参数。@
符号的在 curl 命令表示这是一个文件路径,而不是普通的值。GenStudio 收到图片文件后将存入 OSS,返回 image_id
供其他接口引用。
curl --request POST \
--url https://cloud.infini-ai.com/api/maas/comfy_task_api/upload/image \
--header 'Accept: application/json' \
--header 'Authorization: Bearer sk-xxxxxxxxxxxxxxxx' \
--header 'Content-Type: multipart/form-data' \
--form source_file=@/Users/janedoe/spiderman-in-red-suit.png
示例中使用的是 macOS/Linux 的路径格式,Windows 用户需要使用不同的格式(如 C:\Users\janedoe\pictures\spiderman-in-red-suit.png)
IMPORTANT
如果您更习惯使用 Apifox/Postman 等工具,请务必正确设置 source_file
参数的类型为 file
。推荐您直接导入 GenStudio 提供的 OpenAPI 规范文件,避免手动配置接口导致错误。详见与 Apifix/Postman 集成。
200 OK 响应示例的结构如下:
{
"code": 0,
"msg": "Success",
"data": {
"image_id": "te-b905754427352261/ac-c66h4ddlwutmbinv/sui-c73eqoorz56qaq7q.png"
}
}
提交图生图任务
使用 API 提交图生图任务,需要使用 POST /api/maas/comfy_task_api/prompt 接口。JSON 请求体中的 workflow_id
为工作流 ID。prompt
对象中包含在当前请求中修改的节点参数。
DANGER
JSON 请求体中 prompt
参数的值需要根据工作流的节点 ID 和可修改参数自行构建。
- 请勿在
prompt
参数中直接传入 ComfyUI 导出的 Workflow API JSON 文件。 - 请勿在
prompt
参数中直接传入 GenStudio Workflow 「查看参数」的内容。
CURL 请求可直接从试运行工作流界面中拷贝,示例如下:
curl --request POST \
--url https://cloud.infini-ai.com/api/maas/comfy_task_api/prompt \
--header 'Accept: application/json' \
--header 'Authorization: Bearer sk-xxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"workflow_id": "wf-c73epllu4i3bxvzr",
"prompt": {
"3": {
"inputs": {
"seed": 423710630168223,
"steps": 30,
"cfg": 9,
"sampler_name": "ddim",
"scheduler": "karras",
"denoise": 0.6
}
},
"4": {
"inputs": {
"ckpt_name": "majicMIX realistic 麦橘写实_v7.safetensors"
}
},
"6": {
"inputs": {
"text": "Spiderwoman dressed entirely in monochromatic, pure black suit standing in middle of a crowded place, skyscrapers in the background, cinematic, neon colors, realistic look"
}
},
"7": {
"inputs": {
"text": "ugly, deformed, red, reddish, blue"
}
},
"10": {
"inputs": {
"image": "te-b905754427352261/ac-c66h4ddlwutmbinv/sui-c73eqoorz56qaq7q.png"
}
}
}
}'
200 OK 响应示例的结构如下:
{
"code": 0,
"msg": "Success",
"data": {
"prompt_id": "cft-c73e5ci6dwb5wfhl"
}
}
prompt_id
是提交任务后返回的唯一 ID,用于获取任务状态和结果。
获取图生图任务状态和结果
使用 API 获取任务排队信息和生图结果,需要使用 POST /api/maas/comfy_task_api/get_task_info 接口。
CURL 请求正文示例如下:
curl --request POST \
--url https://cloud.infini-ai.com/api/maas/comfy_task_api/get_task_info \
--header 'Accept: application/json' \
--header 'Authorization: Bearer sk-xxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"comfy_task_ids": [
"cft-c73e5ci6dwb5wfhl"
],
"url_expire_period": 1000
}'
comfy_task_ids
可接受一个任务 ID 数组。由于生图任务是异步生成,需要轮询获取任务状态和结果。
在上面的示例中,我们只传入一个任务 ID(上一步返回的 prompt_id
)。设置 url_expire_period
为 1000,表示结果图片链接有效期为 1000 秒。
如果 200 OK 响应结果中某个任务 ID 的 "status": 3
,表示生图已成功并可通过返回的 OSS URL 获取生图结果。响应示例如下:
{
"code": 0,
"msg": "Success",
"data": {
"comfy_task_info": [
{
"comfy_task_id": "cft-c73e5ci6dwb5wfhl",
"status": 3,
"queue_size": 0,
"current_position": 0,
"errMsg": "",
"files": {
"9": [
"https://infini-imagegen.oss-cn-beijing.aliyuncs.com/te-b905754427352261%2Fac-c66h4ddlwutmbinv%2Fcft-c73e5ci6dwb5wfhl%2F4e066af5-79df-40ab-8a2d-57012b3f94b3.png?Expires=1726654989\u0026OSSAccessKeyId=LTAI5tBgzFapTV38XHKZjHPa\u0026Signature=28hPa004ivIW4WX%2BpueVTvQcLXw%3D"
]
},
"final_files": [
"https://infini-imagegen.oss-cn-beijing.aliyuncs.com/te-b905754427352261%2Fac-c66h4ddlwutmbinv%2Fcft-c76ujyezgep5pcal%2F83f2227c-9c1a-4e6a-813b-1359e2d1867e.png?Expires=1728615208&OSSAccessKeyId=LTAI5tBgzFapTV38XHKZjHPa&Signature=V1XbMwpAYXBt8eD1FN690kKcnVk%3D"
],
"progress_num": 100
}
]
}
}
status
字段为任务状态,取值范围:1-排队中,2-生成中,3-生成成功,4-生成失败,5-权限不足。
files
字段为任务结果,其中 9
是示例工作流 中的出图的节点 ID,它的值为一个数组,数组中的每个元素是一个图片链接。final_files
字段为最终结果。progress_num
字段为任务进度,取值范围:0-100。
NOTE
关于 API 请求和响应字段的具体描述,请查看 API 接口文档 POST /api/maas/comfy_task_api/get_task_info
在使用 curl 下载文件时,URL 必须经过解码处理,因为有时 URL 包含特殊字符或编码字符,可能会导致请求失败。以下是代码示例:
# URL
url_encoded='https://infini-imagegen.oss-cn-beijing.aliyuncs.com/te-b905754427352261%2Fac-c66h4ddlwutmbinv%2Fcft-c73e5ci6dwb5wfhl%2F4e066af5-79df-40ab-8a2d-57012b3f94b3.png?Expires=1726654989\u0026OSSAccessKeyId=LTAI5tBgzFapTV38XHKZjHPa\u0026Signature=28hPa004ivIW4WX%2BpueVTvQcLXw%3D'
# 解码
decoded_url=$(printf '%b' "$url_encoded")
# 下载
curl -o spiderman-in-blue-suit.png "$decoded_url"
以下是结果图片:
实时获取任务进度
您可以使用 WebSocket API 获取并显示 ComfyUI 任务的实时进度。以下使用 Javascript 讲解基本流程。
WebSocket 连接信息
API URL:
wss://cloud.infini-ai.com/maas/api/comfy_task_ws_api/get_task_progress
鉴权 Token:
创建生图任务后,POST /api/maas/comfy_task_api/prompt 接口会返回 prompt_token
,有效期 24 小时。
Step 0 建立 WebSocket 连接
建立 WebSocket 连接时,需要发送 Token。Token 需要附加在 URL 后面,以 ?authorization=
分隔。
const promptToken = 'your_prompt_token_here'; // 替换为实际的 prompt_token
const socket = new WebSocket(`wss://cloud.infini-ai.com/api/maas/comfy_task_ws_api/get_task_progress?authorization=${promptToken}`);
socket.onopen = () => {
console.log('WebSocket 连接已建立');
};
NOTE
不支持在建立 WebSocket 连接时后发送 Token。Token 必须作为 URL 参数包含在初始连接请求中。
Step 1 接收和处理任务进度
连接建立后,会收到 WebSocket 消息事件。消息事件中包含任务进度、状态、已生成数据,您需要解析并显示进度、并获取生成的结果。
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
const taskInfo = data.comfy_task_info;
// 显示任务进度
displayTaskProgress(taskInfo);
};
function displayTaskProgress(taskInfo) {
const progressElement = document.getElementById('task-progress');
progressElement.innerHTML = `
<p>任务ID: ${taskInfo.comfy_task_id}</p>
<p>状态: ${getStatusText(taskInfo.status)}</p>
<p>进度: ${taskInfo.progress_num}%</p>
<p>队列位置: ${taskInfo.current_position} / ${taskInfo.queue_size}</p>
`;
// 当状态为3时,记录"开始生成图片"
if (taskInfo.status === 3) {
console.log("开始生成图片");
}
// 始终获取 files 中的 URL
if (taskInfo.files) {
Object.values(taskInfo.files).forEach(urls => {
displayResultFiles(urls.map(decodeAndCleanUrl));
});
}
// 只有在 progress_num 等于 100 时才获取 final_files 中的 URL
if (taskInfo.progress_num === 100 && taskInfo.final_files) {
displayResultFiles(taskInfo.final_files.map(decodeAndCleanUrl));
}
}
function getStatusText(status) {
const statusMap = {
1: '排队中',
2: '生成中',
3: '生成成功',
4: '生成失败'
};
return statusMap[status] || '未知状态';
}
function displayResultFiles(files) {
const filesElement = document.getElementById('result-files');
filesElement.innerHTML += files.map(file => `<img src="${file}" alt="结果图片">`).join('');
}
// 直接返回的 OSS 链接包含 \u 编码,请解码后使用。
function decodeAndCleanUrl(url) {
// 解码 URL
let decodedUrl = decodeURIComponent(url);
// 替换 \u 编码
decodedUrl = decodedUrl.replace(/\\u[\dA-F]{4}/gi, match =>
String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16))
);
return decodedUrl;
}
消息中的 comfy_task_info
字段的结构如下,字段描述可参考 API 文档中的 ComfyTaskInfo:
{
"comfy_task_info": {
"comfy_task_id": "cft-c76vnohm2zwmmoyj",
"status": 3,
"queue_size": 0,
"current_position": 0,
"errMsg": "",
"files": {
"9": [
"https://infini-imagegen.oss-cn-beijing.aliyuncs.com/te-b905754427352261%2Fac-c66h4ddlwutmbinv%2Fcft-c76u7vyh7k2wlozr%2F7c27a442-31f9-40e3-920c-5a5acd3816c1.png?Expires=1728644139&OSSAccessKeyId=LTAI5tBgzFapTV38XHKZjHPa&Signature=IKntIayj43Fq%2BbJ6djzxuDuAc%2Bw%3D"
]
},
"final_files": [
"https://infini-imagegen.oss-cn-beijing.aliyuncs.com/te-b905754427352261%2Fac-c66h4ddlwutmbinv%2Fcft-c76u7vyh7k2wlozr%2F7c27a442-31f9-40e3-920c-5a5acd3816c1.png?Expires=1728644139&OSSAccessKeyId=LTAI5tBgzFapTV38XHKZjHPa&Signature=IKntIayj43Fq%2BbJ6djzxuDuAc%2Bw%3D"
],
"progress_num": 100
}
}
NOTE
- 直接返回的 OSS 链接包含 \u 编码,请解码后使用。可参见示例代码中的
decodeAndCleanUrl
函数。 - 文件 URL 的有效期为 10 分钟,请及时处理或显示结果文件。
- 每次进度更新都会发送全量文件信息,注意优化界面更新逻辑,避免不必要的重绘。
- 如果达到 100 或者任务失败,连接会自动关闭。如果一直没有达到 100,连接会保持,您也可以设置一个没有进度更新的超时时间,主动断开。
- 暂不限制 WebSocket 连接数量。
图片后处理
在获取 ComfyUI 生成的图片结果时,可指定 image_post_process_cmd
参数,对图片进行实时处理。此参数会您指定的图片处理指令透传给阿里云对象存储服务 (OSS),实现图片格式转换和质量变换等操作。API Response 返回的 OSS 链接将自动包含您指定的图片处理参数,当您通过该链接访问图片时,阿里云 OSS 服务将根据参数实时处理图片并返回结果。
目前支持的处理操作:
您需要在调用 POST /api/maas/comfy_task_api/get_task_info 接口时传入 image_post_process_cmd
参数。具体结构与用法请参考 API 文档。
常见问题
支持什么 ComfyUI 节点?
平台预置的 ComfyUI 运行环境中包含部分常用模型和节点。预置环境中支持的 Checkpoint 和自定义节点: ComfyUI HTTP API 参考文档。
如果预置环境无法运行您的 Workflow,GenStudio 支持定制私有环境。请联系无问芯穹。
为何 ComfyUI 服务生图任务接口没有统一的 OpenAPI 规范?
由于 ComfyUI 工作流 API 服务的「生图任务接口」(/api/maas/comfy_task_api/prompt
)定义是 完全基于用户上传的 ComfyUI 工作流文件动态生成的,因此,该 API 的接口定义(Schema),包括接受哪些参数、参数的数据类型、有效值范围等等,都直接取决于用户工作流文件内部的节点配置和连接方式。
为何无法提供统一的 OpenAPI 规范?
与传统的 API 平台类似,ComfyUI 工作流 HTTP API 提供一份统一的 OpenAPI (Swagger) 规范文档,描述所有可用的 API 接口、请求参数、响应格式等等。
然而,对于 ComfyUI 工作流 HTTP API 的「提交生图任务」接口来说,无法在 OpenAPI 规范提供细致的参数描述,原因在于:
- 用户工作流的差异性:ComfyUI 的强大之处在于其高度的灵活性和可定制性。每个用户可以根据自己的需求,自由地设计和构建完全不同的工作流。不同的工作流会包含不同的节点、不同的参数,以及不同的输入输出结构。
- API 接口的动态生成:「生图任务接口」定义是在用户工作流文件关联环境后,平台动态分析工作流结构,并根据工作流内部的节点参数自动生成的。这意味着,每个用户上传的工作流,都会生成一套独一无二的 API 接口。
平台提供的「入参范围」的作用
为了帮助用户了解自己工作流的「生图任务接口」(/api/maas/comfy_task_api/prompt
) API 输入要求,我们的平台采取了以下方案:
- 工作流文件验证:平台会对用户上传的 ComfyUI 工作流文件进行深度验证,分析工作流的节点结构和参数信息。
- 动态生成参数 Schema:基于验证结果,平台 自动生成详细的参数 Schema。Schema 中会明确列出:
- API 接受的所有输入参数名称。
- 每个参数的数据类型 (例如,字符串、整数、浮点数、枚举值等)。
- 每个参数的有效值范围或枚举值列表 (例如,模型名称的下拉选项、数值参数的最小值/最大值等)。
- 参数的验证规则 (例如,是否必填、数据格式要求等)。
- Web 控制台展示「入参范围」:平台将生成的参数 Schema 以 **「入参范围」**的形式,直观地展示在 Web 控制台上。用户可以在工作流详情页面找到这份数据表。
如何使用「入参范围」?
这份「入参范围」 就是您特定工作流的「生图任务接口」API 入参规范说明文档。
- 了解 API 输入参数:详细列出了您的工作流 API 接受的所有输入参数,以及每个参数的名称和含义。
- 掌握参数数据类型和有效值:清晰地标明每个参数的数据类型和有效值范围 (或枚举值)。这可以帮助您构建正确的 API 请求,避免因参数类型错误或值超出范围导致的请求失败。
- 查看参数验证规则:展示参数的验证规则,例如哪些参数是必填的,哪些参数有特定的格式要求。这可以帮助您确保 API 请求的完整性和有效性。
- 编程方式读取验证规则:可一键复制 JSON 格式的「入参范围」数据,便于在代码中处理。
API 服务可以直接传入工作流 API JSON 吗?
不支持。
ComfyUI 工作流 API 服务的提交生图任务接口定义了专门的输入格式。请参考 POST /api/maas/comfy_task_api/prompt 接口构造请求体。
请勿将 ComfyUI 直接导出的 API Format JSON 作为提交生图任务接口
prompt
参数的值。GenStudio 托管工作流「入参范围」展示的 JSON 也不能直接作为该接口
prompt
参数的值。ComfyUI 工作流托管服务仅支持在控制台网页上新增托管工作流,不支持以 API 方式创建新的托管工作流。
以下 Diff 以文生图工作流为例,展示了 ComfyUI 导出的 API Format JSON(修改前)与 prompt
参数值(修改后)的差异:
{
"3": {
"inputs": {
"seed": 1,
"seed": 423710630168223,
"steps": 20,
"cfg": 7,
"sampler_name": "ddim",
"scheduler": "karras",
"denoise": 1,
"model": [
"4",
0
],
"positive": [
"6",
0
],
"negative": [
"7",
0
],
"latent_image": [
"5",
0
]
},
"class_type": "KSampler",
"_meta": {
"title": "KSampler"
}
},
"4": {
"inputs": {
"ckpt_name": "majicMIX realistic 麦橘写实_v7.safetensors"
},
"class_type": "CheckpointLoaderSimple",
"_meta": {
"title": "Load Checkpoint"
}
},
"5": {
"inputs": {
"width": 512,
"height": 512,
"batch_size": 1
},
"class_type": "EmptyLatentImage",
"_meta": {
"title": "Empty Latent Image"
}
},
"6": {
"inputs": {
"text": "a girl",
"text": "Rabbit in a red suit standing in middle of a crowded place, skyscrapers in the background, cinematic, neon colors, realistic look",
"clip": [
"4",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"7": {
"inputs": {
"text": "",
"text": "ugly, deformed",
"clip": [
"4",
1
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"3",
0
],
"vae": [
"4",
2
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE Decode"
}
},
"9": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "Save Image"
}
}
}