mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-07-28 08:46:35 +00:00
Added some missing type defs, starting work on a revision (v3_01) to change formatting (need to change execution.py to recognize it as v3 as well)
This commit is contained in:
parent
2873aaf4db
commit
6854864db9
@ -115,6 +115,14 @@ class WidgetInputV3(InputV3, io_type=None):
|
|||||||
"widgetType": self.widgetType,
|
"widgetType": self.widgetType,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class OutputV3(IO_V3, io_type=None):
|
||||||
|
def __init__(self, id: str, display_name: str=None, tooltip: str=None,
|
||||||
|
is_output_list=False):
|
||||||
|
self.id = id
|
||||||
|
self.display_name = display_name
|
||||||
|
self.tooltip = tooltip
|
||||||
|
self.is_output_list = is_output_list
|
||||||
|
|
||||||
def CustomType(io_type: IO | str) -> type[IO_V3]:
|
def CustomType(io_type: IO | str) -> type[IO_V3]:
|
||||||
name = f"{io_type}_IO_V3"
|
name = f"{io_type}_IO_V3"
|
||||||
return type(name, (IO_V3,), {}, io_type=io_type)
|
return type(name, (IO_V3,), {}, io_type=io_type)
|
||||||
@ -163,6 +171,9 @@ class BooleanInput(WidgetInputV3, io_type=IO.BOOLEAN):
|
|||||||
"label_off": self.label_off,
|
"label_off": self.label_off,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class BooleanOutput(OutputV3, io_type=IO.BOOLEAN):
|
||||||
|
...
|
||||||
|
|
||||||
class IntegerInput(WidgetInputV3, io_type=IO.INT):
|
class IntegerInput(WidgetInputV3, io_type=IO.INT):
|
||||||
'''
|
'''
|
||||||
Integer input.
|
Integer input.
|
||||||
@ -188,6 +199,9 @@ class IntegerInput(WidgetInputV3, io_type=IO.INT):
|
|||||||
"display": self.display_mode, # NOTE: in frontend, the parameter is called "display"
|
"display": self.display_mode, # NOTE: in frontend, the parameter is called "display"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class IntegerOutput(OutputV3, io_type=IO.INT):
|
||||||
|
...
|
||||||
|
|
||||||
class FloatInput(WidgetInputV3, io_type=IO.FLOAT):
|
class FloatInput(WidgetInputV3, io_type=IO.FLOAT):
|
||||||
'''
|
'''
|
||||||
Float input.
|
Float input.
|
||||||
@ -213,6 +227,9 @@ class FloatInput(WidgetInputV3, io_type=IO.FLOAT):
|
|||||||
"round": self.round,
|
"round": self.round,
|
||||||
"display": self.display_mode, # NOTE: in frontend, the parameter is called "display"
|
"display": self.display_mode, # NOTE: in frontend, the parameter is called "display"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class FloatOutput(OutputV3, io_type=IO.FLOAT):
|
||||||
|
...
|
||||||
|
|
||||||
class StringInput(WidgetInputV3, io_type=IO.STRING):
|
class StringInput(WidgetInputV3, io_type=IO.STRING):
|
||||||
'''
|
'''
|
||||||
@ -233,6 +250,9 @@ class StringInput(WidgetInputV3, io_type=IO.STRING):
|
|||||||
"placeholder": self.placeholder,
|
"placeholder": self.placeholder,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class StringOutput(OutputV3, io_type=IO.STRING):
|
||||||
|
...
|
||||||
|
|
||||||
class ComboInput(WidgetInputV3, io_type=IO.COMBO):
|
class ComboInput(WidgetInputV3, io_type=IO.COMBO):
|
||||||
'''Combo input (dropdown).'''
|
'''Combo input (dropdown).'''
|
||||||
Type = str
|
Type = str
|
||||||
@ -279,27 +299,193 @@ class MultiselectComboWidget(ComboInput, io_type=IO.COMBO):
|
|||||||
})
|
})
|
||||||
|
|
||||||
class ImageInput(InputV3, io_type=IO.IMAGE):
|
class ImageInput(InputV3, io_type=IO.IMAGE):
|
||||||
'''
|
'''Image input.'''
|
||||||
Image input.
|
Type = torch.Tensor
|
||||||
'''
|
|
||||||
|
class ImageOutput(OutputV3, io_type=IO.IMAGE):
|
||||||
|
'''Image output.'''
|
||||||
Type = torch.Tensor
|
Type = torch.Tensor
|
||||||
def __init__(self, id: str, display_name: str=None, optional=False, tooltip: str=None):
|
|
||||||
super().__init__(id, display_name, optional, tooltip)
|
|
||||||
|
|
||||||
class MaskInput(InputV3, io_type=IO.MASK):
|
class MaskInput(InputV3, io_type=IO.MASK):
|
||||||
'''
|
'''Mask input.'''
|
||||||
Mask input.
|
Type = torch.Tensor
|
||||||
'''
|
|
||||||
|
class MaskOutput(OutputV3, io_type=IO.MASK):
|
||||||
|
'''Mask output.'''
|
||||||
Type = torch.Tensor
|
Type = torch.Tensor
|
||||||
def __init__(self, id: str, display_name: str=None, optional=False, tooltip: str=None):
|
|
||||||
super().__init__(id, display_name, optional, tooltip)
|
|
||||||
|
|
||||||
class LatentInput(InputV3, io_type=IO.LATENT):
|
class LatentInput(InputV3, io_type=IO.LATENT):
|
||||||
'''
|
'''Latent input.'''
|
||||||
Latent input.
|
# TODO: make Type a TypedDict
|
||||||
'''
|
...
|
||||||
def __init__(self, id: str, display_name: str=None, optional=False, tooltip: str=None):
|
|
||||||
super().__init__(id, display_name, optional, tooltip)
|
class LatentOutput(OutputV3, io_type=IO.LATENT):
|
||||||
|
'''Latent output.'''
|
||||||
|
# TODO: make Type a TypedDict
|
||||||
|
...
|
||||||
|
|
||||||
|
class ConditioningInput(InputV3, io_type=IO.CONDITIONING):
|
||||||
|
'''Conditioning input.'''
|
||||||
|
# TODO: make Type a TypedDict
|
||||||
|
...
|
||||||
|
|
||||||
|
class ConditioningOutput(OutputV3, io_type=IO.CONDITIONING):
|
||||||
|
'''Conditioning output.'''
|
||||||
|
# TODO: make Type a TypedDict
|
||||||
|
...
|
||||||
|
|
||||||
|
class SamplerInput(InputV3, io_type=IO.SAMPLER):
|
||||||
|
'''Sampler input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class SamplerOutput(OutputV3, io_type=IO.SAMPLER):
|
||||||
|
'''Sampler output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class SigmasInput(InputV3, io_type=IO.SIGMAS):
|
||||||
|
'''Sigmas input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class SigmasOutput(OutputV3, io_type=IO.SIGMAS):
|
||||||
|
'''Sigmas output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class GuiderInput(InputV3, io_type=IO.GUIDER):
|
||||||
|
'''Guider input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class GuiderOutput(OutputV3, io_type=IO.GUIDER):
|
||||||
|
'''Guider output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class NoiseInput(InputV3, io_type=IO.NOISE):
|
||||||
|
'''Noise input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class NoiseOutput(OutputV3, io_type=IO.NOISE):
|
||||||
|
'''Noise output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class ClipInput(InputV3, io_type=IO.CLIP):
|
||||||
|
'''Clip input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class ClipOutput(OutputV3, io_type=IO.CLIP):
|
||||||
|
'''Clip output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class ControlNetInput(InputV3, io_type=IO.CONTROL_NET):
|
||||||
|
'''ControlNet input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class ControlNetOutput(OutputV3, io_type=IO.CONTROL_NET):
|
||||||
|
'''ControlNet output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class VaeInput(InputV3, io_type=IO.VAE):
|
||||||
|
'''Vae input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class VaeOutput(OutputV3, io_type=IO.VAE):
|
||||||
|
'''Vae output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class ModelInput(InputV3, io_type=IO.MODEL):
|
||||||
|
'''Model input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class ModelOutput(OutputV3, io_type=IO.MODEL):
|
||||||
|
'''Model output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class ClipVisionInput(InputV3, io_type=IO.CLIP_VISION):
|
||||||
|
'''ClipVision input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class ClipVisionOutput(OutputV3, io_type=IO.CLIP_VISION):
|
||||||
|
'''ClipVision output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class ClipVisionOutputInput(InputV3, io_type=IO.CLIP_VISION_OUTPUT):
|
||||||
|
'''CLipVisionOutput input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class ClipVisionOutputOutput(OutputV3, io_type=IO.CLIP_VISION_OUTPUT):
|
||||||
|
'''CLipVisionOutput output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class StyleModelInput(InputV3, io_type=IO.STYLE_MODEL):
|
||||||
|
'''StyleModel input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class StyleModelOutput(OutputV3, io_type=IO.STYLE_MODEL):
|
||||||
|
'''StyleModel output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class GligenInput(InputV3, io_type=IO.GLIGEN):
|
||||||
|
'''Gligen input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class GligenOutput(OutputV3, io_type=IO.GLIGEN):
|
||||||
|
'''Gligen output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class UpscaleModelInput(InputV3, io_type=IO.UPSCALE_MODEL):
|
||||||
|
'''UpscaleModel input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class UpscaleModelOutput(OutputV3, io_type=IO.UPSCALE_MODEL):
|
||||||
|
'''UpscaleModel output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class AudioInput(InputV3, io_type=IO.AUDIO):
|
||||||
|
'''Audio input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class AudioOutput(OutputV3, io_type=IO.AUDIO):
|
||||||
|
'''Audio output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class PointInput(InputV3, io_type=IO.POINT):
|
||||||
|
'''Point input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class PointOutput(OutputV3, io_type=IO.POINT):
|
||||||
|
'''Point output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class FaceAnalysisInput(InputV3, io_type=IO.FACE_ANALYSIS):
|
||||||
|
'''FaceAnalysis input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class FaceAnalysisOutput(OutputV3, io_type=IO.FACE_ANALYSIS):
|
||||||
|
'''FaceAnalysis output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class BBOXInput(InputV3, io_type=IO.BBOX):
|
||||||
|
'''Bbox input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class BBOXOutput(OutputV3, io_type=IO.BBOX):
|
||||||
|
'''Bbox output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class SEGSInput(InputV3, io_type=IO.SEGS):
|
||||||
|
'''SEGS input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class SEGSOutput(OutputV3, io_type=IO.SEGS):
|
||||||
|
'''SEGS output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class VideoInput(InputV3, io_type=IO.VIDEO):
|
||||||
|
'''Video input.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
class VideoOutput(OutputV3, io_type=IO.VIDEO):
|
||||||
|
'''Video output.'''
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
class MultitypedInput(InputV3, io_type="COMFY_MULTITYPED_V3"):
|
class MultitypedInput(InputV3, io_type="COMFY_MULTITYPED_V3"):
|
||||||
'''
|
'''
|
||||||
@ -326,39 +512,6 @@ class MultitypedInput(InputV3, io_type="COMFY_MULTITYPED_V3"):
|
|||||||
return ",".join(x.io_type for x in self.io_types)
|
return ",".join(x.io_type for x in self.io_types)
|
||||||
|
|
||||||
|
|
||||||
class OutputV3:
|
|
||||||
def __init__(self, id: str, display_name: str=None, tooltip: str=None,
|
|
||||||
is_output_list=False):
|
|
||||||
self.id = id
|
|
||||||
self.display_name = display_name
|
|
||||||
self.tooltip = tooltip
|
|
||||||
self.is_output_list = is_output_list
|
|
||||||
|
|
||||||
def __init_subclass__(cls, io_type, **kwargs):
|
|
||||||
cls.io_type = io_type
|
|
||||||
super().__init_subclass__(**kwargs)
|
|
||||||
|
|
||||||
class IntegerOutput(OutputV3, io_type=IO.INT):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class FloatOutput(OutputV3, io_type=IO.FLOAT):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class StringOutput(OutputV3, io_type=IO.STRING):
|
|
||||||
pass
|
|
||||||
# def __init__(self, id: str, display_name: str=None, tooltip: str=None):
|
|
||||||
# super().__init__(id, display_name, tooltip)
|
|
||||||
|
|
||||||
class ImageOutput(OutputV3, io_type=IO.IMAGE):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class MaskOutput(OutputV3, io_type=IO.MASK):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class LatentOutput(OutputV3, io_type=IO.LATENT):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DynamicInput(InputV3, io_type=None):
|
class DynamicInput(InputV3, io_type=None):
|
||||||
'''
|
'''
|
||||||
Abstract class for dynamic input registration.
|
Abstract class for dynamic input registration.
|
||||||
@ -566,7 +719,7 @@ def prepare_class_clone(c: ComfyNodeV3 | type[ComfyNodeV3]) -> type[ComfyNodeV3]
|
|||||||
type_clone: type[ComfyNodeV3] = type(f"CLEAN_{c_type.__name__}", c_type.__bases__, {})
|
type_clone: type[ComfyNodeV3] = type(f"CLEAN_{c_type.__name__}", c_type.__bases__, {})
|
||||||
# TODO: what parameters should be carried over?
|
# TODO: what parameters should be carried over?
|
||||||
type_clone.SCHEMA = c_type.SCHEMA
|
type_clone.SCHEMA = c_type.SCHEMA
|
||||||
# TODO: add anything we would want to expose inside node's EXECUTE function
|
# TODO: add anything we would want to expose inside node's execute function
|
||||||
return type_clone
|
return type_clone
|
||||||
|
|
||||||
|
|
||||||
@ -698,7 +851,7 @@ class ComfyNodeV3(ABC):
|
|||||||
cls.GET_SCHEMA()
|
cls.GET_SCHEMA()
|
||||||
return cls._OUTPUT_TOOLTIPS
|
return cls._OUTPUT_TOOLTIPS
|
||||||
|
|
||||||
FUNCTION = "EXECUTE"
|
FUNCTION = "execute"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(cls) -> dict[str, dict]:
|
def INPUT_TYPES(cls) -> dict[str, dict]:
|
||||||
@ -763,7 +916,7 @@ class ComfyNodeV3(ABC):
|
|||||||
# create separate lists from output fields
|
# create separate lists from output fields
|
||||||
output = []
|
output = []
|
||||||
output_is_list = []
|
output_is_list = []
|
||||||
output_name = []
|
output_name = []
|
||||||
output_tooltips = []
|
output_tooltips = []
|
||||||
if schema.outputs:
|
if schema.outputs:
|
||||||
for o in schema.outputs:
|
for o in schema.outputs:
|
||||||
|
1122
comfy_api/v3_01/io.py
Normal file
1122
comfy_api/v3_01/io.py
Normal file
File diff suppressed because it is too large
Load Diff
74
comfy_extras/nodes_v3_01_test.py
Normal file
74
comfy_extras/nodes_v3_01_test.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import torch
|
||||||
|
from comfy_api.v3_01 import io
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
class XYZ:
|
||||||
|
Type = tuple[int,str]
|
||||||
|
class Input(io.InputV3, io_type="XYZ"):
|
||||||
|
...
|
||||||
|
class Output(io.OutputV3, io_type="XYZ"):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class V3TestNode(io.ComfyNodeV3):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.hahajkunless = ";)"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def DEFINE_SCHEMA(cls):
|
||||||
|
return io.SchemaV3(
|
||||||
|
node_id="V3_01_TestNode1",
|
||||||
|
display_name="V3_01 Test Node",
|
||||||
|
description="This is a funky V3_01 node test.",
|
||||||
|
category="v3 nodes",
|
||||||
|
inputs=[
|
||||||
|
io.Image.Input("image", display_name="new_image"),
|
||||||
|
XYZ.Input("xyz", optional=True),
|
||||||
|
#CustomInput("xyz", "XYZ", optional=True),
|
||||||
|
io.Mask.Input("mask", optional=True),
|
||||||
|
io.Integer.Input("some_int", display_name="new_name", min=0, max=127, default=42,
|
||||||
|
tooltip="My tooltip 😎", display_mode=io.NumberDisplay.slider),
|
||||||
|
io.ComboInput("combo", options=["a", "b", "c"], tooltip="This is a combo input"),
|
||||||
|
# ComboInput("combo", image_upload=True, image_folder=FolderType.output,
|
||||||
|
# remote=RemoteOptions(
|
||||||
|
# route="/internal/files/output",
|
||||||
|
# refresh_button=True,
|
||||||
|
# ),
|
||||||
|
# tooltip="This is a combo input"),
|
||||||
|
# IntegerInput("some_int", display_name="new_name", min=0, tooltip="My tooltip 😎", display=NumberDisplay.slider, ),
|
||||||
|
# ComboDynamicInput("mask", behavior=InputBehavior.optional),
|
||||||
|
# IntegerInput("some_int", display_name="new_name", min=0, tooltip="My tooltip 😎", display=NumberDisplay.slider,
|
||||||
|
# dependent_inputs=[ComboDynamicInput("mask", behavior=InputBehavior.optional)],
|
||||||
|
# dependent_values=[lambda my_value: IO.STRING if my_value < 5 else IO.NUMBER],
|
||||||
|
# ),
|
||||||
|
# ["option1", "option2". "option3"]
|
||||||
|
# ComboDynamicInput["sdfgjhl", [ComboDynamicOptions("option1", [IntegerInput("some_int", display_name="new_name", min=0, tooltip="My tooltip 😎", display=NumberDisplay.slider, ImageInput(), MaskInput(), String()]),
|
||||||
|
# CombyDynamicOptons("option2", [])
|
||||||
|
# ]]
|
||||||
|
],
|
||||||
|
outputs=[
|
||||||
|
io.Integer.Output("int_output"),
|
||||||
|
io.Image.Output("img_output", display_name="img🖼️", tooltip="This is an image"),
|
||||||
|
],
|
||||||
|
hidden=[
|
||||||
|
|
||||||
|
],
|
||||||
|
is_output_node=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, image: io.Image.Type, some_int: int, combo: io.ComboInput.Type, xyz: XYZ.Type=None, mask: io.Mask.Type=None):
|
||||||
|
some_int
|
||||||
|
if hasattr(cls, "hahajkunless"):
|
||||||
|
raise Exception("The 'cls' variable leaked instance state between runs!")
|
||||||
|
if hasattr(cls, "doohickey"):
|
||||||
|
raise Exception("The 'cls' variable leaked state on class properties between runs!")
|
||||||
|
cls.doohickey = "LOLJK"
|
||||||
|
return io.NodeOutput(some_int, image)
|
||||||
|
|
||||||
|
|
||||||
|
NODES_LIST: list[io.ComfyNodeV3] = [
|
||||||
|
V3TestNode,
|
||||||
|
]
|
Loading…
x
Reference in New Issue
Block a user