# 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": [
"55",
2
],
"model": [
"66",
0
],
"negative": [
"55",
1
],
"positive": [
"55",
0
],
"sampler_name": "uni_pc",
"scheduler": "simple",
"seed": 887940314022885,
"steps": 20
},
"_meta": {
"title": "KSampler"
}
},
"6": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"38",
0
],
"text": "A handmade claymation stop-motion film of a dancer sculpted from matte red plasticine, the ribbed unitard pressed into soft grooves, thumbprints visible on the face and hands. He dances alone on a flat grey clay plaza in front of a pale, chalky plaster backdrop. He lands from a leap, opens his arms wide, turns a full pirouette, sweeps one arm in a long circle overhead, sinks into a deep lunge to the side and rises back to centre with both arms lifted high. The motion has the charming, slightly stepped rhythm of hand-animated stop motion, with tiny shifts in the clay between frames and a soft shadow following him across the floor. Even, diffuse studio light, warm red against cool grey, the camera locked off at a fixed distance."
},
"_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": [
"3",
0
],
"vae": [
"39",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"37": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "wan2.1_fun_control_1.3B_bf16.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"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"
}
},
"49": {
"class_type": "CLIPVisionLoader",
"inputs": {
"clip_name": "clip_vision_h.safetensors"
},
"_meta": {
"title": "Load CLIP Vision"
}
},
"51": {
"class_type": "CLIPVisionEncode",
"inputs": {
"clip_vision": [
"49",
0
],
"crop": "none",
"image": [
"52",
0
]
},
"_meta": {
"title": "CLIP Vision Encode"
}
},
"52": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_start_image_FILENAME"
},
"_meta": {
"title": "Load Image"
}
},
"55": {
"class_type": "WanFunControlToVideo",
"inputs": {
"batch_size": 1,
"clip_vision_output": [
"51",
0
],
"control_video": [
"71",
0
],
"height": 544,
"length": 77,
"negative": [
"7",
0
],
"positive": [
"6",
0
],
"start_image": [
"52",
0
],
"vae": [
"39",
0
],
"width": 960
},
"_meta": {
"title": "WanFunControlToVideo"
}
},
"65": {
"class_type": "SkipLayerGuidanceDiT",
"inputs": {
"double_layers": "9,10",
"end_percent": 0.8000000000000002,
"model": [
"37",
0
],
"rescaling_scale": 0,
"scale": 3,
"single_layers": "9,10",
"start_percent": 0.01
},
"_meta": {
"title": "SkipLayerGuidanceDiT"
}
},
"66": {
"class_type": "CFGZeroStar",
"inputs": {
"model": [
"68",
0
]
},
"_meta": {
"title": "CFGZeroStar"
}
},
"67": {
"class_type": "ModelSamplingSD3",
"inputs": {
"model": [
"65",
0
],
"shift": 5.000000000000001
},
"_meta": {
"title": "ModelSamplingSD3"
}
},
"68": {
"class_type": "UNetTemporalAttentionMultiply",
"inputs": {
"cross_structural": 1.2,
"cross_temporal": 1.3,
"model": [
"67",
0
],
"self_structural": 1,
"self_temporal": 1
},
"_meta": {
"title": "UNetTemporalAttentionMultiply"
}
},
"71": {
"class_type": "Canny",
"inputs": {
"high_threshold": 0.5000000000000001,
"image": [
"81",
0
],
"low_threshold": 0.20000000000000004
},
"_meta": {
"title": "Detect Edges (Canny)"
}
},
"74": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"71",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"78": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"79",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"79": {
"class_type": "CreateVideo",
"inputs": {
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": 16,
"images": [
"8",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"80": {
"class_type": "LoadVideo",
"inputs": {
"file": "UPLOADED_control_video_FILENAME"
},
"_meta": {
"title": "Load Video"
}
},
"81": {
"class_type": "GetVideoComponents",
"inputs": {
"video": [
"80",
0
]
},
"_meta": {
"title": "Get Video Components"
}
}
})
workflow.set_input("80", "file", client.assets.from_url("https://comfy.org/catalog-media/5633cc1a-9750-4b77-99bd-66dfd37ec42f/892afaeb-0d7c-419c-9876-0432cd52981c"))
workflow.set_input("52", "image", client.assets.from_url("https://comfy.org/catalog-media/84b51fda-1b0e-49e3-ac52-dc66ce4c2bda/78e79119-687a-4248-b490-d980a2e24921"))
# 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("78"):
output.to_file(output.name)