"""Consulta el catalogo de nodos de un servidor ComfyUI via GET /object_info. Funcion impura: hace red (HTTP GET). Solo stdlib (urllib, json). El catalogo describe cada class_type disponible: sus inputs requeridos y opcionales, sus tipos, y los valores enumerados (ej. la lista de checkpoints visibles para el servidor en CheckpointLoaderSimple). Util para validar un workflow antes de enviarlo y para descubrir que checkpoints/samplers existen. """ import json import urllib.error import urllib.parse import urllib.request def comfyui_object_info( server: str = "127.0.0.1:8188", node_class: str | None = None, timeout: float = 30.0, ) -> dict: """Recupera el catalogo de nodos (o uno concreto) de ComfyUI. Args: server: host:port del servidor ComfyUI (sin esquema). node_class: si se pasa, consulta solo ese class_type via GET /object_info/{node_class} (ej. "CheckpointLoaderSimple"). Si es None, devuelve el catalogo completo (GET /object_info). timeout: timeout de la peticion HTTP en segundos. Returns: dict con el catalogo. Con node_class=None es {class_type: spec, ...}. Con node_class set, ComfyUI devuelve {class_type: spec} (un solo item). Raises: RuntimeError: si la peticion HTTP falla (conexion rechazada, timeout, HTTP de error) o si la respuesta no es JSON valido. El mensaje incluye el cuerpo del error cuando ComfyUI lo provee. """ path = "/object_info" if node_class is not None: path = f"/object_info/{urllib.parse.quote(node_class)}" url = f"http://{server}{path}" try: with urllib.request.urlopen(url, timeout=timeout) as resp: return json.loads(resp.read()) except urllib.error.HTTPError as exc: body = exc.read().decode(errors="replace") raise RuntimeError( f"comfyui_object_info: HTTP {exc.code} en {url}: {body}" ) from exc except urllib.error.URLError as exc: raise RuntimeError( f"comfyui_object_info: no se pudo conectar a {url}: {exc.reason}" ) from exc except json.JSONDecodeError as exc: raise RuntimeError( f"comfyui_object_info: respuesta no es JSON valido desde {url}: {exc}" ) from exc if __name__ == "__main__": info = comfyui_object_info() print(f"nodos disponibles: {len(info)}") ckpts = info["CheckpointLoaderSimple"]["input"]["required"]["ckpt_name"][0] print(f"checkpoints visibles: {ckpts}")