mirror of
https://git.datalinker.icu/comfyanonymous/ComfyUI
synced 2025-12-08 21:44:33 +08:00
131 lines
5.0 KiB
Plaintext
131 lines
5.0 KiB
Plaintext
from typing_extensions import override
|
|
|
|
from comfy_api.latest import ComfyExtension, io
|
|
|
|
|
|
class Example(io.ComfyNode):
|
|
"""
|
|
An example node
|
|
|
|
Class methods
|
|
-------------
|
|
define_schema (io.Schema):
|
|
Tell the main program the metadata, input, output parameters of nodes.
|
|
fingerprint_inputs:
|
|
optional method to control when the node is re executed.
|
|
check_lazy_status:
|
|
optional method to control list of input names that need to be evaluated.
|
|
|
|
"""
|
|
|
|
@classmethod
|
|
def define_schema(cls) -> io.Schema:
|
|
"""
|
|
Return a schema which contains all information about the node.
|
|
Some types: "Model", "Vae", "Clip", "Conditioning", "Latent", "Image", "Int", "String", "Float", "Combo".
|
|
For outputs the "io.Model.Output" should be used, for inputs the "io.Model.Input" can be used.
|
|
The type can be a "Combo" - this will be a list for selection.
|
|
"""
|
|
return io.Schema(
|
|
node_id="Example",
|
|
display_name="Example Node",
|
|
category="Example",
|
|
inputs=[
|
|
io.Image.Input("image"),
|
|
io.Int.Input(
|
|
"int_field",
|
|
min=0,
|
|
max=4096,
|
|
step=64, # Slider's step
|
|
display_mode=io.NumberDisplay.number, # Cosmetic only: display as "number" or "slider"
|
|
lazy=True, # Will only be evaluated if check_lazy_status requires it
|
|
),
|
|
io.Float.Input(
|
|
"float_field",
|
|
default=1.0,
|
|
min=0.0,
|
|
max=10.0,
|
|
step=0.01,
|
|
round=0.001, #The value representing the precision to round to, will be set to the step value by default. Can be set to False to disable rounding.
|
|
display_mode=io.NumberDisplay.number,
|
|
lazy=True,
|
|
),
|
|
io.Combo.Input("print_to_screen", options=["enable", "disable"]),
|
|
io.String.Input(
|
|
"string_field",
|
|
multiline=False, # True if you want the field to look like the one on the ClipTextEncode node
|
|
default="Hello world!",
|
|
lazy=True,
|
|
)
|
|
],
|
|
outputs=[
|
|
io.Image.Output(),
|
|
],
|
|
)
|
|
|
|
@classmethod
|
|
def check_lazy_status(cls, image, string_field, int_field, float_field, print_to_screen):
|
|
"""
|
|
Return a list of input names that need to be evaluated.
|
|
|
|
This function will be called if there are any lazy inputs which have not yet been
|
|
evaluated. As long as you return at least one field which has not yet been evaluated
|
|
(and more exist), this function will be called again once the value of the requested
|
|
field is available.
|
|
|
|
Any evaluated inputs will be passed as arguments to this function. Any unevaluated
|
|
inputs will have the value None.
|
|
"""
|
|
if print_to_screen == "enable":
|
|
return ["int_field", "float_field", "string_field"]
|
|
else:
|
|
return []
|
|
|
|
@classmethod
|
|
def execute(cls, image, string_field, int_field, float_field, print_to_screen) -> io.NodeOutput:
|
|
if print_to_screen == "enable":
|
|
print(f"""Your input contains:
|
|
string_field aka input text: {string_field}
|
|
int_field: {int_field}
|
|
float_field: {float_field}
|
|
""")
|
|
#do some processing on the image, in this example I just invert it
|
|
image = 1.0 - image
|
|
return io.NodeOutput(image)
|
|
|
|
"""
|
|
The node will always be re executed if any of the inputs change but
|
|
this method can be used to force the node to execute again even when the inputs don't change.
|
|
You can make this node return a number or a string. This value will be compared to the one returned the last time the node was
|
|
executed, if it is different the node will be executed again.
|
|
This method is used in the core repo for the LoadImage node where they return the image hash as a string, if the image hash
|
|
changes between executions the LoadImage node is executed again.
|
|
"""
|
|
#@classmethod
|
|
#def fingerprint_inputs(s, image, string_field, int_field, float_field, print_to_screen):
|
|
# return ""
|
|
|
|
# Set the web directory, any .js file in that directory will be loaded by the frontend as a frontend extension
|
|
# WEB_DIRECTORY = "./somejs"
|
|
|
|
|
|
# Add custom API routes, using router
|
|
from aiohttp import web
|
|
from server import PromptServer
|
|
|
|
@PromptServer.instance.routes.get("/hello")
|
|
async def get_hello(request):
|
|
return web.json_response("hello")
|
|
|
|
|
|
class ExampleExtension(ComfyExtension):
|
|
@override
|
|
async def get_node_list(self) -> list[type[io.ComfyNode]]:
|
|
return [
|
|
Example,
|
|
]
|
|
|
|
|
|
async def comfy_entrypoint() -> ExampleExtension: # ComfyUI calls this to load your extension and its nodes.
|
|
return ExampleExtension()
|