"""Envia un workflow (API format) a un servidor ComfyUI via POST /prompt. Funcion impura: hace red (HTTP POST). Solo stdlib (urllib, json, uuid). ComfyUI encola el workflow y devuelve un dict con prompt_id (para seguir el resultado con comfyui_wait_result), number (posicion en la cola) y node_errors. Si el workflow es invalido, ComfyUI responde HTTP 400 con detalles de la validacion por nodo: esta funcion los captura y los propaga en el error. """ import json import urllib.error import urllib.request import uuid def comfyui_submit_workflow( workflow: dict, server: str = "127.0.0.1:8188", client_id: str | None = None, timeout: float = 30.0, ) -> dict: """Encola un workflow en ComfyUI y devuelve la respuesta del servidor. Args: workflow: dict en API format (resultado de comfyui_build_txt2img_workflow u otro builder). Las claves son node_ids y cada valor tiene class_type + inputs. server: host:port del servidor ComfyUI (sin esquema). client_id: identificador de cliente para correlar eventos (WS/history). Si es None, se genera un uuid4. Se incluye en la respuesta. timeout: timeout de la peticion HTTP en segundos. Returns: dict con al menos prompt_id (str), number (int, posicion en cola) y node_errors (dict). Se anade la clave "client_id" usada. Raises: RuntimeError: si ComfyUI rechaza el workflow (HTTP 400 con detalles de validacion en el cuerpo), si no se puede conectar, o si la respuesta no es JSON valido. El mensaje incluye el cuerpo del error. """ cid = client_id or str(uuid.uuid4()) body = json.dumps({"prompt": workflow, "client_id": cid}).encode() url = f"http://{server}/prompt" req = urllib.request.Request( url, data=body, headers={"Content-Type": "application/json"} ) try: with urllib.request.urlopen(req, timeout=timeout) as resp: out = json.loads(resp.read()) except urllib.error.HTTPError as exc: detail = exc.read().decode(errors="replace") raise RuntimeError( f"comfyui_submit_workflow: ComfyUI rechazo el workflow " f"(HTTP {exc.code}): {detail}" ) from exc except urllib.error.URLError as exc: raise RuntimeError( f"comfyui_submit_workflow: no se pudo conectar a {url}: {exc.reason}" ) from exc except json.JSONDecodeError as exc: raise RuntimeError( f"comfyui_submit_workflow: respuesta no es JSON valido desde {url}: {exc}" ) from exc out["client_id"] = cid return out if __name__ == "__main__": from comfyui_build_txt2img_workflow import comfyui_build_txt2img_workflow wf = comfyui_build_txt2img_workflow( ckpt_name="v1-5-pruned-emaonly-fp16.safetensors", positive="a red apple on a wooden table, sharp focus", negative="blurry, low quality", steps=20, seed=42, ) resp = comfyui_submit_workflow(wf) print(f"prompt_id={resp['prompt_id']} number={resp.get('number')}")