Skip to main content

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
  • function works the same as the traditional FUNCTION member, but has a default value of execute. 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 executed execute.
  • The category member is equivalent to the CATEGORY member, it is simply written in lower case letters for consistency.
  • display_name defines 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. MyCustomNode in this example, automatically. This is only relevant, if you use the exporter function, described below, otherwise it can safely be ignored.
  • deprecated and experimental are simply aliases for DEPRECATED and EXPERIMENTAL respectively

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 CATEGORY instead of category
  • use FUNCTION instead of function
  • define your INPUT_TYPES or RETURN_TYPES as 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

comfyui_types-1.3.4.tar.gz (112.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

comfyui_types-1.3.4-py3-none-any.whl (26.3 kB view details)

Uploaded Python 3

File details

Details for the file comfyui_types-1.3.4.tar.gz.

File metadata

  • Download URL: comfyui_types-1.3.4.tar.gz
  • Upload date:
  • Size: 112.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for comfyui_types-1.3.4.tar.gz
Algorithm Hash digest
SHA256 cea4a09b96fa8f81434bbde758d0f74f09e4e9c9fe1da584345f3434fa87641f
MD5 ff45204411580c3e4a783b2ff05486cf
BLAKE2b-256 5312bb4aedf93aeb68b234df5ea340fdc276f77300afac0a6c51260224e22973

See more details on using hashes here.

File details

Details for the file comfyui_types-1.3.4-py3-none-any.whl.

File metadata

  • Download URL: comfyui_types-1.3.4-py3-none-any.whl
  • Upload date:
  • Size: 26.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for comfyui_types-1.3.4-py3-none-any.whl
Algorithm Hash digest
SHA256 32c702a212f01cebd134c1a62cbcc2738d57713180c956938b7b0a4d6344afc7
MD5 812db2b8988334612662cd39e7b508d7
BLAKE2b-256 47dde4e88c97e0a622202865512f7b021b8f89fcf632d14cedc99a4a2f6fbcc2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page