Contenido

Tutorial de la API de ComfyUI: automatiza la generación de imágenes con Python

ComfyUI es en sí mismo un servidor HTTP. Cada ejecución desde la interfaz llama a su API. Puedes enviar flujos de trabajo mediante código para:

  • Generar muchas imágenes en lote (por ejemplo, una imagen para cada uno de 100 productos)
  • Integrar ComfyUI en tu sitio web, chatbot o flujo de automatización de n8n
  • Generar contenido automáticamente de forma programada

1. Exporta un flujo de trabajo en formato API

El JSON del flujo de trabajo guardado desde la interfaz incluye información de diseño. La API necesita otro formato más compacto:

  1. Crea y prueba un flujo de trabajo en ComfyUI.
  2. En el menú de la esquina superior izquierda, selecciona File → Export (API) y guárdalo como workflow_api.json.
Menú de la esquina superior izquierda de ComfyUI
Menú de ComfyUI en la esquina superior izquierda: el submenú File incluye las opciones para abrir, guardar y exportar; también puedes explorar plantillas desde aquí

El formato API tiene este aspecto. Cada nodo usa su ID como clave:

{
  "3": {
    "class_type": "KSampler",
    "inputs": {
      "seed": 123456,
      "steps": 25,
      "cfg": 6,
      "sampler_name": "dpmpp_2m",
      "scheduler": "karras",
      "denoise": 1,
      "model": ["4", 0],
      "positive": ["6", 0],
      "negative": ["7", 0],
      "latent_image": ["5", 0]
    }
  },
  "6": {
    "class_type": "CLIPTextEncode",
    "inputs": { "text": "a cat sitting on a windowsill", "clip": ["4", 1] }
  }
}

["4", 0] significa «la salida 0 del nodo 4». Anota los ID de los nodos que quieras modificar (por ejemplo, el prompt positivo es 6 y KSampler es 3).

2. Envía una tarea

curl -X POST http://127.0.0.1:8188/prompt \
  -H "Content-Type: application/json" \
  -d "{\"prompt\": $(cat workflow_api.json)}"

Usa el prompt_id de la respuesta para consultar el resultado.

3. Ejemplo completo en Python

import json
import random
import time
import urllib.parse
import urllib.request

SERVER = "http://127.0.0.1:8188"

def queue(workflow: dict) -> str:
    data = json.dumps({"prompt": workflow}).encode()
    req = urllib.request.Request(f"{SERVER}/prompt", data=data, headers={"Content-Type": "application/json"})
    return json.load(urllib.request.urlopen(req))["prompt_id"]

def wait_for(prompt_id: str) -> dict:
    while True:
        history = json.load(urllib.request.urlopen(f"{SERVER}/history/{prompt_id}"))
        if prompt_id in history:
            return history[prompt_id]
        time.sleep(1)

def download_images(result: dict, prefix: str):
    for node_output in result["outputs"].values():
        for i, img in enumerate(node_output.get("images", [])):
            query = urllib.parse.urlencode(
                {"filename": img["filename"], "subfolder": img["subfolder"], "type": img["type"]}
            )
            with urllib.request.urlopen(f"{SERVER}/view?{query}") as r, open(f"{prefix}_{i}.png", "wb") as f:
                f.write(r.read())

workflow = json.load(open("workflow_api.json", encoding="utf-8"))

subjects = ["a red bicycle", "a vintage camera", "a cup of bubble tea"]
for n, subject in enumerate(subjects):
    workflow["6"]["inputs"]["text"] = f"product photo of {subject}, white background, studio lighting"
    workflow["3"]["inputs"]["seed"] = random.randint(0, 2**32 - 1)
    pid = queue(workflow)
    print("Tarea enviada", subject, pid)
    download_images(wait_for(pid), f"product_{n}")
    print("Completado", subject)

Cambia "6" y "3" por los ID de los nodos correspondientes en tu flujo de trabajo.

Sube imágenes de entrada

Si necesitas una imagen de entrada para image-to-image o ControlNet, súbela primero:

curl -X POST http://127.0.0.1:8188/upload/image -F "image=@./input.jpg"

La respuesta incluirá un nombre de archivo. Introdúcelo en el campo image del nodo Load Image.

Progreso en tiempo real: WebSocket

Conéctate a ws://127.0.0.1:8188/ws?clientId=ID_personalizado (incluye el mismo client_id en el JSON al enviar la tarea) para recibir en tiempo real los nodos en ejecución, el porcentaje de progreso y la notificación de finalización. Esto resulta útil para crear una interfaz con una barra de progreso.

Otros endpoints habituales

EndpointUso
GET /queueCola actual
POST /interruptInterrumpe la ejecución actual
GET /historyHistorial
GET /object_infoDefiniciones de todos los nodos (entradas, salidas y opciones)
GET /system_statsInformación del sistema y de la tarjeta gráfica

Consideraciones para el despliegue

  • La API de ComfyUI no tiene autenticación. No la expongas directamente a Internet. Llámala desde tu propio programa de backend y aplica allí la autenticación y los límites de uso.
  • Para hacer llamadas desde otro equipo, inicia ComfyUI con --listen y limita el origen mediante el firewall.
  • Si generas contenido por lotes durante mucho tiempo, recuerda limpiar periódicamente la carpeta output.

También puedes integrar ComfyUI con n8n: usa el nodo HTTP Request para enviar el flujo de trabajo y luego Wait y un bucle para consultar el resultado. Consulta el tutorial de n8n para aprender a usarlo.

Actualizado 12 de octubre de 2026