# 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({
"1": {
"class_type": "ModelSamplingAuraFlow",
"inputs": {
"model": [
"13",
0
],
"sampling": "flow",
"shift": 3.1000000000000005
},
"_meta": {
"title": "ModelSamplingAuraFlow"
}
},
"2": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"4",
0
],
"text": ""
},
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"3": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"4",
0
],
"text": [
"53",
0
]
},
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"4": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors",
"device": "default",
"type": "qwen_image"
},
"_meta": {
"title": "Load CLIP"
}
},
"5": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "qwen_image_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"6": {
"class_type": "EmptySD3LatentImage",
"inputs": {
"batch_size": 1,
"height": 1024,
"width": 2048
},
"_meta": {
"title": "EmptySD3LatentImage"
}
},
"9": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"14",
0
],
"vae": [
"5",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"13": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "qwen-360-diffusion-2512-int8-bf16-v2.safetensors",
"model": [
"15",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
},
"14": {
"class_type": "KSampler",
"inputs": {
"cfg": 4,
"denoise": 1,
"latent_image": [
"6",
0
],
"model": [
"1",
0
],
"negative": [
"2",
0
],
"positive": [
"3",
0
],
"sampler_name": "euler",
"scheduler": "simple",
"seed": 364767852585212,
"steps": 50
},
"_meta": {
"title": "KSampler"
}
},
"15": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "qwen_image_2512_bf16.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"49": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "360_4k",
"images": [
"50:27",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"51": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "Standing at eye level across an immense, desolate salt flat, an ultra-wide panoramic perspective reveals an unbroken 360-degree expanse under the quiet chill of dusk. Directly underfoot, coarse crystalline crusts and sharp geometric fissures of dried white alkali spread outward, transitioning into a seamless, bone-white plain reaching every edge of the visible world. The horizon line circles the viewer in a flat, razor-sharp contour, utterly empty and undisturbed. Overhead, the vast atmospheric dome sweeps from a deep indigo zenith down into bruised violet, dusty lilac, and faint bands of pale apricot along the perimeter. Soft, diffused twilight casts an ethereal, melancholic glow across the mineral earth, bathing the rugged textures in low-contrast ambient illumination without direct glare, creating an overwhelming sensation of isolation and absolute stillness."
},
"_meta": {
"title": "Location Prompt"
}
},
"52": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "equirectangular 360 image, "
},
"_meta": {
"title": "Text (Multiline)"
}
},
"53": {
"class_type": "StringConcatenate",
"inputs": {
"delimiter": "",
"string_a": [
"52",
0
],
"string_b": [
"51",
0
]
},
"_meta": {
"title": "Concatenate Text"
}
},
"50:21": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"9",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"50:22": {
"class_type": "SeedVR2LoadVAEModel",
"inputs": {
"cache_model": False,
"decode_tile_overlap": 128,
"decode_tile_size": 1024,
"decode_tiled": True,
"device": "cuda:0",
"encode_tile_overlap": 128,
"encode_tile_size": 1024,
"encode_tiled": True,
"model": "ema_vae_fp16.safetensors",
"offload_device": "none",
"tile_debug": "false"
},
"_meta": {
"title": "SeedVR2 (Down)Load VAE Model"
}
},
"50:25": {
"class_type": "SimpleMath+",
"inputs": {
"a": [
"50:43",
0
],
"b": [
"50:30",
0
],
"value": "a*b"
},
"_meta": {
"title": "Upscale to Shortest Edge (pixels)"
}
},
"50:27": {
"class_type": "SeedVR2VideoUpscaler",
"inputs": {
"batch_size": 1,
"color_correction": "lab",
"dit": [
"50:28",
0
],
"enable_debug": False,
"image": [
"9",
0
],
"input_noise_scale": 0,
"latent_noise_scale": 0,
"max_resolution": 0,
"offload_device": "cpu",
"prepend_frames": 0,
"resolution": [
"50:25",
0
],
"seed": 3795628944,
"temporal_overlap": 0,
"uniform_batch_size": False,
"vae": [
"50:22",
0
]
},
"_meta": {
"title": "SeedVR2 Video Upscaler (v2.5.24)"
}
},
"50:28": {
"class_type": "SeedVR2LoadDiTModel",
"inputs": {
"attention_mode": "sdpa",
"blocks_to_swap": 0,
"cache_model": False,
"device": "cuda:0",
"model": "seedvr2_ema_3b_fp16.safetensors",
"offload_device": "cpu",
"swap_io_components": False
},
"_meta": {
"title": "SeedVR2 (Down)Load DiT Model"
}
},
"50:30": {
"class_type": "PrimitiveFloat",
"inputs": {
"value": 2
},
"_meta": {
"title": "Upscale Factor"
}
},
"50:40": {
"class_type": "ImpactCompare",
"inputs": {
"a": [
"50:21",
0
],
"b": [
"50:21",
1
],
"cmp": "a <= b"
},
"_meta": {
"title": "ImpactCompare"
}
},
"50:43": {
"class_type": "LayerUtility: If ",
"inputs": {
"if_condition": [
"50:40",
0
],
"when_FALSE": [
"50:21",
1
],
"when_TRUE": [
"50:21",
0
]
},
"_meta": {
"title": "IfElse"
}
}
})
# 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("49"):
output.to_file(output.name)