# 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": "SaveImage",
"inputs": {
"filename_prefix": "Kandinsky5",
"images": [
"12:9",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"12:1": {
"class_type": "DualCLIPLoader",
"inputs": {
"clip_name1": "qwen_2.5_vl_7b_fp8_scaled.safetensors",
"clip_name2": "clip_l.safetensors",
"device": "default",
"type": "kandinsky5_image"
},
"_meta": {
"title": "Load CLIP (Dual)"
}
},
"12:18": {
"class_type": "EmptyLatentImage",
"inputs": {
"batch_size": 1,
"height": 1024,
"width": 1024
},
"_meta": {
"title": "Empty Latent Image"
}
},
"12:2": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"12:1",
0
],
"text": ""
},
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"12:3": {
"class_type": "ModelSamplingSD3",
"inputs": {
"model": [
"12:4",
0
],
"shift": 3
},
"_meta": {
"title": "ModelSamplingSD3"
}
},
"12:4": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "kandinsky5lite_t2i.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"12:6": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "ae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"12:7": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"12:1",
0
],
"text": "A three-quarter side profile shot captured from a slightly low, stationary camera angle, this image frames a joyful hiker against the jagged, dramatic peaks of the Dolomites, where the elevated perspective emphasizes both the grandeur of the alpine landscape and the upward, hopeful tilt of his gaze. He wears a snug, mustard-yellow knit beanie that matches his chunky, textured sweater, paired with round, wire-rimmed glasses that add a thoughtful, approachable charm, while a rugged, oversized hiking backpack in weathered taupe is secured across his shoulders with gray, adjustable straps, complemented by a utility waist belt with a small, functional pouch. The scene is enhanced by a warm, vintage-inspired filter that bathes the frame in rich golden-amber tones, boosting contrast between the hiker’s vibrant knitwear and the tawny mountain slopes, and a subtle film grain that lends a nostalgic, cinematic quality; soft, directional sunlight casts gentle shadows along his beard and sweater to add depth, with the crisp, saturated blue sky providing a striking counterpoint to the earthy foreground, creating an immersive portrait of adventure and warmth.\n"
},
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"12:8": {
"class_type": "KSampler",
"inputs": {
"cfg": 3.5,
"denoise": 1,
"latent_image": [
"12:18",
0
],
"model": [
"12:3",
0
],
"negative": [
"12:2",
0
],
"positive": [
"12:7",
0
],
"sampler_name": "euler",
"scheduler": "simple",
"seed": 297935044336751,
"steps": 50
},
"_meta": {
"title": "KSampler"
}
},
"12:9": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"12:8",
0
],
"vae": [
"12:6",
0
]
},
"_meta": {
"title": "VAE Decode"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)