python对接comfyui的过程

让我先搜索一下项目中是否有ComfyUI相关的代码或文档。

toolName: search_codebase

status: success

query: ComfyUI相关代码、接口、API调用

ComfyUI接口详解与集成方案

1. ComfyUI核心接口

1.1 主要API端点

ComfyUI提供以下主要HTTP接口:

端点 方法 功能 用途
/prompt POST 提交工作流执行请求 触发图片/视频生成
/history GET 获取执行历史 查询任务状态
/view GET 获取生成的图片/视频 下载生成的媒体文件
/queue GET 获取队列状态 查看任务队列
/object_info GET 获取节点信息 了解可用节点和参数
/embeddings GET 获取嵌入模型列表 查看可用模型
/upload/image POST 上传图片 上传输入图片

1.2 详细接口说明

1.2.1 提交工作流 (/prompt)

请求示例

python 复制代码
import requests

comfyui_url = "http://localhost:8188"

# 提交工作流
payload = {
    "prompt": {
        "1": {
            "class_type": "CheckpointLoaderSimple",
            "inputs": {
                "ckpt_name": "v1-5-pruned-emaonly.safetensors"
            }
        },
        "2": {
            "class_type": "CLIPTextEncode",
            "inputs": {
                "text": "a beautiful sunset",
                "clip": ["1", 1]
            }
        },
        "3": {
            "class_type": "KSampler",
            "inputs": {
                "seed": 123456789,
                "steps": 20,
                "cfg": 7,
                "sampler_name": "euler",
                "scheduler": "normal",
                "denoise": 1,
                "model": ["1", 0],
                "positive": ["2", 0],
                "negative": ["2", 1]
            }
        },
        "4": {
            "class_type": "VAEDecode",
            "inputs": {
                "samples": ["3", 0],
                "vae": ["1", 2]
            }
        },
        "5": {
            "class_type": "SaveImage",
            "inputs": {
                "filename_prefix": "ComfyUI",
                "images": ["4", 0]
            }
        }
    },
    "client_id": "client_001"
}

response = requests.post(f"{comfyui_url}/prompt", json=payload)
result = response.json()
# 返回: {"prompt_id": "uuid", "number": 1}
1.2.2 获取执行历史 (/history)

请求示例

python 复制代码
# 获取所有历史
response = requests.get(f"{comfyui_url}/history")
history = response.json()

# 获取特定prompt的历史
prompt_id = "your_prompt_id"
response = requests.get(f"{comfyui_url}/history/{prompt_id}")
prompt_history = response.json()

响应格式

json 复制代码
{
  "prompt_id": {
    "prompt": {},
    "outputs": {
      "5": {
        "images": [
          {
            "filename": "ComfyUI_00001.png",
            "subfolder": "",
            "type": "output"
          }
        ]
      }
    }
  }
}
1.2.3 获取生成的图片 (/view)

请求示例

python 复制代码
# 获取图片
filename = "ComfyUI_00001.png"
subfolder = ""
image_type = "output"

response = requests.get(
    f"{comfyui_url}/view",
    params={
        "filename": filename,
        "subfolder": subfolder,
        "type": image_type
    }
)

# 保存图片
with open("output.png", "wb") as f:
    f.write(response.content)
1.2.4 获取队列状态 (/queue)

请求示例

python 复制代码
response = requests.get(f"{comfyui_url}/queue")
queue_status = response.json()

# 响应格式
{
  "queue_running": [
    [1, ["prompt_id", {}], {}]
  ],
  "queue_pending": [
    [2, ["prompt_id", {}], {}]
  ]
}
1.2.5 获取节点信息 (/object_info)

请求示例

python 复制代码
response = requests.get(f"{comfyui_url}/object_info")
object_info = response.json()

# 响应包含所有可用节点及其参数
{
  "CheckpointLoaderSimple": {
    "input": {
      "required": {
        "ckpt_name": ["STRING", {"default": "model.safetensors"}]
      }
    },
    "output": ["MODEL", "VAE", "CLIP"]
  }
}
1.2.6 上传图片 (/upload/image)

请求示例

python 复制代码
files = {
    "image": ("input.png", open("input.png", "rb"), "image/png"),
    "overwrite": "true"
}

response = requests.post(
    f"{comfyui_url}/upload/image",
    files=files
)

upload_result = response.json()
# 返回: {"name": "input.png", "subfolder": "", "type": "input"}

