# 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({
"3": {
"class_type": "KSampler",
"inputs": {
"cfg": 6,
"denoise": 1,
"latent_image": [
"49",
2
],
"model": [
"48",
0
],
"negative": [
"49",
1
],
"positive": [
"49",
0
],
"sampler_name": "uni_pc",
"scheduler": "simple",
"seed": 95385376145355,
"steps": 20
},
"_meta": {
"title": "KSampler"
}
},
"6": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"38",
0
],
"text": "A girl is dancing in a sea of flowers, slowly moving her hands, stretching her arms. There is a super close - up and a close - up of the upper body. The character is surrounded by other transparent glass flowers in the style of Nicoletta Ceccoli, creating a beautiful, surreal, and emotionally expressive movie scene. It has a white and transparent feeling, is dreamy, and in close range. "
},
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"7": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"38",
0
],
"text": "过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走,过曝,"
},
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"8": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"58",
0
],
"vae": [
"39",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"38": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors",
"device": "default",
"type": "wan"
},
"_meta": {
"title": "Load CLIP"
}
},
"39": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "wan_2.1_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"48": {
"class_type": "ModelSamplingSD3",
"inputs": {
"model": [
"140",
0
],
"shift": 8.000000000000002
},
"_meta": {
"title": "ModelSamplingSD3"
}
},
"49": {
"class_type": "WanVaceToVideo",
"inputs": {
"batch_size": 1,
"control_masks": [
"191:156",
0
],
"control_video": [
"191:145",
0
],
"height": [
"194",
0
],
"length": [
"131",
0
],
"negative": [
"7",
0
],
"positive": [
"6",
0
],
"strength": 1,
"vae": [
"39",
0
],
"width": [
"193",
0
]
},
"_meta": {
"title": "WanVaceToVideo"
}
},
"58": {
"class_type": "TrimVideoLatent",
"inputs": {
"samples": [
"3",
0
],
"trim_amount": [
"49",
3
]
},
"_meta": {
"title": "Trim Video Latent"
}
},
"68": {
"class_type": "CreateVideo",
"inputs": {
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": 16,
"images": [
"8",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"69": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/wan2.1_vace",
"format": "auto",
"format.codec": "h264",
"video": [
"68",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"131": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 81
},
"_meta": {
"title": "Length"
}
},
"140": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "wan2.1_vace_14B_fp16.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"144": {
"class_type": "LoadImage",
"inputs": {
"image": "video_wan_vace_flf2v_start_image.png"
},
"_meta": {
"title": "first frame"
}
},
"147": {
"class_type": "LoadImage",
"inputs": {
"image": "video_wan_vace_flf2v_end_image.png"
},
"_meta": {
"title": "Last frame"
}
},
"171": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 79
},
"_meta": {
"title": "Length"
}
},
"193": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 512
},
"_meta": {
"title": "Width"
}
},
"194": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 512
},
"_meta": {
"title": "Height"
}
},
"191:145": {
"class_type": "ImageBatch",
"inputs": {
"image1": [
"191:150",
0
],
"image2": [
"147",
0
]
},
"_meta": {
"title": "Batch Images (DEPRECATED)"
}
},
"191:146": {
"class_type": "SolidMask",
"inputs": {
"height": [
"194",
0
],
"value": 1,
"width": [
"193",
0
]
},
"_meta": {
"title": "Create Solid Mask"
}
},
"191:148": {
"class_type": "MaskToImage",
"inputs": {
"mask": [
"191:146",
0
]
},
"_meta": {
"title": "Convert Mask to Image"
}
},
"191:149": {
"class_type": "RepeatImageBatch",
"inputs": {
"amount": [
"171",
0
],
"image": [
"191:148",
0
]
},
"_meta": {
"title": "Repeat Image Batch"
}
},
"191:150": {
"class_type": "ImageBatch",
"inputs": {
"image1": [
"144",
0
],
"image2": [
"191:149",
0
]
},
"_meta": {
"title": "Batch Images (DEPRECATED)"
}
},
"191:151": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"191:145",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"191:152": {
"class_type": "SolidMask",
"inputs": {
"height": [
"194",
0
],
"value": 0,
"width": [
"193",
0
]
},
"_meta": {
"title": "Create Solid Mask"
}
},
"191:153": {
"class_type": "ImageBatch",
"inputs": {
"image1": [
"191:154",
0
],
"image2": [
"191:149",
0
]
},
"_meta": {
"title": "Batch Images (DEPRECATED)"
}
},
"191:154": {
"class_type": "MaskToImage",
"inputs": {
"mask": [
"191:152",
0
]
},
"_meta": {
"title": "Convert Mask to Image"
}
},
"191:155": {
"class_type": "ImageBatch",
"inputs": {
"image1": [
"191:153",
0
],
"image2": [
"191:154",
0
]
},
"_meta": {
"title": "Batch Images (DEPRECATED)"
}
},
"191:156": {
"class_type": "ImageToMask",
"inputs": {
"channel": "red",
"image": [
"191:155",
0
]
},
"_meta": {
"title": "Convert Image to Mask"
}
},
"191:157": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"191:155",
0
]
},
"_meta": {
"title": "Preview Image"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)