# 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": "LoadImage",
"inputs": {
"image": "UPLOADED_image_FILENAME"
},
"_meta": {
"title": "Load Image"
}
},
"75:61": {
"class_type": "KSamplerSelect",
"inputs": {
"sampler_name": "euler"
},
"_meta": {
"title": "KSamplerSelect"
}
},
"75:62": {
"class_type": "Flux2Scheduler",
"inputs": {
"height": [
"75:99",
1
],
"steps": 4,
"width": [
"75:99",
0
]
},
"_meta": {
"title": "Flux2Scheduler"
}
},
"75:63": {
"class_type": "CFGGuider",
"inputs": {
"cfg": 1,
"model": [
"75:70",
0
],
"negative": [
"75:79:100",
0
],
"positive": [
"75:79:77",
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:99",
1
],
"width": [
"75:99",
0
]
},
"_meta": {
"title": "Empty Flux 2 Latent"
}
},
"75:70": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "flux-2-klein-9b.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": 137120342660015
},
"_meta": {
"title": "RandomNoise"
}
},
"75:74": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"75:71",
0
],
"text": "Turn the amber bottle into a bottle carved from clear blue ice. Keep both hands, their position and grip, the travertine table, the linen runner and the warm plaster wall exactly as they are, with the same camera angle and framing. The ice bottle keeps the same shape, the vertical fluting and the faceted stopper, but it is cold and translucent, with tiny trapped air bubbles, frosted edges and a thin film of meltwater beading on its surface. A few drops have fallen onto the stone and catch the low sunlight. Inside the bottle, the honey-coloured oil now glows a pale mint green. Keep the late-afternoon light from the left and the long soft shadows."
},
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"75:79:100": {
"class_type": "ReferenceLatent",
"inputs": {
"conditioning": [
"75:82",
0
],
"latent": [
"75:79:78",
0
]
},
"_meta": {
"title": "Set Reference Latent"
}
},
"75:79:77": {
"class_type": "ReferenceLatent",
"inputs": {
"conditioning": [
"75:74",
0
],
"latent": [
"75:79:78",
0
]
},
"_meta": {
"title": "Set Reference Latent"
}
},
"75:79:78": {
"class_type": "VAEEncode",
"inputs": {
"pixels": [
"75:80",
0
],
"vae": [
"75:72",
0
]
},
"_meta": {
"title": "VAE Encode"
}
},
"75:80": {
"class_type": "ImageScaleToTotalPixels",
"inputs": {
"image": [
"76",
0
],
"megapixels": 1,
"resolution_steps": 1,
"upscale_method": "nearest-exact"
},
"_meta": {
"title": "Scale Image to Total Pixels"
}
},
"75:82": {
"class_type": "ConditioningZeroOut",
"inputs": {
"conditioning": [
"75:74",
0
]
},
"_meta": {
"title": "Conditioning Zero Out"
}
},
"75:99": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"75:80",
0
]
},
"_meta": {
"title": "Get Image Size"
}
}
})
workflow.set_input("76", "image", client.assets.from_url("https://comfy.org/catalog-media/bccdb702-e6ca-432c-9c0c-1396b7cd4bb9/11f8ca2e-81c9-486d-9dcc-751a717d5a5a"))
# 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)