2. Python Web框架集成方案

2.1 Flask集成示例

python 复制代码
from flask import Flask, request, jsonify, send_file
import requests
import os
import tempfile

app = Flask(__name__)
COMFYUI_URL = "http://localhost:8188"

@app.route('/api/generate-image', methods=['POST'])
def generate_image():
    """
    生成图片接口
    """
    data = request.json
    
    # 构建ComfyUI工作流
    workflow = build_comfyui_workflow(
        prompt=data.get('prompt', ''),
        negative_prompt=data.get('negative_prompt', ''),
        steps=data.get('steps', 20),
        cfg_scale=data.get('cfg_scale', 7),
        seed=data.get('seed', -1)
    )
    
    # 提交到ComfyUI
    try:
        comfy_response = requests.post(
            f"{COMFYUI_URL}/prompt",
            json={"prompt": workflow, "client_id": data.get('client_id', 'default')},
            timeout=30
        )
        
        if comfy_response.status_code != 200:
            return jsonify({"error": "ComfyUI请求失败"}), 500
        
        prompt_result = comfy_response.json()
        prompt_id = prompt_result.get('prompt_id')
        
        # 等待生成完成
        result = wait_for_completion(prompt_id)
        
        if result.get('status') == 'completed':
            # 获取生成的图片
            image_info = result['outputs']['images'][0]
            image_url = get_image_url(image_info)
            
            # 下载图片
            image_response = requests.get(image_url)
            
            # 返回图片
            return send_file(
                tempfile.NamedTemporaryFile(delete=False),
                mimetype='image/png',
                as_attachment=True,
                download_name=image_info['filename']
            )
        else:
            return jsonify({"error": "生成失败"}), 500
            
    except Exception as e:
        return jsonify({"error": str(e)}), 500

@app.route('/api/generate-video', methods=['POST'])
def generate_video():
    """
    生成视频接口
    """
    data = request.json
    
    # 构建视频生成工作流
    workflow = build_video_workflow(data)
    
    # 提交到ComfyUI
    try:
        comfy_response = requests.post(
            f"{COMFYUI_URL}/prompt",
            json={"prompt": workflow, "client_id": data.get('client_id', 'default')},
            timeout=60
        )
        
        if comfy_response.status_code != 200:
            return jsonify({"error": "ComfyUI请求失败"}), 500
        
        prompt_result = comfy_response.json()
        prompt_id = prompt_result.get('prompt_id')
        
        # 等待生成完成
        result = wait_for_completion(prompt_id)
        
        if result.get('status') == 'completed':
            # 获取生成的视频
            video_info = result['outputs']['videos'][0]
            video_url = get_video_url(video_info)
            
            # 下载视频
            video_response = requests.get(video_url)
            
            # 返回视频
            return send_file(
                tempfile.NamedTemporaryFile(delete=False),
                mimetype='video/mp4',
                as_attachment=True,
                download_name=video_info['filename']
            )
        else:
            return jsonify({"error": "生成失败"}), 500
            
    except Exception as e:
        return jsonify({"error": str(e)}), 500

def build_comfyui_workflow(prompt, negative_prompt, steps, cfg_scale, seed):
    """
    构建ComfyUI工作流
    """
    return {
        "1": {
            "class_type": "CheckpointLoaderSimple",
            "inputs": {
                "ckpt_name": "v1-5-pruned-emaonly.safetensors"
            }
        },
        "2": {
            "class_type": "CLIPTextEncode",
            "inputs": {
                "text": prompt,
                "clip": ["1", 1]
            }
        },
        "3": {
            "class_type": "CLIPTextEncode",
            "inputs": {
                "text": negative_prompt,
                "clip": ["1", 1]
            }
        },
        "4": {
            "class_type": "KSampler",
            "inputs": {
                "seed": seed,
                "steps": steps,
                "cfg": cfg_scale,
                "sampler_name": "euler",
                "scheduler": "normal",
                "denoise": 1,
                "model": ["1", 0],
                "positive": ["2", 0],
                "negative": ["3", 0]
            }
        },
        "5": {
            "class_type": "VAEDecode",
            "inputs": {
                "samples": ["4", 0],
                "vae": ["1", 2]
            }
        },
        "6": {
            "class_type": "SaveImage",
            "inputs": {
                "filename_prefix": "generated",
                "images": ["5", 0]
            }
        }
    }

