
Control ComfyUI with Python
10x faster development of ComfyUI pipelines. MIT License.
ComfyUI + Python = ๐ฅ
Execute workflows with loops, conditionals, and logic that can't be done with nodes.
Stateful ComfyUI
Preserve data between workflow runs with minimal effort and time/compute overhead.
No more spaghetti!
Run partial workflows and build complex pipelines from simple building blocks.
Perfect For
๐ Iterative Refinement
Progressively improve outputs through multiple passes
๐๏ธ Parameter Sweeps
Test multiple configurations automatically
๐ Batch Processing
Process large datasets with custom logic
๐งช A/B Testing
Compare different approaches systematically
See Discomfort in Action
Iterative Workflows with State
Run workflows with loops and persistent state management
async def main():
discomfort = await Discomfort.create()
with discomfort.Context() as context:
for i in range(10):
context.save("seed", 1000 + i)
context.save("cfg", 4.0 + i * 0.5)
await discomfort.run(["workflow.json"],
context=context)
Workflow Stitching
Combine multiple partial workflows programmatically
workflows = [
"load_model.json",
"img2img_latent.json",
"ksampler.json"
]
stitched = discomfort.Tools.stitch_workflows(workflows)
await discomfort.run([stitched["stitched_workflow"]])
Conditional Execution
Branch workflow execution based on runtime conditions
for i in range(10):
if i % 2 == 0:
# Use empty latent
await discomfort.run(["empty_latent.json"])
else:
# Use img2img
context.save("input_image", image)
await discomfort.run(["img2img.json"])
Data Type Handling
Automatic pass-by-value and pass-by-reference for different data types
# Images pass by value (direct storage)
context.save("my_image", image_tensor)
# Models pass by reference (workflow graphs)
context.save("my_model", model_workflow)
# Load any type seamlessly
loaded_data = context.load("my_image")