# 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({
"682": {
"class_type": "DrawBBoxes",
"inputs": {
"bboxes": [
"675:678",
0
],
"image": [
"687",
0
]
},
"_meta": {
"title": "Draw BBoxes"
}
},
"687": {
"class_type": "ResizeImageMaskNode",
"inputs": {
"input": [
"698",
0
],
"resize_type": "scale longer dimension",
"resize_type.longer_size": [
"688",
0
],
"scale_method": "lanczos"
},
"_meta": {
"title": "Resize Image/Mask"
}
},
"688": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 1024
},
"_meta": {
"title": "Int"
}
},
"690": {
"class_type": "ImageBlend",
"inputs": {
"blend_factor": 0.5,
"blend_mode": "normal",
"image1": [
"682",
0
],
"image2": [
"675:672",
0
]
},
"_meta": {
"title": "Blend Images"
}
},
"694": {
"class_type": "LoadVideo",
"inputs": {
"file": "man_palying_violin.mp4"
},
"_meta": {
"title": "Load Video"
}
},
"695": {
"class_type": "CreateVideo",
"inputs": {
"audio": [
"675:692",
1
],
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"675:692",
2
],
"images": [
"690",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"697": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"695",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"698": {
"class_type": "GetVideoComponents",
"inputs": {
"video": [
"694",
0
]
},
"_meta": {
"title": "Get Video Components"
}
},
"699": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"675:672",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"675:671": {
"class_type": "SDPoseKeypointExtractor",
"inputs": {
"batch_size": 16,
"bboxes": [
"675:678",
0
],
"image": [
"675:674",
0
],
"model": [
"675:673",
0
],
"vae": [
"675:673",
2
]
},
"_meta": {
"title": "SDPose Keypoint Extractor"
}
},
"675:672": {
"class_type": "SDPoseDrawKeypoints",
"inputs": {
"draw_body": True,
"draw_face": True,
"draw_feet": True,
"draw_hands": True,
"draw_head": True,
"face_point_size": 2,
"keypoints": [
"675:671",
0
],
"score_threshold": 0.5,
"stick_width": 4
},
"_meta": {
"title": "SDPose Draw Keypoints"
}
},
"675:673": {
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "sdpose_wholebody_fp16.safetensors"
},
"_meta": {
"title": "Load Checkpoint"
}
},
"675:674": {
"class_type": "ResizeImageMaskNode",
"inputs": {
"input": [
"675:692",
0
],
"resize_type": "scale longer dimension",
"resize_type.longer_size": [
"688",
0
],
"scale_method": "lanczos"
},
"_meta": {
"title": "Resize Image/Mask"
}
},
"675:677": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "rt_detr_v4-x-hgnet_fp16.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"675:678": {
"class_type": "RTDETR_detect",
"inputs": {
"class_name": "person",
"image": [
"675:674",
0
],
"max_detections": 2,
"model": [
"675:677",
0
],
"threshold": 0.5
},
"_meta": {
"title": "Run Real-Time Detection (RT-DETR)"
}
},
"675:692": {
"class_type": "GetVideoComponents",
"inputs": {
"video": [
"694",
0
]
},
"_meta": {
"title": "Get Video Components"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)