# 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": 1,
"denoise": 1,
"latent_image": [
"98",
0
],
"model": [
"78",
0
],
"negative": [
"47",
0
],
"positive": [
"94",
0
],
"sampler_name": "euler",
"scheduler": "simple",
"seed": 31,
"steps": 8
},
"_meta": {
"title": "KSampler"
}
},
"18": {
"class_type": "VAEDecodeAudio",
"inputs": {
"samples": [
"3",
0
],
"vae": [
"106",
0
]
},
"_meta": {
"title": "VAE Decode Audio"
}
},
"47": {
"class_type": "ConditioningZeroOut",
"inputs": {
"conditioning": [
"94",
0
]
},
"_meta": {
"title": "Conditioning Zero Out"
}
},
"78": {
"class_type": "ModelSamplingAuraFlow",
"inputs": {
"model": [
"104",
0
],
"sampling": "flow",
"shift": 3
},
"_meta": {
"title": "ModelSamplingAuraFlow"
}
},
"94": {
"class_type": "TextEncodeAceStepAudio1.5",
"inputs": {
"bpm": 128,
"cfg_scale": 2,
"clip": [
"105",
0
],
"duration": 120,
"generate_audio_codes": True,
"keyscale": "E minor",
"language": "en",
"lyrics": "[Intro]\n\n[Verse 1]\nHeadlights on the coastline, the city falls behind\nRadio is humming every word that's on my mind\nMile after mile the ocean keeps the time\nYour hand out the window, catching starlight\n\n[Pre-Chorus]\nDon't slow down, don't look back\nThe night is ours on this empty track\n\n[Chorus]\nWe're driving into midnight, chasing neon skies\nEvery exit's calling but we never say goodbye\nHold on to the moment, let the engine sing\nWe're driving into midnight, we can have anything\n\n[Verse 2]\nTail lights like a heartbeat pulsing in the rain\nSaltwater on the windshield, nothing stays the same\nTurn the music louder, let the static fade\nEvery curve is golden, every fear is gone\n\n[Bridge]\nAnd when the morning finds us\nWe'll still be singing\n\n[Chorus]\nWe're driving into midnight, chasing neon skies\nEvery exit's calling but we never say goodbye\nHold on to the moment, let the engine sing\nWe're driving into midnight, we can have anything\n\n[Outro]",
"min_p": 0,
"seed": 31,
"tags": "Upbeat modern electro-synthpop with a driving 128 BPM tempo. Mood evolves from moody nocturnal anticipation into euphoric, bittersweet catharsis. Production style features hyper-compressed sidechain pumping, warm tube saturation, and an expansive stereo field. \n\nInstrumentation: Punchy four-on-the-floor hybrid drums, aggressive sidechained sawtooth bass, shimmering analog polyphonic pads, and crystalline lead synthesizers.\n\nArrangement:\n- Intro: Low-pass filtered drum groove beneath swelling atmospheric pads.\n- Verse: Driving bassline and rhythmic muted guitar stabs under an intimate, emotive male vocal.\n- Chorus: Full explosive dynamic lift featuring soaring multi-tracked vocal harmonies singing an anthemic hook about driving at night, accompanied by bright supersaw synth leads and crisp claps.\n- Bridge: Atmospheric half-time breakdown featuring resonant filter sweeps and vocoder textures.\n- Outro: Driving high-energy reprise gradually stripping back to the core rhythm, ending on a sustained reverb tail.",
"temperature": 0.85,
"timesignature": "4",
"top_k": 0,
"top_p": 0.9
},
"_meta": {
"title": "TextEncodeAceStepAudio1.5"
}
},
"98": {
"class_type": "EmptyAceStep1.5LatentAudio",
"inputs": {
"batch_size": 1,
"seconds": 120
},
"_meta": {
"title": "Empty Ace Step 1.5 Latent Audio"
}
},
"104": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "acestep_v1.5_turbo.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"105": {
"class_type": "DualCLIPLoader",
"inputs": {
"clip_name1": "qwen_0.6b_ace15.safetensors",
"clip_name2": "qwen_4b_ace15.safetensors",
"device": "default",
"type": "ace"
},
"_meta": {
"title": "Load CLIP (Dual)"
}
},
"106": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "ace_1.5_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"107": {
"class_type": "SaveAudioMP3",
"inputs": {
"audio": [
"18",
0
],
"filename_prefix": "audio/ComfyUI",
"quality": "V0"
},
"_meta": {
"title": "Save Audio (MP3) (DEPRECATED)"
}
}
})
# 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("107"):
output.to_file(output.name)