# 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({
"7": {
"class_type": "ByteDance2ReferenceNode",
"inputs": {
"model": "Seedance 2.0",
"model.auto_downscale": False,
"model.auto_upscale": False,
"model.duration": 7,
"model.generate_audio": False,
"model.prompt": "Reference @video1 for all scene composition, lighting, and camera movement. Add a single blue morpho butterfly that enters from upper left, drifts and circles around the watch for a few seconds with wings catching the cold side light, then descends and lands on the leather strap. Wings open and close once after landing. No other changes. One continuous take, no cuts.",
"model.ratio": "16:9",
"model.reference_videos.video_1": [
"30",
0
],
"model.resolution": "720p",
"seed": 74646607,
"watermark": False
},
"_meta": {
"title": "ByteDance Seedance 2.5 Reference to Video (Legacy)"
}
},
"9": {
"class_type": "ByteDance2ReferenceNode",
"inputs": {
"model": "Seedance 2.0",
"model.auto_downscale": False,
"model.auto_upscale": False,
"model.duration": 7,
"model.generate_audio": False,
"model.prompt": "Use @image1 to match scene lighting, environment, color grade, and atmosphere. Use @image2 as the vehicle reference. Top-down aerial shot looking straight down at the sedan. Camera slowly rolls clockwise around the car. The car remains centered and stationary throughout, and its headlight lights up in the end. One continuous take, no cuts, no camera shake.",
"model.ratio": "16:9",
"model.reference_images.image_1": [
"23",
0
],
"model.reference_images.image_2": [
"17",
0
],
"model.resolution": "720p",
"seed": 387457956,
"watermark": False
},
"_meta": {
"title": "ByteDance Seedance 2.5 Reference to Video (Legacy)"
}
},
"17": {
"class_type": "LoadImage",
"inputs": {
"image": "e6dbc9cbb46649f95bb1e670cd3349456596e48a92af70c862d9fdfbcd8be65e.png"
},
"_meta": {
"title": "PRODUCT REFERENCE"
}
},
"19": {
"class_type": "ByteDance2TextToVideoNode",
"inputs": {
"model": "Seedance 2.0",
"model.duration": 8,
"model.generate_audio": True,
"model.prompt": "A sleek, generic smartphone stands perfectly upright on its own, screen facing camera, in the middle of a dark ancient forest at night. No brand markings, no logos, screen surface dark and reflective. Camera performs a slow 360-degree orbit around the device at eye level, maintaining even distance and framing throughout. As the camera orbits, shafts of cold volumetric light filter through the tree canopy above, catching the device edges and casting long dramatic shadows across the forest floor. Bioluminescent particles drift slowly through the air around it. The device feels monolithic — impossibly still, slightly oversized relative to the environment. Professional motion design render — hyper-real CG aesthetic, physically based rendering, deep blacks, razor sharp product edges, cinematic anamorphic lens. Ultra slow orbit, one continuous take, no cuts.\n",
"model.ratio": "16:9",
"model.resolution": "1080p",
"seed": 1148625786,
"watermark": False
},
"_meta": {
"title": "ByteDance Seedance 2.5 Text to Video"
}
},
"23": {
"class_type": "LoadImage",
"inputs": {
"image": "97496b8d4e3639a26d015112fd5f190c3934eb93d4ec2ff438595538abca054b.png"
},
"_meta": {
"title": "SCENE TO MATCH"
}
},
"24": {
"class_type": "LoadVideo",
"inputs": {
"file": "36c0142281084219c29272b22aad8fa21a1a153dd23b3dc97eced79d875c508e.mp4"
},
"_meta": {
"title": "INPUT VIDEO"
}
},
"30": {
"class_type": "Video Slice",
"inputs": {
"duration": 10,
"start_time": 0,
"strict_duration": False,
"video": [
"24",
0
]
},
"_meta": {
"title": "Trim Video"
}
},
"31": {
"class_type": "SaveVideo",
"inputs": {
"codec": "auto",
"filename_prefix": "video/Efdit",
"format": "auto",
"format.codec": "auto",
"video": [
"7",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"32": {
"class_type": "SaveVideo",
"inputs": {
"codec": "auto",
"filename_prefix": "video/Insert",
"format": "auto",
"format.codec": "auto",
"video": [
"9",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"33": {
"class_type": "SaveVideo",
"inputs": {
"codec": "auto",
"filename_prefix": "video/B-Roll",
"format": "auto",
"format.codec": "auto",
"video": [
"19",
0
]
},
"_meta": {
"title": "Save Video"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)