def wait_for_completion(prompt_id, max_wait=300):
    """
    等待生成完成
    """
    import time
    start_time = time.time()
    
    while time.time() - start_time < max_wait:
        response = requests.get(f"{COMFYUI_URL}/history/{prompt_id}")
        history = response.json()
        
        if prompt_id in history:
            result = history[prompt_id]
            return {
                "status": "completed",
                "outputs": result.get('outputs', {})
            }
        
        time.sleep(2)
    
    return {"status": "timeout"}

def get_image_url(image_info):
    """
    获取图片URL
    """
    filename = image_info['filename']
    subfolder = image_info.get('subfolder', '')
    image_type = image_info.get('type', 'output')
    
    return f"{COMFYUI_URL}/view?filename={filename}&subfolder={subfolder}&type={image_type}"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

2.2 FastAPI集成示例

python 复制代码
from fastapi import FastAPI, HTTPException, BackgroundTasks
from fastapi.responses import StreamingResponse
import requests
import asyncio
from typing import Optional

app = FastAPI()
COMFYUI_URL = "http://localhost:8188"

@app.post("/api/generate-image")
async def generate_image(
    prompt: str,
    negative_prompt: str = "",
    steps: int = 20,
    cfg_scale: float = 7.0,
    seed: int = -1,
    client_id: str = "default"
):
    """
    生成图片接口(异步)
    """
    workflow = build_comfyui_workflow(prompt, negative_prompt, steps, cfg_scale, seed)
    
    try:
        # 提交到ComfyUI
        comfy_response = await asyncio.to_thread(
            requests.post,
            f"{COMFYUI_URL}/prompt",
            json={"prompt": workflow, "client_id": client_id},
            timeout=30
        )
        
        if comfy_response.status_code != 200:
            raise HTTPException(status_code=500, detail="ComfyUI请求失败")
        
        prompt_result = comfy_response.json()
        prompt_id = prompt_result.get('prompt_id')
        
        # 等待生成完成
        result = await wait_for_completion_async(prompt_id)
        
        if result['status'] == 'completed':
            # 获取图片
            image_info = result['outputs']['images'][0]
            image_url = get_image_url(image_info)
            
            # 下载图片
            image_response = await asyncio.to_thread(requests.get, image_url)
            
            # 返回图片流
            return StreamingResponse(
                image_response.iter_content(chunk_size=8192),
                media_type="image/png"
            )
        else:
            raise HTTPException(status_code=500, detail="生成失败")
            
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/api/generate-video")
async def generate_video(
    prompt: str,
    negative_prompt: str = "",
    steps: int = 20,
    cfg_scale: float = 7.0,
    seed: int = -1,
    client_id: str = "default"
):
    """
    生成视频接口(异步)
    """
    workflow = build_video_workflow(prompt, negative_prompt, steps, cfg_scale, seed)
    
    try:
        # 提交到ComfyUI
        comfy_response = await asyncio.to_thread(
            requests.post,
            f"{COMFYUI_URL}/prompt",
            json={"prompt": workflow, "client_id": client_id},
            timeout=60
        )
        
        if comfy_response.status_code != 200:
            raise HTTPException(status_code=500, detail="ComfyUI请求失败")
        
        prompt_result = comfy_response.json()
        prompt_id = prompt_result.get('prompt_id')
        
        # 等待生成完成
        result = await wait_for_completion_async(prompt_id)
        
        if result['status'] == 'completed':
            # 获取视频
            video_info = result['outputs']['videos'][0]
            video_url = get_video_url(video_info)
            
            # 下载视频
            video_response = await asyncio.to_thread(requests.get, video_url)
            
            # 返回视频流
            return StreamingResponse(
                video_response.iter_content(chunk_size=8192),
                media_type="video/mp4"
            )
        else:
            raise HTTPException(status_code=500, detail="生成失败")
            
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

async def wait_for_completion_async(prompt_id: str, max_wait: int = 300):
    """
    异步等待生成完成
    """
    import time
    start_time = time.time()
    
    while time.time() - start_time < max_wait:
        response = await asyncio.to_thread(
            requests.get,
            f"{COMFYUI_URL}/history/{prompt_id}"
        )
        history = response.json()
        
        if prompt_id in history:
            result = history[prompt_id]
            return {
                "status": "completed",
                "outputs": result.get('outputs', {})
            }
        
        await asyncio.sleep(2)
    
    return {"status": "timeout"}

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=5000)

