# 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({
"5": {
"class_type": "GeminiNanoBanana2",
"inputs": {
"aspect_ratio": "9:16",
"images": [
"16",
0
],
"model": "Nano Banana 2 (Gemini 3.1 Flash Image)",
"prompt": [
"36:21",
0
],
"resolution": "4K",
"response_modalities": "IMAGE",
"seed": 945201656143140,
"system_prompt": "no text overlays, text bubbles or any other dialogue visualisations. A single image.",
"thinking_level": "HIGH"
},
"_meta": {
"title": "Nano Banana 2"
}
},
"7": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"148",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"15": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"36:21",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"16": {
"class_type": "LoadImage",
"inputs": {
"image": "input_storyboard_video.jpg"
},
"_meta": {
"title": "Load Image"
}
},
"20": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"146",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"23": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"37:24",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"29": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"38:34",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"142": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"5",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"146": {
"class_type": "GeminiNode",
"inputs": {
"images": [
"16",
0
],
"model": "gemini-3-pro-preview",
"prompt": "",
"seed": 323787791232589,
"system_prompt": "Write a 3 scene script. Extract the scenes to prompts. Each prompt has less than 512 characters. Number the prompts: A), B), C)"
},
"_meta": {
"title": "Google Gemini"
}
},
"148": {
"class_type": "KlingOmniProImageToVideoNode",
"inputs": {
"aspect_ratio": "9:16",
"duration": 12,
"generate_audio": True,
"model_name": "kling-v3-omni",
"prompt": "",
"reference_images": [
"5",
0
],
"resolution": "720p",
"seed": 205346978,
"storyboards": "3 storyboards",
"storyboards.storyboard_1_duration": 4,
"storyboards.storyboard_1_prompt": [
"36:21",
0
],
"storyboards.storyboard_2_duration": 4,
"storyboards.storyboard_2_prompt": [
"37:24",
0
],
"storyboards.storyboard_3_duration": 4,
"storyboards.storyboard_3_prompt": [
"38:34",
0
]
},
"_meta": {
"title": "Kling 3.0 Omni Image to Video"
}
},
"36:21": {
"class_type": "OpenAIChatNode",
"inputs": {
"advanced_options": [
"36:22",
0
],
"model": "gpt-5-mini",
"persist_context": False,
"prompt": [
"146",
0
]
},
"_meta": {
"title": "OpenAI ChatGPT"
}
},
"36:22": {
"class_type": "OpenAIChatConfig",
"inputs": {
"instructions": "strictly extract prompt A) only return one prompt without any explanation.",
"max_output_tokens": 4096,
"reasoning_effort": "default",
"truncation": "auto"
},
"_meta": {
"title": "OpenAI ChatGPT Advanced Options"
}
},
"37:24": {
"class_type": "OpenAIChatNode",
"inputs": {
"advanced_options": [
"37:25",
0
],
"model": "gpt-5-mini",
"persist_context": False,
"prompt": [
"146",
0
]
},
"_meta": {
"title": "OpenAI ChatGPT"
}
},
"37:25": {
"class_type": "OpenAIChatConfig",
"inputs": {
"instructions": "strictly extract prompt B) only return one prompt without any explanation.",
"max_output_tokens": 4096,
"reasoning_effort": "default",
"truncation": "auto"
},
"_meta": {
"title": "OpenAI ChatGPT Advanced Options"
}
},
"38:28": {
"class_type": "OpenAIChatConfig",
"inputs": {
"instructions": "strictly extract prompt C) only return one prompt without any explanation.",
"max_output_tokens": 4096,
"reasoning_effort": "default",
"truncation": "auto"
},
"_meta": {
"title": "OpenAI ChatGPT Advanced Options"
}
},
"38:34": {
"class_type": "OpenAIChatNode",
"inputs": {
"advanced_options": [
"38:28",
0
],
"model": "gpt-5-mini",
"persist_context": False,
"prompt": [
"146",
0
]
},
"_meta": {
"title": "OpenAI ChatGPT"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)