Comfy Nodekit
Utilities for working with ComfyUI node graphs from Python. The project provides typed wrappers around ComfyUI nodes, lightweight graph primitives, and helpers for exporting a workflow back to the JSON format that the ComfyUI API expects.
- Typed
NodeandEdgemodels (Pydantic) for tracking dependencies and serialising graphs. - A generated
nodes.pymodule that mirrors the ComfyUI node catalogue with Python callables. - Tooling (
nodes_to_py.py) to regenerate those bindings directly from a running ComfyUI server. - Example workflow builder scaffolding that shows how to stitch nodes into higher-level pipelines.
Requirements
- Python 3.12+
requestsandpydantic(installed automatically when the package is installed)- Access to a running ComfyUI server when regenerating node bindings
Installation
uv add comfy_nodekit
# pip install comfy_nodekitGenerate node bindings (required before usage)
Before using the factory functions, generate nodes.py from your running ComfyUI:
uv run python -m comfy_nodekit.nodes_to_py http://127.0.0.1:8188/
# or: just runIf you omit the URL, it defaults to http://127.0.0.1:8188/. This writes nodes.py based on the server's /object_info. Re-run whenever your ComfyUI nodes change.
You can also generate from a local JSON schema (previously fetched from /object_info):
# From default server (same as before) uv run python -m comfy_nodekit.nodes_to_py # From a specific server and write to a custom path uv run python -m comfy_nodekit.nodes_to_py http://127.0.0.1:8188/ ./nodes.py # From a local JSON file and write to a custom path uv run python -m comfy_nodekit.nodes_to_py ./object_info.json ./nodes.py
Usage
Create nodes the same way you would wire a ComfyUI graph. Each factory function from nodes.py returns a typed Edge that keeps track of its originating node. When you are ready to export the workflow, grab the source_node of your terminal edge and call build_json_workflow().
from comfy_nodekit.models import Edge from comfy_nodekit.nodes import ( CheckpointLoaderSimple, CLIPTextEncode, EmptyLatentImage, KSampler, VAEDecode, ) # Load base models model, clip, vae = CheckpointLoaderSimple("juggernautXL_v9Rdphoto2Lightning.safetensors") # Encode prompts positive = CLIPTextEncode(text="a cinematic portrait of an astronaut", clip=clip) negative = CLIPTextEncode(text="", clip=clip) # Create latents and sample latent = EmptyLatentImage(width=1024, height=1024, batch_size=1) sampled = KSampler( model=model, seed=42, steps=20, cfg=7.5, sampler_name="euler", scheduler="normal", positive=positive, negative=negative, latent_image=latent, denoise=1.0, ) decoded = VAEDecode(samples=sampled, vae=vae) # Export to ComfyUI JSON format workflow = decoded.source_node.build_json_workflow() # Optionally: print or send to a ComfyUI server import json print(json.dumps(workflow, indent=2))
Notes
- The generator downloads the node schema, sanitises type names, and rewrites
nodes.pywith updated classes and helper functions. - The
justrecipejust runwraps the generation command if you prefer using just.
Acknowledgments
Thanks to ComfyScript for inspiration and prior art.