Files
fn_registry/python/functions/ml/comfyui_stream_progress.md
T
egutierrez ff41f4f053 feat(ml): auto-commit con 7 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-24 02:52:51 +02:00

5.6 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_stream_progress function py ml 1.1.0 impure def comfyui_stream_progress(prompt_id: str, *, server: str = "127.0.0.1:8188", client_id: str | None = None, timeout: float = 300.0) -> dict Sigue en vivo el progreso de un prompt ComfyUI por WebSocket ws://<server>/ws?clientId= (eventos progress paso/total, executing por nodo, execution_success/execution_error) en vez de hacer polling. Alternativa en-vivo a comfyui_wait_result. Si websocket-client NO esta en el interprete que ejecuta (el venv del registry no lo trae; el de ComfyUI si), cae limpiamente a polling de /history reutilizando comfyui_wait_result y marca method='polling'. Devuelve {ok, completed, steps_seen, last_node, method, error}. Impura: WebSocket o HTTP.
comfyui
ml
progress
websocket
stream
http
comfyui_wait_result_py_ml
false error_go_core
name desc
prompt_id id devuelto por comfyui_submit_workflow, el prompt cuyo progreso seguir.
name desc
server host:port del servidor ComfyUI sin esquema (default '127.0.0.1:8188').
name desc
client_id clientId para registrar el socket; si None se genera un uuid4 hex.
name desc
timeout maximo de segundos a esperar a que el prompt complete (default 300).
dict con ok (bool), completed (bool, True si el prompt termino), steps_seen (int, mensajes 'progress' vistos por WS; 0 en fallback de polling), last_node (str, ultimo nodo en ejecucion visto), method (str, 'websocket' o 'polling'), error (str, vacio si OK). false
python/functions/ml/comfyui_stream_progress.py

Ejemplo

import sys, os, uuid
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_stream_progress import comfyui_stream_progress

cid = uuid.uuid4().hex   # MISMO clientId en submit y en stream para ver progress en vivo
wf = comfyui_build_txt2img_workflow(
    ckpt_name="dreamshaper_8.safetensors",
    positive="an ornate brass clockwork dragon", steps=25, seed=424242)
pid = comfyui_submit_workflow(wf, client_id=cid)["prompt_id"]

res = comfyui_stream_progress(pid, client_id=cid, timeout=300)
# {'ok': True, 'completed': True, 'steps_seen': 13, 'last_node': '9',
#  'method': 'websocket', 'error': ''}

Si NO compartes el client_id, el seguimiento sigue funcionando (detecta el fin por /history) pero steps_seen sale 0: ComfyUI envia los eventos progress al socket del clientId que encolo el prompt, no a otro.

Para WebSocket real hay que ejecutarlo con un interprete que tenga websocket-client (el venv de ComfyUI lo trae). Con el venv del registry (./fn run) cae a polling automaticamente y devuelve method='polling'.

Cuando usarla

Cuando quieres feedback en vivo de una generacion larga (hires-fix, vídeo, 3D multi-vista) en lugar de esperar a ciegas con comfyui_wait_result: ver por que nodo va el grafo (last_node) y cuantos pasos de sampler han pasado (steps_seen). Util para barras de progreso o para detectar un cuelgue (si steps_seen no avanza). Para el caso simple "solo dime cuando esta listo", comfyui_wait_result (polling) basta y es mas portable.

Gotchas

  • websocket-client NO esta en el venv del registry, asi que ./fn run comfyui_stream_progress <pid> cae a polling (method='polling', steps_seen=0). Para el WebSocket real, ejecutalo con el python de ComfyUI (que si lo trae). El fallback es transparente: mismo dict de retorno.
  • steps_seen cuenta mensajes progress del WS, no el "step N/total" exacto del sampler; sirve como senal de avance, no como porcentaje preciso. En trabajos con nodos cacheados (que completan en <1s) puede salir 0 con completed=True: no hubo pasos que emitir, el fin se detecto por el chequeo de /history.
  • Carrera submit/WS (v1.1.0): un prompt rapido o cacheado puede terminar antes de que el WS reciba su execution_success. La funcion se defiende: comprueba /history al entrar (si ya termino, retorna ya) y en cada ventana de recv sin eventos (detecta el fin sin esperar al timeout). Por eso NO se cuelga 300s en trabajos veloces.
  • client_id debe coincidir con el del submit para ver progress. ComfyUI enruta los eventos progress/executing al socket cuyo clientId encolo el prompt (send_sync(..., sid=client_id)). Si llamas a esta funcion con un client_id distinto (o None, que genera uno nuevo) NO recibiras esos eventos de ese prompt y steps_seen saldra 0 — aunque completed se detecta igual por el chequeo de /history. Para barra de progreso real: genera un cid, pasalo a comfyui_submit_workflow(..., client_id=cid) Y a esta funcion.
  • En fallo de conexion del WS degrada al fallback de polling en vez de lanzar; si tambien falla el polling, devuelve ok=False con el motivo en error.
  • Los frames binarios del WS (previews de imagen en vivo) se ignoran; esta funcion solo sigue el progreso, no descarga la imagen (para eso, comfyui_fetch_output_image).

Capability growth log

  • v1.1.0 (24/06/2026) — robustez ante la carrera submit/WS: pre-check de /history al entrar + re-check de /history en cada ventana de recv sin eventos y al agotar el timeout. Evita el cuelgue hasta timeout cuando un trabajo cacheado/rapido completa antes de que el WS reciba execution_success. Smoke previo lo destapo (prompt cacheado completaba en ~0.7s y la v1.0.0 esperaba 180s en vano).