3. Dify集成方案

3.1 创建ComfyUI工具

python 复制代码
# api/core/tools/builtin_tool/providers/comfyui.py
from core.tools.__base.tool import Tool
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolProviderType
from typing import Any, Generator
import requests
import time

class ComfyUITool(Tool):
    def tool_provider_type(self) -> ToolProviderType:
        return ToolProviderType.BUILTIN

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
        conversation_id: str | None = None,
        app_id: str | None = None,
        message_id: str | None = None,
    ) -> ToolInvokeMessage | list[ToolInvokeMessage] | Generator[ToolInvokeMessage, None, None]:
        # 获取参数
        comfyui_url = tool_parameters.get('comfyui_url', 'http://localhost:8188')
        prompt = tool_parameters.get('prompt', '')
        negative_prompt = tool_parameters.get('negative_prompt', '')
        steps = tool_parameters.get('steps', 20)
        cfg_scale = tool_parameters.get('cfg_scale', 7.0)
        seed = tool_parameters.get('seed', -1)
        client_id = tool_parameters.get('client_id', f'dify_{user_id}')
        
        # 构建工作流
        workflow = self._build_workflow(prompt, negative_prompt, steps, cfg_scale, seed)
        
        try:
            # 提交到ComfyUI
            response = requests.post(
                f"{comfyui_url}/prompt",
                json={"prompt": workflow, "client_id": client_id},
                timeout=30
            )
            
            if response.status_code != 200:
                return self.create_text_message(f"ComfyUI请求失败: {response.text}")
            
            prompt_result = response.json()
            prompt_id = prompt_result.get('prompt_id')
            
            # 等待生成完成
            result = self._wait_for_completion(comfyui_url, prompt_id)
            
            if result['status'] == 'completed':
                # 获取生成的图片
                outputs = result.get('outputs', {})
                for node_id, node_output in outputs.items():
                    if 'images' in node_output:
                        for image_info in node_output['images']:
                            # 构建图片URL
                            image_url = self._get_image_url(
                                comfyui_url,
                                image_info['filename'],
                                image_info.get('subfolder', ''),
                                image_info.get('type', 'output')
                            )
                            # 返回图片消息
                            yield self.create_image_message(image_url)
                    
                    if 'videos' in node_output:
                        for video_info in node_output['videos']:
                            # 构建视频URL
                            video_url = self._get_video_url(
                                comfyui_url,
                                video_info['filename'],
                                video_info.get('subfolder', ''),
                                video_info.get('type', 'output')
                            )
                            # 返回视频URL
                            yield self.create_link_message(video_url)
            else:
                return self.create_text_message("生成失败")
                
        except Exception as e:
            return self.create_text_message(f"错误: {str(e)}")
    
    def _build_workflow(self, prompt: str, negative_prompt: str, steps: int, cfg_scale: float, seed: int) -> dict:
        """
        构建ComfyUI工作流
        """
        return {
            "1": {
                "class_type": "CheckpointLoaderSimple",
                "inputs": {
                    "ckpt_name": "v1-5-pruned-emaonly.safetensors"
                }
            },
            "2": {
                "class_type": "CLIPTextEncode",
                "inputs": {
                    "text": prompt,
                    "clip": ["1", 1]
                }
            },
            "3": {
                "class_type": "CLIPTextEncode",
                "inputs": {
                    "text": negative_prompt,
                    "clip": ["1", 1]
                }
            },
            "4": {
                "class_type": "KSampler",
                "inputs": {
                    "seed": seed,
                    "steps": steps,
                    "cfg": cfg_scale,
                    "sampler_name": "euler",
                    "scheduler": "normal",
                    "denoise": 1,
                    "model": ["1", 0],
                    "positive": ["2", 0],
                    "negative": ["3", 0]
                }
            },
            "5": {
                "class_type": "VAEDecode",
                "inputs": {
                    "samples": ["4", 0],
                    "vae": ["1", 2]
                }
            },
            "6": {
                "class_type": "SaveImage",
                "inputs": {
                    "filename_prefix": "dify_generated",
                    "images": ["5", 0]
                }
            }
        }
    
    def _wait_for_completion(self, comfyui_url: str, prompt_id: str, max_wait: int = 300) -> dict:
        """
        等待生成完成
        """
        start_time = time.time()
        
        while time.time() - start_time < max_wait:
            response = requests.get(f"{comfyui_url}/history/{prompt_id}")
            history = response.json()
            
            if prompt_id in history:
                result = history[prompt_id]
                return {
                    "status": "completed",
                    "outputs": result.get('outputs', {})
                }
            
            time.sleep(2)
        
        return {"status": "timeout"}
    
    def _get_image_url(self, comfyui_url: str, filename: str, subfolder: str, image_type: str) -> str:
        """
        获取图片URL
        """
        return f"{comfyui_url}/view?filename={filename}&subfolder={subfolder}&type={image_type}"
    
    def _get_video_url(self, comfyui_url: str, filename: str, subfolder: str, video_type: str) -> str:
        """
        获取视频URL
        """
        return f"{comfyui_url}/view?filename={filename}&subfolder={subfolder}&type={video_type}"

