A small helper library to add types for custom ComfyUI nodes.
Project description
ComfyUI Types
This is a small helper project to make it easier to write custom nodes for ComfyUI. Usually, types in ComfyUI are represented as string constants for parameter and return types, which can cause errors during development, as it is easy to mistype. With such string constants, your IDE cannot recognize the types and offer suggestions or alarm you abour errors. Such an error will only be found, when ComfyUI is restarted and the custom node is executed.
This project provides a small set of shallow Python classes that provide typing, so an IDE can pick up correct types and show errors before the node is imported, making development much faster and reducing debugging.
Installation
Install from PyPI:
pip install comfyui-types
Or via conda:
conda install tkreuziger::comfyui_types
Alternatively, you can install the package locally from source:
git clone https://github.com/tkreuziger/comfyui-types.git ./comfyui_types
pip install ./comfyui_types
Defining a custom node
Base node
Your custom node must derive from ComfyUINode:
from comfyui_types import ComfyUINode
class MyCustomNode(ComfyUINode):
"""Your custom node."""
This does most of the heavy lifting and ensures that ComfyUI can import your node correctly.
Meta parameters
Next you can define some meta parameters:
from comfyui_types import ComfyUINode
class MyCustomNode(ComfyUINode):
function = 'execute'
category = 'mycategory/mynodes'
display_name = 'My Custom Node'
deprecated = False
experimental = False
functionworks the same as the traditionalFUNCTIONmember, but has a default value ofexecute. This means that you can save yourself writing one line of code, if you simply name the method of your node that you want to be executedexecute.- The
categorymember is equivalent to theCATEGORYmember, it is simply written in lower case letters for consistency. display_namedefines the name that will be exported and used for showing your name in the ComfyUI frontend. If you do not define this member, it will simply use the name of the class, i.e.MyCustomNodein this example, automatically. This is only relevant, if you use the exporter function, described below, otherwise it can safely be ignored.deprecatedandexperimentalare simply aliases forDEPRECATEDandEXPERIMENTALrespectively
Defining input parameters
You define your input parameters as fields of the node class. All available input types are described in the documentation.
By default, the name of the field will be used as the name that is shown in the
UI. You can override this behavior, by passing the optional parameter
display_name, when defining your inputs. Any other options are defined as
parameters of the input field:
from comfyui_types import ComfyUINode, StringInput, FloatInput
class MyCustomNode(ComfyUINode):
pos_prompt_text = StringInput(default='masterpiece', multiline=True)
neg_prompt_text = StringInput(required=False, default='b&w', multiline=True)
custom_weight = FloatInput(default=1.0, min=0.0, max=1.0, step=0.1)
secret_parameter = FloatInput(hidden=True, display_name='super secret')
Input parameters can be required, optional, or hidden (see Input
type for more information). Usually, most
parameters are required, so the default value for required is True. If you
need an optional parameter, pass in required=False. If you want a hidden
parameter, pass in hidden=True. Due to the assumption of required being the
default state, hidden=True will overwrite the required state.
The defintion above will lead to the following inputs for our custom node:
>> print(MyCustomNode.INPUT_TYPES)
{
'required': {
'pos_prompt_text': ('STRING', {'multiline': True, 'default': 'masterpiece'}),
'custom_weight': ('FLOAT', {'default': 1.0, 'min': 0.0, 'max': 1.0,
'step': 0.1}),
},
'optional': {
'neg_prompt_text': ('STRING', {'multiline': True, 'default': 'b&w'})
},
'hidden': {
'super secret': ('FLOAT',)
}
}
Defining output parameters
Output parameters are defined analogously to input parameters as fields. Check the list of available output types in the documentation.
Example:
from comfyui_types import ComfyUINode, StringOutput, FloatOutput
class MyCustomNode(ComfyUINode):
# Definitions so far...
combined_prompt = StringOutput()
calculated_score = FloatOutput(display_name='Final Score')
Outputs are very straightforward to define, as they do not need any
configuration. The name for the RETURN_NAMES list is taken from the variable
name that you are assigning, i.e., combined_prompt in this example.
Alternatively, you can override this in the same way as with input parameters by
passing the optional display_name parameter to the definition. The example
above would result in the following outputs:
RETURN_TYPES = ('STRING', 'FLOAT')
RETURN_NAMES = ('combined_prompt', 'Final Score')
Examples
We are providing some examples here to help you better understand, how to write your own custom nodes.
Exporting custom nodes
Custom nodes can be manually exported as always like this:
NODE_CLASS_MAPPINGS = {
'MyCustomNode': MyCustomNode,
}
NODE_DISPLAY_NAME_MAPPINGS = {
'MyCustomNode': 'My Cool Custom Node',
}
__all__ = [NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS]
However, there is a convenience function to help with this:
NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS = export_nodes([
MyCustomNode,
])
__all__ = [NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS]
(The __all__ is not strictly needed, but good practice.)
This will automatically create the mapping tables according to the class name
and optionally the display_name property. If no display_name is set, the
class name is used.
Under the hood
Internally, the ComfyUINode simply exports the parameters that you have
defined with proper classes and types in such a way that ComfyUI can load them.
That means for example that all your input parameters are collected and used to
automatically create the INPUT_TYPES dictionary that ComfyUI will try to find
in your node. For example, the input parameter
pos_prompt_text = StringInput(default='masterpiece', multiline=True)
will automatically create the following entry in INPUT_TYPES:
('STRING', {'default': 'masterpiece', 'multiline': True})
Compatibility with ComfyUI
The way the ComfyUINode is defined is fully compatible with existing nodes and
practices. It simply creates the fields that are expected from a class that
ComfyUI imports as a custom node, like INPUT_TYPES. If at any point, you do
not like the conventions or they do not work with your use case, you can fall
back to the regular way of defining custom nodes in ComfyUI, i.e.:
- use
CATEGORYinstead ofcategory - use
FUNCTIONinstead offunction - define your
INPUT_TYPESorRETURN_TYPESas always
Only the parts that you choose to use will actually be active, you can mix and match to suit your preferences.
Projects using ComfyUI-Types
The following list of projects are using this project. This is not relevant to end-consumers, but if you are developing your own nodes, head over there and get some inspiration and real-world exposure:
- ComfyUI Claude: A set of custom nodes that are using Anthropic's Claude models for describing images and transforming texts.
If you want to add a project to this list, please open a PR!
Development
The project uses tox for development. You can get started like this:
git clone https://github.com/tkreuziger/comfyui-types.git ./comfyui_types
pip install -e ./comfyui_types
Then you can run different parts of the pipeline:
# Format code with Ruff
tox -e format
# Run linters Ruff and MyPy
tox -e lint
# Build the package
tox -e build
License
This code is provided under the terms of the GPL-3.0 license.
Contributions
Contributions of any kind (bug fixes, extensions, documentation etc.) are always welcome, simply open a PR!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file comfyui_types-1.3.1.tar.gz.
File metadata
- Download URL: comfyui_types-1.3.1.tar.gz
- Upload date:
- Size: 112.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5f46bfb59918b133650395792d52832bd23ee9636050f2d639deca47019c4cf
|
|
| MD5 |
9a8bbf7c43d2a3551e3ab12d614619e4
|
|
| BLAKE2b-256 |
ce345e511e56ea8b2b4e55c1ff1d373986910b21a492ac80daa7591eaf79abff
|
File details
Details for the file comfyui_types-1.3.1-py3-none-any.whl.
File metadata
- Download URL: comfyui_types-1.3.1-py3-none-any.whl
- Upload date:
- Size: 26.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
457bf0129163fe44df3574cbddf924a0a800ebb25ca2046ffbdc07135bc80b31
|
|
| MD5 |
6f10a6ca9a27d97fde1850559e1d9c77
|
|
| BLAKE2b-256 |
47ae5da40e591eb3efee8065e9616fc39062f2fb0b37373af5c7af401343b0e1
|