# 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({
"16": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/Seedance2.5_video_extend",
"format": "auto",
"format.codec": "auto",
"video": [
"38",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"35": {
"class_type": "LoadVideo",
"inputs": {
"file": "UPLOADED_video_FILENAME"
},
"_meta": {
"title": "Load Video"
}
},
"36": {
"class_type": "Video Slice",
"inputs": {
"duration": 5,
"start_time": 0,
"strict_duration": False,
"video": [
"35",
0
]
},
"_meta": {
"title": "Trim Video"
}
},
"38": {
"class_type": "ByteDance2ReferenceNodeV2",
"inputs": {
"model": "Seedance 2.5",
"model.auto_downscale": True,
"model.auto_upscale": False,
"model.duration": 5,
"model.generate_audio": True,
"model.output_format": "mp4",
"model.prompt": "Continuing from the previous shot, live-action western rodeo, dusty arena, golden hour. The raging bull calms down and stops, the buzzer rings. The sloth in the cowboy hat hops off the bull's back, lands steadily in the dust, slowly dusts off his hat, then strolls away unhurriedly with a deadpan expression. Slow motion, dust floating in warm sunlight, cheering crowd roars and waves hats in the background. Steadicam follow shot. Western arena music swells. No black frames, no text overlays.",
"model.ratio": "adaptive",
"model.reference_videos.video_1": [
"36",
0
],
"model.resolution": "720p",
"model.task_type": "extend",
"seed": 1672978219,
"watermark": False
},
"_meta": {
"title": "ByteDance Seedance 2.5 Reference to Video"
}
},
"40": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/Seedance2.5_video_extend_merged",
"format": "auto",
"format.codec": "auto",
"video": [
"39:8",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"39:1": {
"class_type": "GetVideoComponents",
"inputs": {
"video": [
"35",
0
]
},
"_meta": {
"title": "Get Video Components"
}
},
"39:10": {
"class_type": "EmptyAudio",
"inputs": {
"channels": 2,
"duration": 60,
"sample_rate": 44100
},
"_meta": {
"title": "Empty Audio"
}
},
"39:11": {
"class_type": "PrimitiveBoolean",
"inputs": {
"value": False
},
"_meta": {
"title": "Boolean"
}
},
"39:13": {
"class_type": "BatchImagesNode",
"inputs": {
"images.image0": [
"39:1",
0
],
"images.image1": [
"39:27",
0
]
},
"_meta": {
"title": "Batch Images"
}
},
"39:2": {
"class_type": "GetVideoComponents",
"inputs": {
"video": [
"38",
0
]
},
"_meta": {
"title": "Get Video Components"
}
},
"39:27": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"39:2",
0
],
"on_true": [
"39:6",
0
],
"switch": [
"39:28",
0
]
},
"_meta": {
"title": "If/Else Switch"
}
},
"39:28": {
"class_type": "PrimitiveBoolean",
"inputs": {
"value": False
},
"_meta": {
"title": "Boolean"
}
},
"39:3": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"39:42",
0
],
"on_true": [
"39:10",
0
],
"switch": [
"39:11",
0
]
},
"_meta": {
"title": "If/Else Switch"
}
},
"39:42": {
"class_type": "AudioConcat",
"inputs": {
"audio1": [
"39:2",
1
],
"audio2": [
"39:1",
1
],
"direction": "after"
},
"_meta": {
"title": "Concatenate Audio"
}
},
"39:6": {
"class_type": "ResizeAndPadImage",
"inputs": {
"image": [
"39:2",
0
],
"interpolation": "lanczos",
"padding_color": "white",
"target_height": [
"39:7",
1
],
"target_width": [
"39:7",
0
]
},
"_meta": {
"title": "Resize And Pad Image"
}
},
"39:7": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"39:1",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"39:8": {
"class_type": "CreateVideo",
"inputs": {
"audio": [
"39:3",
0
],
"bit_depth": 8,
"codec": "none",
"color_space": "sRGB",
"fps": [
"39:1",
2
],
"images": [
"39:13",
0
]
},
"_meta": {
"title": "Create Video"
}
}
})
# Replace each example.com URL with a public URL of your file.
workflow.set_input("35", "file", client.assets.from_url("https://example.com/replace-with-a-url/video"))
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)