From d99f7789826492e3f0d243cdd23b7b102d98d47b Mon Sep 17 00:00:00 2001 From: "kosinkadink1@gmail.com" Date: Tue, 15 Jul 2025 14:27:39 -0500 Subject: [PATCH] Added ComfyNodeInternal to comfy_api.internal that will contain classes intended to be used by all V3 schema iterations going forward --- comfy_api/internal/__init__.py | 6 ++++ comfy_api/v3/io.py | 60 ++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 comfy_api/internal/__init__.py diff --git a/comfy_api/internal/__init__.py b/comfy_api/internal/__init__.py new file mode 100644 index 000000000..7b53c639e --- /dev/null +++ b/comfy_api/internal/__init__.py @@ -0,0 +1,6 @@ +class ComfyNodeInternal: + '''Class that all V3-based APIs inhertif from for ComfyNode. + + This is intended to only be referenced within execution.py, as it has to handle all V3 APIs going forward.''' + ... + diff --git a/comfy_api/v3/io.py b/comfy_api/v3/io.py index c2733bf14..92c0ffc8c 100644 --- a/comfy_api/v3/io.py +++ b/comfy_api/v3/io.py @@ -6,6 +6,7 @@ from abc import ABC, abstractmethod from dataclasses import dataclass, asdict from collections import Counter from comfy_execution.graph import ExecutionBlocker +from comfy_api.internal import ComfyNodeInternal from comfy_api.v3.resources import Resources, ResourcesLocal import copy # used for type hinting @@ -226,6 +227,13 @@ class OutputV3(IO_V3): self.display_name = display_name self.tooltip = tooltip self.is_output_list = is_output_list + + def as_dict_V3(self): + return prune_dict({ + "display_name": self.display_name, + "tooltip": self.tooltip, + "is_output_list": self.is_output_list, + }) class ComfyTypeI(ComfyType): @@ -733,6 +741,10 @@ class BBOX(ComfyTypeIO): class SEGS(ComfyTypeIO): Type = Any # NOTE: I couldn't find any references in core code to POINT io_type. Does this exist? +@comfytype(io_type="*") +class AnyType(ComfyTypeIO): + Type = Any + @comfytype(io_type="COMFY_MULTITYPED_V3") class MultiType: Type = Any @@ -794,7 +806,7 @@ class DynamicOutput(OutputV3, ABC): ''' Abstract class for dynamic output registration. ''' - def __init__(self, id: str, display_name: str=None, tooltip: str=None, + def __init__(self, id: str=None, display_name: str=None, tooltip: str=None, is_output_list=False): super().__init__(id, display_name, tooltip, is_output_list) @@ -804,7 +816,7 @@ class DynamicOutput(OutputV3, ABC): @comfytype(io_type="COMFY_AUTOGROW_V3") -class AutogrowDynamic: +class AutogrowDynamic(ComfyTypeI): Type = list[Any] class Input(DynamicInput): def __init__(self, id: str, template_input: InputV3, min: int=1, max: int=None, @@ -850,6 +862,48 @@ class ComboDynamicInput(DynamicInput): pass +@comfytype(io_type="COMFY_MATCHTYPE_V3") +class MatchType(ComfyTypeIO): + class Template: + def __init__(self, template_id: str, allowed_types: ComfyType | list[ComfyType]): + self.template_id = template_id + self.allowed_types = [allowed_types] if isinstance(allowed_types, ComfyType) else allowed_types + + def as_dict(self): + return { + "template_id": self.template_id, + "allowed_types": "".join(t.io_type for t in self.allowed_types), + } + + class Input(DynamicInput): + def __init__(self, id: str, template: MatchType.Template, + display_name: str=None, optional=False, tooltip: str=None, lazy: bool=None, extra_dict=None): + super().__init__(id, display_name, optional, tooltip, lazy, extra_dict) + self.template = template + + def get_dynamic(self) -> list[InputV3]: + return [self] + + def as_dict_V1(self): + return super().as_dict_V1() | prune_dict({ + "template": self.template.as_dict(), + }) + + class Output(DynamicOutput): + def __init__(self, id: str, template: MatchType.Template, display_name: str=None, tooltip: str=None, + is_output_list=False): + super().__init__(id, display_name, tooltip, is_output_list) + self.template = template + + def get_dynamic(self) -> list[OutputV3]: + return [self] + + def as_dict_V3(self): + return super().as_dict_V3() | prune_dict({ + "template": self.template.as_dict(), + }) + + class HiddenHolder: def __init__(self, unique_id: str, prompt: Any, extra_pnginfo: Any, dynprompt: Any, @@ -1083,7 +1137,7 @@ def add_to_dict_v1(i: InputV3, input: dict): input.setdefault(key, {})[i.id] = (i.get_io_type_V1(), i.as_dict_V1()) -class ComfyNodeV3: +class ComfyNodeV3(ComfyNodeInternal): """Common base class for all V3 nodes.""" RELATIVE_PYTHON_MODULE = None