# Python 3.10+: pip install comfy-sdk==0.4.0
import os
from comfy_sdk import Comfy
api_key = os.environ.get("COMFY_API_KEY", "").strip()
if not api_key: raise RuntimeError("Set COMFY_API_KEY")
os.environ.setdefault("COMFY_BASE_URL", "https://cloud.comfy.org")
client = Comfy(api_key=api_key)
workflow = client.workflows.from_json({
"60": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"102:8",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"78": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_image_FILENAME"
},
"_meta": {
"title": "Load Image"
}
},
"93": {
"class_type": "ImageScaleToTotalPixels",
"inputs": {
"image": [
"78",
0
],
"megapixels": 1.5,
"resolution_steps": 1,
"upscale_method": "lanczos"
},
"_meta": {
"title": "Scale Image to Total Pixels"
}
},
"102:103": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 4
},
"_meta": {
"title": "Steps"
}
},
"102:105": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 1
},
"_meta": {
"title": "CFG"
}
},
"102:106": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 20
},
"_meta": {
"title": "Steps"
}
},
"102:107": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 2.5
},
"_meta": {
"title": "CFG"
}
},
"102:108": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"102:37",
0
],
"on_true": [
"102:89",
0
],
"switch": [
"102:111",
0
]
},
"_meta": {
"title": "Switch (model)"
}
},
"102:109": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"102:107",
0
],
"on_true": [
"102:105",
0
],
"switch": [
"102:111",
0
]
},
"_meta": {
"title": "Switch (CFG)"
}
},
"102:110": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"102:106",
0
],
"on_true": [
"102:103",
0
],
"switch": [
"102:111",
0
]
},
"_meta": {
"title": "Switch (Steps)"
}
},
"102:111": {
"class_type": "PrimitiveBoolean",
"inputs": {
"value": False
},
"_meta": {
"title": "Enable 4steps LoRA"
}
},
"102:3": {
"class_type": "KSampler",
"inputs": {
"cfg": [
"102:109",
0
],
"denoise": 1,
"latent_image": [
"102:88",
0
],
"model": [
"102:75",
0
],
"negative": [
"102:77",
0
],
"positive": [
"102:76",
0
],
"sampler_name": "euler",
"scheduler": "simple",
"seed": 344147753686358,
"steps": [
"102:110",
0
]
},
"_meta": {
"title": "KSampler"
}
},
"102:37": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "qwen_image_edit_fp8_e4m3fn.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"102:38": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors",
"device": "default",
"type": "qwen_image"
},
"_meta": {
"title": "Load CLIP"
}
},
"102:39": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "qwen_image_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"102:66": {
"class_type": "ModelSamplingAuraFlow",
"inputs": {
"model": [
"102:108",
0
],
"sampling": "flow",
"shift": 3
},
"_meta": {
"title": "ModelSamplingAuraFlow"
}
},
"102:75": {
"class_type": "CFGNorm",
"inputs": {
"model": [
"102:66",
0
],
"pre_cfg": False,
"strength": 1
},
"_meta": {
"title": "CFGNorm"
}
},
"102:76": {
"class_type": "TextEncodeQwenImageEdit",
"inputs": {
"clip": [
"102:38",
0
],
"image": [
"78",
0
],
"prompt": "Turn this morning kitchen scene into a snowy winter evening while keeping the two people exactly as they are. Outside the big multi-paned windows it is now dusk with heavy snow falling and snow piled on the outside sills, while everything indoors stays dry with no snow on the table; the low golden sunlight is replaced by the warm glow of a pendant lamp above the table and a few lit candles among the breakfast things. Add a steaming mug of cocoa in front of the boy and a small vase of pine branches on the table. Keep the grandmother, the boy, their faces, clothes and poses, the table, the green tiled walls, the shelves and the stove unchanged, with the same framing and camera angle.",
"vae": [
"102:39",
0
]
},
"_meta": {
"title": "Text Encode Qwen Image Edit"
}
},
"102:77": {
"class_type": "TextEncodeQwenImageEdit",
"inputs": {
"clip": [
"102:38",
0
],
"image": [
"78",
0
],
"prompt": "",
"vae": [
"102:39",
0
]
},
"_meta": {
"title": "Text Encode Qwen Image Edit"
}
},
"102:8": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"102:3",
0
],
"vae": [
"102:39",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"102:88": {
"class_type": "VAEEncode",
"inputs": {
"pixels": [
"78",
0
],
"vae": [
"102:39",
0
]
},
"_meta": {
"title": "VAE Encode"
}
},
"102:89": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "Qwen-Image-Edit-Lightning-4steps-V1.0-bf16.safetensors",
"model": [
"102:37",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
}
})
workflow.set_input("78", "image", client.assets.from_url("https://comfy.org/catalog-media/9ee77aad-91bf-4dcc-9e25-3863116c11b6/2eb83e3c-da89-41c5-9f0e-8a7e3c681aa6"))
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)
for output in job.get_outputs("60"):
output.to_file(output.name)