# 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({
"52": {
"class_type": "LoadImage",
"inputs": {
"image": "image_chrono_edit_input_image.png"
},
"_meta": {
"title": "Load Image"
}
},
"60": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "Chrono_Edit_14B",
"images": [
"97:103",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"97:100": {
"class_type": "CLIPVisionLoader",
"inputs": {
"clip_name": "clip_vision_h.safetensors"
},
"_meta": {
"title": "Load CLIP Vision"
}
},
"97:101": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "chrono_edit_14B_fp16.safetensors",
"weight_dtype": "fp8_e4m3fn"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"97:102": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"97:110",
0
],
"vae": [
"97:99",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"97:103": {
"class_type": "ImageFromBatch",
"inputs": {
"batch_index": 4,
"image": [
"97:102",
0
],
"length": 1
},
"_meta": {
"title": "Get Image from Batch"
}
},
"97:104": {
"class_type": "CLIPVisionEncode",
"inputs": {
"clip_vision": [
"97:100",
0
],
"crop": "none",
"image": [
"52",
0
]
},
"_meta": {
"title": "CLIP Vision Encode"
}
},
"97:105": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"97:108",
0
],
"text": "A bottle of facial cleansing foam and bubble shampoo, surrounded by white, round, foamy bubbles. The bubbles are very fluffy, crystal clear, giving a sense of fluffiness and comfort. There are also several bubbles floating in the air around, and the bottle is floating in the air. The background is light pink. The high-resolution picture creates a professional advertising style with high-definition images and high-quality details."
},
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"97:106": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"97:108",
0
],
"text": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走"
},
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"97:107": {
"class_type": "ModelSamplingSD3",
"inputs": {
"model": [
"97:101",
0
],
"shift": 5
},
"_meta": {
"title": "ModelSamplingSD3"
}
},
"97:108": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors",
"device": "default",
"type": "wan"
},
"_meta": {
"title": "Load CLIP"
}
},
"97:109": {
"class_type": "WanImageToVideo",
"inputs": {
"batch_size": 1,
"clip_vision_output": [
"97:104",
0
],
"height": 720,
"length": 5,
"negative": [
"97:106",
0
],
"positive": [
"97:105",
0
],
"start_image": [
"52",
0
],
"vae": [
"97:99",
0
],
"width": 720
},
"_meta": {
"title": "WanImageToVideo"
}
},
"97:110": {
"class_type": "KSampler",
"inputs": {
"cfg": [
"97:119",
0
],
"denoise": 1,
"latent_image": [
"97:109",
2
],
"model": [
"97:117",
0
],
"negative": [
"97:109",
1
],
"positive": [
"97:109",
0
],
"sampler_name": "uni_pc",
"scheduler": "simple",
"seed": 164026091171544,
"steps": [
"97:118",
0
]
},
"_meta": {
"title": "KSampler"
}
},
"97:111": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "chronoedit_distill_lora.safetensors",
"model": [
"97:98",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
},
"97:113": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 20
},
"_meta": {
"title": "Step"
}
},
"97:116": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 4
},
"_meta": {
"title": "Step"
}
},
"97:117": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"97:98",
0
],
"on_true": [
"97:111",
0
],
"switch": [
"97:123",
0
]
},
"_meta": {
"title": "Switch (Model)"
}
},
"97:118": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"97:113",
0
],
"on_true": [
"97:116",
0
],
"switch": [
"97:123",
0
]
},
"_meta": {
"title": "Switch (Step)"
}
},
"97:119": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"97:122",
0
],
"on_true": [
"97:121",
0
],
"switch": [
"97:123",
0
]
},
"_meta": {
"title": "Switch (CFG)"
}
},
"97:121": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 1
},
"_meta": {
"title": "CFG"
}
},
"97:122": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 4
},
"_meta": {
"title": "CFG"
}
},
"97:123": {
"class_type": "PrimitiveBoolean",
"inputs": {
"value": False
},
"_meta": {
"title": "Enable Distll LoRA"
}
},
"97:98": {
"class_type": "ScaleROPE",
"inputs": {
"model": [
"97:107",
0
],
"scale_t": 7,
"scale_x": 1,
"scale_y": 1,
"shift_t": 0,
"shift_x": 0,
"shift_y": 0
},
"_meta": {
"title": "ScaleROPE"
}
},
"97:99": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "wan_2.1_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)