通过 API 使用托管 ComfyUI 工作流
ComfyUI 是一套生图领域常用的工作流(workflow)编排工具,可以方便灵活的设计图片处理工作流。无问芯穹 GenStudio 提供了 ComfyUI 工作流托管服务,用户托管工作流后,可以在业务中通过 API 调用该工作流。平台负责维护工作流的运行环境,优化算力资源、推理效率。
NOTE
- 如需总体了解云端全托管 ComfyUI 工作流的解决方案,请参考迁移到云端全托管 ComfyUI 工作流。
- 关于 API 端点的路径、参数等细节,详见 ComfyUI HTTP API 参考文档。
- 由于合规要求,本功能仅对企业级用户开放。
简介
本文介绍了如何接入 GenStudio ComfyUI 服务通信的 API 端点,以及 API 的主调用流程。
您将了解:
- 如何在 GenStudio 中创建托管的 ComfyUI 工作流。
- 完整体验文生图的 API 调用流程(CURL)。
- 完整体验图生图的 API 调用流程(CURL)。
- 如何在获取托管工作流 API 的输入参数类型和范围。
- 如何在业务流程中修改工作流参数。
NOTE
我们还提供了一个实践教程 使用 Python 接入 GenStudio 托管 ComfyUI 工作流 API,结合 Python 代码演示了部分数据预处理、API 对接和获取结果的流程。
快捷体验
如果您仅希望快速体验 ComfyUI 工作流的云端托管和 API 调用功能,我们提供了一组预置的示例工作流。无需上传自己的工作流文件,您可以直接选用这些示例工作流,立即开始体验工作流在网页端的运行效果,并尝试通过 API 调用工作流。待您熟悉整个流程后,再开始上传和托管自己的工作流。
如果您仅希望快捷体验完整流程,可移步以下文档:
托管 ComfyUI 工作流
托管工作流是指将本地以开发好的 ComfyUI 工作流上传至 GenStudio 平台。
导出 API Format 工作流
请在 ComfyUI 中使用 "Save(API Format)" 保存工作流。若无此选项,需在设置中启用 "Enable Dev Mode options"。
上传 API Format 工作流
前往 GenStudio 托管工作流的管理界面,上传从 ComfyUI 导出的 API JSON 格式文件以创建工作流。
平台会校验您的工作流中的节点参数,通过校验表示托管成功,平台会生成工作流 ID。
NOTE
如果校验不通过,请检查工作流是否符合以下要求:
- 通过 ComfyUI 的 Save(API Format)导出的工作流文件。
- 工作流中使用的自定义节点和模型是否在 GenStudio 托管 ComfyUI 工作流支持的列表中。
- 是否需要上传自己的 ComfyUI 模型资产至 GenStudio。
通过上述步骤,我们已完成在 ComfyUI 中的处理。后续在搭建 API 流程时,我们将使用 GenStudio 平台,获取工作流 ID 和工作流参数。
支持的自定义节点和模型
GenStudio 托管 ComfyUI 工作流已预置部分自定义节点和 Checkpoint,完整列表请参考 ComfyUI HTTP API 参考文档。
NOTE
如果您需要的自定义节点不在此列表中,欢迎联系无问芯穹。
上传我的模型资产
除使用预置的模型外,现已支持在工作流中使用自行上传的 Checkpoint 模型、VAE、LoRA 等。我们提供安全可靠的模型资产管理功能,通过加密传输和严格的访问控制确保您的模型安全。导入后的私有模型仅您可见,仅可以在您的工作流中便捷调用。
试运行工作流
工作流校验通过后,您可以从工作流列表中点击该工作流,进入以下详情页。在详情页的参数预览标签页,支持输入少量关键参数,以及上传图片。点击试运行,即可在详情页右侧预览结果及对应的 API 请求体示例。
NOTE
试运行仅用于验证工作流是否可以正常运行,以及验证效果是否和本地一致。完整的工作流调试请在您本地的 ComfyUI 中进行。
查看 API 入参范围
GenStudio 的 ComfyUI 服务会对您上传的工作流中进行校验,并为工作流中的每个节点返回有效参数的范围(供您在对接时参考),例如 ckpt_name
的参数支持的 Checkpoint 列表,seed
或 seed
的取值范围等。
您可以在 GenStudio 托管工作流的管理界面,点击工作流右侧的查看参数,获取参数有效取值范围。通过 API 调用工作流时,如果发生参数错误,可在此对照输入参数的类型、范围等。
平台会在每个可传入的参数的 spec
键下返回可接受的入参范围和默认值。
"spec": {
"default": 20,
"min": 1,
"max": 10000
}
API 鉴权设置
使用 API 服务,首先需要完成身份验证。请按照以下步骤获取您的 API 密钥:
- 复制已有的 API 密钥,或自助创建 API Key。
- 点击复制按钮获取密钥。您可能需要完成二次验证。
您将获取到一个格式为 sk-
前缀的 API 密钥,例如 sk-axbx5xcx9xAxbZyx
。在后续的 CURL 请求中,请注意在 header 中传入自己的 API 密钥。
--header 'Authorization: Bearer sk-xxxxxxxxxxxxxxxx'
API 端点
GenStudio ComfyUI 服务提供了封装原始 ComfyUI HTTP 端点的新端点。以下是端点映射:
原始 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 | 实时获取任务进度和生图结果 | /mass/api/comfy_task_api/get_task_progress |
GenStudio 的 API Base URL 为 https://cloud.infini-ai.com
。
为了保障服务的稳定性及合理使用,我们对 GenStudio API 服务进行了频率限制。参见 API 频率限制。
文生图任务
如果使用 GenStudio 托管图生图工作流,API 调用流程如下:
- 提交生图请求,将文生图任务加入队列。
- 轮询任务状态,直到任务完成或失败。状态 3 表示全部图片生成结束。
- 下载当前 Workflow 生成的所有图像。
NOTE
首次体验时,可直接下载示例工作流后进行上传,无需上传自己的工作流。
在下面的流程中,我们将使用示例工作流,通过 API 提交一个文生图任务,并获取生成的图像。
文生图示例介绍
示例使用以下设置:
- 上传的工作流: 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 调用流程如下:
- 调用图片上传接口,将图片提供给 GenStudio,获取 GenStudio 返回的图片 ID。
- 提交生图请求,在 Load Image 节点传入图片 ID,将图生图任务加入队列。
- 轮询任务状态,直到任务完成或失败。状态 3 表示全部图片生成结束。
- 下载当前 Workflow 生成的所有图像。
NOTE
首次体验时,可直接下载示例工作流后进行上传,无需上传自己的工作流。
在下面的流程中,我们将使用示例工作流,以文生图的生成结果作为输入,通过 API 提交一个图生图任务,并获取修改后的图像。
图生图示例介绍
示例使用以下设置:
- 上传的工作流: 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
使用以下 CURL 请求向 GenStudio 发送文件。其中 --form
是 curl 命令中用于发送 multipart/form-data
格式数据的参数。@
符号的在 curl 命令表示这是一个文件路径,而不是普通的值。
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"
以下是结果图片:
获取 ComfyUI 任务的实时进度
您可以使用 WebSocket API 获取并显示 ComfyUI 任务的实时进度。以下使用 Javascript 讲解基本流程。
WebSocket 连接信息
API URL:
wss://cloud.infini-ai.com/mass/api/comfy_task_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/mass/comfy_task_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 节点?
我们预置了部分常用节点。如果您的 Workflow 中使用了不受支持的 ComfyUI 节点,将无法通过 Workflow API JSON 校验。
查看已支持的 Checkpoint 和自定义节点: ComfyUI HTTP API 参考文档。
如果您需要更多节点,请联系 GenStudio 团队。
API Format JSON 可以直接传入 API 吗?
不可以。您需要手动构造 POST /api/maas/comfy_task_api/prompt 接口 prompt
参数的值。
NOTE
- ComfyUI 直接导出的 API Format JSON 不能直接作为该接口
prompt
参数的值。 - GenStudio 托管工作流「查看参数」展示的 JSON 也不能直接作为该接口
prompt
参数的值。
以下 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"
}
}
}