Files
fn_registry/python/functions/ml/comfyui_wait_result.md
T
egutierrez 898502a321 fix(ml): comfyui_wait_result no sale prematuro en jobs de video/3D
Exige outputs no vacios (no solo status terminal) para dar por completado
un prompt: en jobs pesados ComfyUI marca la entry de /history como
terminada antes de poblar outputs, lo que devolvia un dict vacio mientras
el job seguia en GPU. Ahora sigue sondeando hasta que los outputs aparecen
o hasta agotar el timeout. Timeout default 180s -> 600s (cubre video/3D) y
timeout HTTP por-request acotado a 30s. Firma y contrato de retorno intactos.

Tests nuevos (mock urllib CI-safe + live opcional contra /history real):
golden, regresion del bug, edge imagen corta, timeout y error. v1.0.0 -> 1.1.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 12:39:58 +02:00

5.1 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
comfyui_wait_result function py ml 1.1.0 impure def comfyui_wait_result(prompt_id: str, server: str = "127.0.0.1:8188", timeout: float = 600.0, poll_interval: float = 1.0) -> dict Sondea GET /history/{prompt_id} hasta que un prompt ComfyUI completa con estado de exito (status.completed o status_str success) Y outputs ya poblados, o falla (status_str error), o se agota el timeout. Exige outputs no vacios para no salir prematuro en jobs de video/3D donde la entry de /history aparece marcada como terminada antes de poblar resultados. Devuelve los outputs por nodo (node_id -> {images: [...]}). Polling como mecanismo principal (no WebSocket). Impura: HTTP GET en bucle + sleep, solo stdlib.
comfyui
ml
image-generation
stable-diffusion
http
polling
false error_go_core
name desc
prompt_id id devuelto por comfyui_submit_workflow (clave 'prompt_id' de su respuesta).
name desc
server host:port del servidor ComfyUI sin esquema (default '127.0.0.1:8188').
name desc
timeout Maximo de segundos a esperar antes de lanzar TimeoutError. Default amplio (600s) para cubrir video/3D; imagenes cortas retornan en cuanto los outputs estan listos.
name desc
poll_interval Segundos entre sondeos de /history.
dict de outputs {node_id: {'images': [{'filename', 'subfolder', 'type'}, ...]}} tal como ComfyUI los expone en history[prompt_id]['outputs']. Siempre no vacio en caso de exito. Para un txt2img, el nodo SaveImage ('9') trae el PNG. El video (SaveVideo) aparece bajo 'images' con 'animated':[True]. Puede contener otros tipos (gifs, texto) segun los nodos del workflow. true
Golden: espera hasta que /history puebla outputs no vacios (entry tarda en aparecer)
Regresion bug: 'done' con outputs vacios NO sale prematuro, espera a que aparezcan
Edge: imagen corta ya completada en el primer sondeo retorna inmediato
Edge: status.completed sin status_str success tambien vale si hay outputs
Error: timeout genuino (prompt inexistente) lanza TimeoutError sin colgar
Error: status_str 'error' lanza RuntimeError
Live (skippable): job de video ya completado en /history real devuelve outputs
python/functions/ml/tests/test_comfyui_wait_result.py python/functions/ml/comfyui_wait_result.py

Ejemplo

import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from ml.comfyui_build_txt2img_workflow import comfyui_build_txt2img_workflow
from ml.comfyui_submit_workflow import comfyui_submit_workflow
from ml.comfyui_wait_result import comfyui_wait_result

wf = comfyui_build_txt2img_workflow(
    ckpt_name="v1-5-pruned-emaonly-fp16.safetensors",
    positive="a red apple on a wooden table, sharp focus",
)
pid = comfyui_submit_workflow(wf)["prompt_id"]
outputs = comfyui_wait_result(pid, timeout=240)
for node_id, out in outputs.items():
    for img in out.get("images", []):
        print(img["filename"])    # ej. comfy_00001_.png en ~/ComfyUI/output/

O lanzable directo (build + submit + wait) con: ./fn run comfyui_wait_result.

Cuando usarla

Tercer y ultimo paso del round-trip: tras comfyui_submit_workflow, para bloquear hasta que la generacion termine y recuperar las rutas de los PNG generados. Usala cuando quieras el resultado fija (no streaming de progreso paso a paso) — es portable porque solo depende de HTTP, no de websocket-client.

Gotchas

  • Bloquea el hilo (sondea + duerme). Para varias generaciones en paralelo, encola todas con submit y luego espera cada prompt_id, o usa hilos.
  • El timeout por defecto es ahora 600s (antes 180s) para cubrir video/3D. Sigue pudiendo quedarse corto en workflows muy pesados o GPUs lentas: sube timeout segun el caso. Lanza TimeoutError si se agota.
  • Considera el job terminado solo cuando el estado es de exito y los outputs estan poblados. Si ComfyUI marca la entry como terminada pero aun sin outputs (ocurre en jobs de video/3D mientras la GPU sigue escribiendo), sigue sondeando hasta que aparezcan o hasta agotar el timeout — no devuelve un dict vacio prematuro. Corolario: un workflow sin nodo de guardado (no produce outputs) agota el timeout en vez de devolver {}.
  • Lanza RuntimeError si la ejecucion termina con status_str "error" (el detalle del fallo va en el mensaje) o si no se puede conectar al servidor.
  • Devuelve metadatos de los PNG/MP4 (filename, subfolder, type), NO los bytes de la imagen. Los archivos quedan en la carpeta output/ del servidor; para leerlos desde otra maquina usa GET /view?filename=...&subfolder=...&type=output.

Capability growth log

  • v1.1.0 (2026-06-24) — fix salida prematura en jobs de video/3D: ahora exige outputs no vacios (no solo status terminal) para dar por completado, sigue sondeando si la entry de /history aparece terminada pero sin outputs, sube el timeout default 180s -> 600s y acota el timeout HTTP por-request a 30s. Anadidos tests (mock urllib + live opcional). Documentado en report 0106.