Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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. |
|
|
false | error_go_core |
|
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-clientNO 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_seencuenta mensajesprogressdel 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 concompleted=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/historyal 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_iddebe coincidir con el del submit para verprogress. ComfyUI enruta los eventosprogress/executingal socket cuyoclientIdencolo el prompt (send_sync(..., sid=client_id)). Si llamas a esta funcion con unclient_iddistinto (o None, que genera uno nuevo) NO recibiras esos eventos de ese prompt ysteps_seensaldra 0 — aunquecompletedse detecta igual por el chequeo de/history. Para barra de progreso real: genera uncid, pasalo acomfyui_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=Falsecon el motivo enerror. - 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
/historyal entrar + re-check de/historyen 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 recibaexecution_success. Smoke previo lo destapo (prompt cacheado completaba en ~0.7s y la v1.0.0 esperaba 180s en vano).