Files
dagthomas-comfyui_dagthomas/scripts/check_widgets.py
T

81 lines
3.4 KiB
Python

# Verifies widgets_values in the generated workflows against the actual node
# definitions: count, order, and combo membership.
import json
import os
import sys
import types
for name in ("folder_paths",):
if name not in sys.modules:
mod = types.ModuleType(name)
mod.get_temp_directory = lambda: r"X:\Temp"
mod.get_output_directory = lambda: r"X:\Temp"
sys.modules[name] = mod
sys.path.insert(0, r"X:\comfyui\comfyui\ComfyUI_windows_portable\ComfyUI\custom_nodes")
from comfyui_dagthomas import NODE_CLASS_MAPPINGS
EX = r"X:\comfyui\comfyui\ComfyUI_windows_portable\ComfyUI\custom_nodes\comfyui_dagthomas\examples\h3"
PRIMITIVES = ("STRING", "INT", "FLOAT", "BOOLEAN")
def widget_list(cls):
"""[(name, type_or_options)] for every widget, in declaration order."""
it = cls.INPUT_TYPES()
out = []
for group in ("required", "optional"):
for name, spec in (it.get(group) or {}).items():
typ = spec[0]
opts = spec[1] if len(spec) > 1 and isinstance(spec[1], dict) else {}
if opts.get("forceInput"):
continue
if isinstance(typ, list):
out.append((name, typ))
elif typ in PRIMITIVES:
out.append((name, typ))
if name in ("seed", "noise_seed"):
out.append((name + ".control", "STRING"))
return out
def check(fname, node_types):
with open(os.path.join(EX, fname), encoding="utf-8") as f:
wf = json.load(f)
for n in wf["nodes"]:
if n["type"] not in node_types:
continue
cls = NODE_CLASS_MAPPINGS[n["type"]]
expected = widget_list(cls)
values = n.get("widgets_values") or []
assert len(values) == len(expected), (
f"{fname} node {n['id']} {n['type']}: {len(values)} widget values, "
f"expected {len(expected)}: {[e[0] for e in expected]}"
)
for (wname, wtype), val in zip(expected, values):
if isinstance(wtype, list):
assert val in wtype, (
f"{fname} node {n['id']} {n['type']} widget {wname}: "
f"{val!r} not a valid combo option"
)
print(f" ok: {fname} node {n['id']} {n['type']} ({len(values)} widgets)")
check("h3_music_video.json", {"H3SongAnalysis"})
check("h3_music_video_masked_audio.json", {"H3SongAnalysis"})
check("h3_presentation.json", {"H3ClaudeCodePresentationWriter", "H3Characters", "H3ScenesReview"})
check("h3_music_video_minimal.json", {"H3MusicVideoMinimal", "H3ScenesReview", "H3SongAnalysis"})
check("h3_music_video_masked_audio_briefs.json",
{"H3ClaudeCodeMusicVideoWriter", "H3SceneBrief", "H3Characters", "H3ScenesReview"})
check("h3_music_video_dailies_gate.json",
{"H3ClaudeCodeMusicVideoWriter", "H3Characters", "H3ScenesReviewGate"})
check("h3_short_film.json", {"H3ClaudeCodeShortFilmWriter", "H3Characters", "H3ScenesReview"})
check("h3_music_video_minimal_dailies_gate.json", {"H3MusicVideoMinimal", "H3ScenesReviewGate"})
check("h3_music_video_masked_audio_briefs_dailies_gate.json",
{"H3ClaudeCodeMusicVideoWriter", "H3SceneBrief", "H3ScenesReviewGate"})
check("h3_presentation_dailies_gate.json",
{"H3ClaudeCodePresentationWriter", "H3Characters", "H3ScenesReviewGate"})
check("h3_short_film_manual.json", {"H3ManualScenes", "H3ScenesReview"})
print("WIDGETS-OK")