Python调用ComfyOne示例
OnethingAI
发布于:2025-06-12
示例工作流文件 test_flow.json(与Python脚本文件,放在同一目录下)
1.9 KB
# -*- coding: utf-8 -*-
import requests
import json
import base64
from PIL import Image
import io
import time
import os
# This is a demo script showcasing the basic functionality of ComfyOne API
# It demonstrates how to:
# - Register a new backend instance with the ComfyOne service
# - Handle API responses and error cases
# - Implement retry logic for robust API communication
#
# Usage:
# Simply run this script directly: python generate_image.py
# The script will create a demo instance and attempt to register it with the service
# Constants
BASE_URL = "https://pandora-server-cf.onethingai.com"
# 请求 comfyone API
def request_comfyone_api(api: str, payload: dict, method: str, api_key: str) -> dict | None:
"""
向ComfyOne API发送请求的通用函数
Args:
api: comfyone API路径
payload: 请求体数据,可以为None
method: HTTP请求方法(GET, POST等)
api_key: onethingai 开发者密钥
Returns:
dict: API响应数据
None: 请求失败时返回None
"""
url = f"{BASE_URL}/{api}"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
try:
retry_count = 0
max_retries = 3
while retry_count < max_retries:
try:
if payload:
response = requests.request(method, url, headers=headers, json=payload, timeout=5)
else:
response = requests.request(method, url, headers=headers, timeout=5)
response.raise_for_status()
return response.json()
except requests.exceptions.Timeout:
retry_count += 1
if retry_count == max_retries:
raise
time.sleep(2 ** retry_count) # Exponential backoff
continue
except requests.exceptions.RequestException as e:
print(str(e))
retry_count += 1
if retry_count == max_retries:
return {"error": str(e)}
time.sleep(2 ** retry_count)
continue
except Exception as e:
print(f"Error requesting {api}: {e}")
return None
# 查询可用后端
def get_available_backends(api_key: str) -> dict | None:
"""
查询所有可用的ComfyOne后端服务实例
Args:
api_key (str): onethingai开发者密钥
Returns:
dict: 包含可用后端列表的响应数据
None: 查询失败时返回None
"""
api = "v1/backends"
headers = {
"Authorization": f"Bearer {api_key}"
}
return request_comfyone_api(api, None, "GET", api_key)
# 注册实例
def register_comfyone_backend(instance_id: str, api_key: str) -> str | None:
"""
注册一个新的实例作为ComfyOne后端服务。
该函数将提供的实例ID添加到ComfyOne后端管理系统中,
使其能够处理图像生成请求和工作流处理。
参数:
instance_id (str): 要注册的实例的唯一标识符
api_key (str): onethingai开发者密钥
返回:
str或None: 如果成功注册为后端则返回实例ID,失败则返回None
"""
api = "v1/backends"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
payload = {
"instance_id": instance_id
}
return request_comfyone_api(api, payload, "POST", api_key)
# 创建工作流
def create_workflow(api_key: str, name: str, inputs: dict, outputs: dict, workflow_file: str):
"""
创建一个新的工作流。
该函数将创建一个新的工作流配置,包含输入参数、输出节点和工作流定义。
参数:
api_key (str): onethingai开发者密钥
name (str): 工作流名称
inputs (dict): 工作流输入参数配置
outputs (dict): 工作流输出节点配置
workflow_file (str): 工作流定义文件路径
返回:
dict: API响应数据,包含工作流ID等信息
None: 创建失败时返回None
"""
api = "v1/workflows"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
with open(workflow_file, 'r', encoding='utf-8-sig') as f:
#print(f.read())
workflow_data = json.load(f)
payload = {
"name": name,
"inputs": inputs,
"outputs": outputs,
"workflow": workflow_data
}
return request_comfyone_api(api, payload, "POST", api_key)
def prompt_comfyone(payload: dict, api_key: str) -> str | None:
"""
向ComfyOne API发送prompt请求。
该函数用于向已创建的工作流发送具体的生成参数。
参数:
payload (dict): prompt请求参数,包含工作流ID和具体的生成参数
api_key (str): onethingai开发者密钥:w
返回:
str或None: 如果请求成功返回任务ID,失败返回None
"""
# API endpoint
api = f"v1/prompts"
# Request headers
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
return request_comfyone_api(api, payload, "POST", api_key)
# Usage example
if __name__ == "__main__":
# 以下演示了ComfyOne API的基本使用流程:
# 1. 设置API密钥和实例ID,确保API密钥和实例ID正确,注意密钥安全,不要泄露
# 2. 查询可用后端,如果实例未注册则进行注册,确保至少有一个后端可用
# 3. 创建工做流
# 4. 构造prompt参数并调用API生成结果
API_KEY = "onethingai-api-key" # 替换为你的实际API密钥
INSTANCE_ID = "onethingai-instance-id" # 替换为你的实际实例ID
inputs = [
{'id': '5', 'type': 'number', 'name': 'height'}, # 输入节点的字段配置
{'id': '5', 'type': 'number', 'name': 'width'}] # 注意: 输入节点字段配置需要和工作流json文件中一致
outputs = ['9'] # 需要监控的输出节点的ID
# 查询可用后端
backends = get_available_backends(API_KEY)
print(backends)
# 如果实例没有注册到ComfyOne,则注册
is_registered = False
for backend in backends['data']:
if backend['name'] == INSTANCE_ID:
is_registered = True
break
if not is_registered:
register_result = register_comfyone_backend(INSTANCE_ID, API_KEY)
if register_result is not None and register_result['code'] == 0:
print(f"注册实例成功: {register_result['data']['name']}")
else:
print(f"注册实例失败: {register_result['code']}, {register_result['msg']}")
exit(1)
# 创建工作流, 创建工作流后, 工作流ID会返回
create_workflow_result = create_workflow(API_KEY, "test", inputs, outputs, "test_flow.json")
# 生成图片
if create_workflow_result is not None and create_workflow_result['code'] == 0:
prompt_params = {
"workflow_id": create_workflow_result['data']['id'], # 工作流ID,需要创建工作流然后再Prompt
"inputs": [
{
"id": "5",
"params": {
"width": 1024,
"height": 1024
}
}
],
"free_cache": False
}
prompt_result = prompt_comfyone(prompt_params, API_KEY)
if prompt_result is not None and prompt_result['code'] == 0:
print(prompt_result)
else:
print(f"生成图片失败: {prompt_result['code']}, {prompt_result['msg']}")
exit(1)
else:
print(f"创建工作流失败: {create_workflow_result['code']}, {create_workflow_result['msg']}")
exit(1)