# 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({
"9": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "Flux2-Klein",
"images": [
"75:65",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"76": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "A sweeping panoramic landscape photograph features a lone cowboy crouched low on the far-left icy riverbank, clad in a weathered golden-yellow duster and a crisp white felt hat. The river stretches broadly across the terrain, its dark, freezing waters winding past smooth, rime-frosted stones. Near the center, a line of four silhouetted horsemen crosses the shallow current, kicking up misty splashes in the frigid air. The expansive horizon showcases gently rolling snowfields rising toward towering, jagged white peaks beneath a deep, cloudless cobalt sky. A delicate, frost-laden branch frames the upper right. Direct sunlight casts long, cool blue shadows and warm highlights across the snow, conveying immense scale and the rugged solitude of the winter frontier in sharp, vivid detail."
},
"_meta": {
"title": "Prompt"
}
},
"75:61": {
"class_type": "KSamplerSelect",
"inputs": {
"sampler_name": "euler"
},
"_meta": {
"title": "KSamplerSelect"
}
},
"75:62": {
"class_type": "Flux2Scheduler",
"inputs": {
"height": [
"75:69",
0
],
"steps": 20,
"width": [
"75:68",
0
]
},
"_meta": {
"title": "Flux2Scheduler"
}
},
"75:63": {
"class_type": "CFGGuider",
"inputs": {
"cfg": 5,
"model": [
"75:70",
0
],
"negative": [
"75:67",
0
],
"positive": [
"75:74",
0
]
},
"_meta": {
"title": "CFG Guider"
}
},
"75:64": {
"class_type": "SamplerCustomAdvanced",
"inputs": {
"guider": [
"75:63",
0
],
"latent_image": [
"75:66",
0
],
"noise": [
"75:73",
0
],
"sampler": [
"75:61",
0
],
"sigmas": [
"75:62",
0
]
},
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"75:65": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"75:64",
0
],
"vae": [
"75:72",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"75:66": {
"class_type": "EmptyFlux2LatentImage",
"inputs": {
"batch_size": 1,
"height": [
"75:69",
0
],
"width": [
"75:68",
0
]
},
"_meta": {
"title": "Empty Flux 2 Latent"
}
},
"75:67": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"75:71",
0
],
"text": ""
},
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"75:68": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 1344
},
"_meta": {
"title": "Width"
}
},
"75:69": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 768
},
"_meta": {
"title": "Height"
}
},
"75:70": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "flux-2-klein-base-9b-fp8.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"75:71": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "qwen_3_8b_fp8mixed.safetensors",
"device": "default",
"type": "flux2"
},
"_meta": {
"title": "Load CLIP"
}
},
"75:72": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "flux2-vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"75:73": {
"class_type": "RandomNoise",
"inputs": {
"noise_seed": 0
},
"_meta": {
"title": "RandomNoise"
}
},
"75:74": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"75:71",
0
],
"text": [
"76",
0
]
},
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
}
})
# 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("9"):
output.to_file(output.name)