3.2 工具提供者配置

python 复制代码
# api/core/tools/builtin_tool/providers/comfyui/__init__.py
from core.tools.builtin_tool.provider import BuiltinToolProviderController
from core.tools.entities.tool_entities import ToolEntity, ToolParameter, ToolDescription
from core.tools.entities.common_entities import I18nObject
from .comfyui_tool import ComfyUITool

class ComfyUIProvider(BuiltinToolProviderController):
    def get_provider_name(self) -> str:
        return "comfyui"
    
    def get_provider_description(self) -> I18nObject:
        return I18nObject(
            en_US="ComfyUI integration for image and video generation",
            zh_Hans="ComfyUI集成,用于图片和视频生成"
        )
    
    def get_tools(self) -> list[ToolEntity]:
        return [
            ToolEntity(
                identity=ToolIdentity(
                    name="generate_image",
                    author="dify",
                    label=I18nObject(
                        en_US="Generate Image",
                        zh_Hans="生成图片"
                    ),
                    description=ToolDescription(
                        human=I18nObject(
                            en_US="Generate images using ComfyUI",
                            zh_Hans="使用ComfyUI生成图片"
                        ),
                        llm="Generate images using ComfyUI"
                    ),
                    parameters=[
                        ToolParameter(
                            name="prompt",
                            label=I18nObject(
                                en_US="Prompt",
                                zh_Hans="提示词"
                            ),
                            human_description=I18nObject(
                                en_US="Text prompt for image generation",
                                zh_Hans="图片生成的文本提示"
                            ),
                            type=ToolParameter.ToolParameterType.STRING,
                            required=True,
                            form=ToolParameter.ToolParameterForm.LLM
                        ),
                        ToolParameter(
                            name="negative_prompt",
                            label=I18nObject(
                                en_US="Negative Prompt",
                                zh_Hans="负面提示词"
                            ),
                            human_description=I18nObject(
                                en_US="Negative prompt for image generation",
                                zh_Hans="图片生成的负面提示"
                            ),
                            type=ToolParameter.ToolParameterType.STRING,
                            required=False,
                            form=ToolParameter.ToolParameterForm.FORM
                        ),
                        ToolParameter(
                            name="steps",
                            label=I18nObject(
                                en_US="Steps",
                                zh_Hans="步数"
                            ),
                            human_description=I18nObject(
                                en_US="Number of sampling steps",
                                zh_Hans="采样步数"
                            ),
                            type=ToolParameter.ToolParameterType.NUMBER,
                            required=False,
                            form=ToolParameter.ToolParameterForm.FORM,
                            default=20
                        ),
                        ToolParameter(
                            name="cfg_scale",
                            label=I18nObject(
                                en_US="CFG Scale",
                                zh_Hans="CFG缩放"
                            ),
                            human_description=I18nObject(
                                en_US="Classifier free guidance scale",
                                zh_Hans="无分类器引导缩放"
                            ),
                            type=ToolParameter.ToolParameterType.NUMBER,
                            required=False,
                            form=ToolParameter.ToolParameterForm.FORM,
                            default=7.0
                        ),
                        ToolParameter(
                            name="seed",
                            label=I18nObject(
                                en_US="Seed",
                                zh_Hans="种子"
                            ),
                            human_description=I18nObject(
                                en_US="Random seed for generation",
                                zh_Hans="生成的随机种子"
                            ),
                            type=ToolParameter.ToolParameterType.NUMBER,
                            required=False,
                            form=ToolParameter.ToolParameterForm.FORM,
                            default=-1
                        )
                    ]
                )
            ]
    
    def get_tool(self, tool_name: str) -> ToolEntity | None:
        for tool in self.get_tools():
            if tool.identity.name == tool_name:
                return tool
        return None
    
    def get_tool_instance(self, tool_name: str) -> ComfyUITool | None:
        tool_entity = self.get_tool(tool_name)
        if tool_entity:
            return ComfyUITool(entity=tool_entity, runtime=None)
        return None

4. 前端集成方案

4.1 前端调用示例

typescript 复制代码
// web/app/components/comfyui/generate.tsx
import React, { useState } from 'react';

interface GenerateParams {
  prompt: string;
  negative_prompt?: string;
  steps?: number;
  cfg_scale?: number;
  seed?: number;
}

export const ComfyUIGenerate: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [imageUrl, setImageUrl] = useState<string>('');
  const [videoUrl, setVideoUrl] = useState<string>('');

  const generateImage = async (params: GenerateParams) => {
    setLoading(true);
    try {
      const response = await fetch('/api/generate-image', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(params),
      });

      if (response.ok) {
        const blob = await response.blob();
        const url = URL.createObjectURL(blob);
        setImageUrl(url);
      } else {
        console.error('生成失败');
      }
    } catch (error) {
      console.error('错误:', error);
    } finally {
      setLoading(false);
    }
  };

  const generateVideo = async (params: GenerateParams) => {
    setLoading(true);
    try {
      const response = await fetch('/api/generate-video', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(params),
      });

      if (response.ok) {
        const blob = await response.blob();
        const url = URL.createObjectURL(blob);
        setVideoUrl(url);
      } else {
        console.error('生成失败');
      }
    } catch (error) {
      console.error('错误:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <h2>ComfyUI生成器</h2>
      
      <div>
        <input
          type="text"
          placeholder="输入提示词"
          onChange={(e) => setPrompt(e.target.value)}
        />
        <input
          type="text"
          placeholder="负面提示词"
          onChange={(e) => setNegativePrompt(e.target.value)}
        />
        <input
          type="number"
          placeholder="步数"
          defaultValue={20}
          onChange={(e) => setSteps(Number(e.target.value))}
        />
        <input
          type="number"
          placeholder="CFG缩放"
          defaultValue={7.0}
          step={0.1}
          onChange={(e) => setCfgScale(Number(e.target.value))}
        />
        <input
          type="number"
          placeholder="种子"
          defaultValue={-1}
          onChange={(e) => setSeed(Number(e.target.value))}
        />
      </div>

      <button onClick={() => generateImage({ prompt, negative_prompt, steps, cfg_scale, seed })}>
        生成图片
      </button>
      <button onClick={() => generateVideo({ prompt, negative_prompt, steps, cfg_scale, seed })}>
        生成视频
      </button>

      {loading && <div>生成中...</div>}
      
      {imageUrl && (
        <div>
          <h3>生成的图片</h3>
          <img src={imageUrl} alt="生成的图片" />
        </div>
      )}
      
      {videoUrl && (
        <div>
          <h3>生成的视频</h3>
          <video src={videoUrl} controls />
        </div>
      )}
    </div>
  );
};

