# 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({
"9": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "Qwen_Edit_2511",
"images": [
"170:158",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"41": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_image_FILENAME"
},
"_meta": {
"title": "Load Image"
}
},
"83": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_material_FILENAME"
},
"_meta": {
"title": "Load Image"
}
},
"170:145": {
"class_type": "ModelSamplingAuraFlow",
"inputs": {
"model": [
"170:161",
0
],
"sampling": "flow",
"shift": 3.1
},
"_meta": {
"title": "ModelSamplingAuraFlow"
}
},
"170:146": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "qwen_image_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"170:147": {
"class_type": "FluxKontextMultiReferenceLatentMethod",
"inputs": {
"conditioning": [
"170:149",
0
],
"reference_latents_method": "index_timestep_zero"
},
"_meta": {
"title": "Edit Model Reference Method"
}
},
"170:148": {
"class_type": "FluxKontextMultiReferenceLatentMethod",
"inputs": {
"conditioning": [
"170:151",
0
],
"reference_latents_method": "index_timestep_zero"
},
"_meta": {
"title": "Edit Model Reference Method"
}
},
"170:149": {
"class_type": "TextEncodeQwenImageEditPlus",
"inputs": {
"clip": [
"170:162",
0
],
"image1": [
"170:160",
0
],
"image2": [
"83",
0
],
"prompt": "",
"vae": [
"170:146",
0
]
},
"_meta": {
"title": "Text Encode Qwen Image Edit Plus"
}
},
"170:151": {
"class_type": "TextEncodeQwenImageEditPlus",
"inputs": {
"clip": [
"170:162",
0
],
"image1": [
"170:160",
0
],
"image2": [
"83",
0
],
"prompt": "Change the upholstery of the sofa in image 1 to the woven fabric in image 2. Re-cover every cushion, the seat, the back and both arms in that emerald, sage and silver-gilt botanical silk, with its raised damask scrolls and ribbed weave following the curves of the cushions and wrapping neatly around the seams and the welt trim. Keep the pattern at a believable furniture scale, repeating across the seat and back rather than enlarged. Let the silk catch the amber pendant light with a soft metallic sheen on the raised motifs and deeper shadow in the folds. Keep everything else exactly as it is: the sofa's shape and black steel legs, the rain-streaked steel windows, the concrete floor, the basalt side table with the glass carafe, the brick wall and the stormy night light.",
"vae": [
"170:146",
0
]
},
"_meta": {
"title": "TextEncodeQwenImageEditPlus (Positive)"
}
},
"170:152": {
"class_type": "CFGNorm",
"inputs": {
"model": [
"170:145",
0
],
"pre_cfg": False,
"strength": 1
},
"_meta": {
"title": "CFGNorm"
}
},
"170:153": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "Qwen-Image-Edit-2511-Lightning-4steps-V1.0-bf16.safetensors",
"model": [
"170:152",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
},
"170:154": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 4
},
"_meta": {
"title": "CFG"
}
},
"170:155": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 1
},
"_meta": {
"title": "CFG"
}
},
"170:156": {
"class_type": "VAEEncode",
"inputs": {
"pixels": [
"170:160",
0
],
"vae": [
"170:146",
0
]
},
"_meta": {
"title": "VAE Encode"
}
},
"170:158": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"170:169",
0
],
"vae": [
"170:146",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"170:160": {
"class_type": "FluxKontextImageScale",
"inputs": {
"image": [
"41",
0
]
},
"_meta": {
"title": "FluxKontextImageScale"
}
},
"170:161": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "qwen_image_edit_2511_bf16.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"170:162": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors",
"device": "default",
"type": "qwen_image"
},
"_meta": {
"title": "Load CLIP"
}
},
"170:163": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"170:152",
0
],
"on_true": [
"170:153",
0
],
"switch": [
"170:168",
0
]
},
"_meta": {
"title": "Switch (Model)"
}
},
"170:164": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"170:154",
0
],
"on_true": [
"170:155",
0
],
"switch": [
"170:168",
0
]
},
"_meta": {
"title": "Switch (CFG)"
}
},
"170:165": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 4
},
"_meta": {
"title": "Steps"
}
},
"170:166": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 40
},
"_meta": {
"title": "Steps"
}
},
"170:167": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"170:166",
0
],
"on_true": [
"170:165",
0
],
"switch": [
"170:168",
0
]
},
"_meta": {
"title": "Switch (Steps)"
}
},
"170:168": {
"class_type": "PrimitiveBoolean",
"inputs": {
"value": False
},
"_meta": {
"title": "Enable 4steps LoRA?"
}
},
"170:169": {
"class_type": "KSampler",
"inputs": {
"cfg": [
"170:164",
0
],
"denoise": 1,
"latent_image": [
"170:156",
0
],
"model": [
"170:163",
0
],
"negative": [
"170:147",
0
],
"positive": [
"170:148",
0
],
"sampler_name": "euler",
"scheduler": "simple",
"seed": 0,
"steps": [
"170:167",
0
]
},
"_meta": {
"title": "KSampler"
}
}
})
workflow.set_input("41", "image", client.assets.from_url("https://comfy.org/catalog-media/4bb67d1b-b6ef-4ff6-9312-87120a3aa9e5/408d02ad-fe6c-4ea8-bdf4-dc374b36e1e9"))
workflow.set_input("83", "image", client.assets.from_url("https://comfy.org/catalog-media/b39ab263-ed77-4915-88c4-835f84923f6c/d75c6f16-06b9-48e4-84b2-b2eab0d3cc36"))
# 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("9"):
output.to_file(output.name)