5. 总结

ComfyUI提供了丰富的HTTP API接口,可以方便地集成到各种应用中:

  1. 核心接口/prompt/history/view/queue
  2. 集成方式:可以通过Flask、FastAPI等Python Web框架封装
  3. Dify集成:通过创建自定义工具实现
  4. 前端调用:通过REST API调用,直接获取生成的图片和视频

通过以上方案,你可以灵活地将ComfyUI集成到你的应用中,实现图片和视频的生成功能。

相关推荐
&星痕&1 小时前
从零开始手搓 (1)计算图 (c++,python语言实现)
c++·python·深度学习·机器学习
竹林8182 小时前
从数据混乱到丝滑管理:我在Python项目中重构SQLite数据库的实战记录
python·sqlite
TsukasaNZ2 小时前
C++中的命令模式
开发语言·c++·算法
笨笨马甲2 小时前
Qt 快速实现YY语音房间
开发语言·qt
小糖学代码2 小时前
计算机网络理论:3.数据链路层
网络·计算机网络
我是苏苏2 小时前
消息中间件RabbitMQ04:路由模式+死信队列的应用实践模板
java·开发语言
花无缺0002 小时前
Java开发踩坑:一次线上性能优化案例
java·开发语言·人工智能·面试
superkcl20222 小时前
指针常量有什么用呢?
开发语言·c++·算法