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 about 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

Requirements

  • Python 3.10+
  • No runtime dependencies

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 definition 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', {'lazy': False})
    }
}

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
cd comfyui_types
uv sync --group dev

Then you can run different parts of the pipeline:

# Format code with Ruff
tox -e format

# Run linters Ruff and MyPy
tox -e lint

# Run tests with pytest
tox -e test

# Build the package
tox -e build

Dependency Groups

This project uses PEP 735 dependency groups for development dependencies. The following groups are available:

  • lint: ruff, mypy
  • test: pytest
  • build: build, twine
  • dev: all of the above plus tox

Install with uv:

uv sync --group dev      # all dev dependencies
uv sync --group lint     # only lint tools
uv sync --group test     # only test tools

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.4.1.tar.gz (162.9 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.4.1-py3-none-any.whl (26.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: comfyui_types-1.4.1.tar.gz
  • Upload date:
  • Size: 162.9 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.4.1.tar.gz
Algorithm Hash digest
SHA256 eddcd590db232bdcd1423243771ae9b9a91abf90c74b94fbe99c5428c14b19fc
MD5 6bfdd8a459ac3f4217942b5a44105286
BLAKE2b-256 ca4edbb7c7e4cfef879d0b2004fcf916fab679fd00cfcdeca5afbce0aee6919f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: comfyui_types-1.4.1-py3-none-any.whl
  • Upload date:
  • Size: 26.7 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.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 38dd7adab9658d43717f6f46ced31e80da59882a1012306ca4546cd4baf8ba34
MD5 aa3904c472a74af8281027e75f73a9f6
BLAKE2b-256 5420bf33c9bf021c1e9a7294d6a81bd744c475787d2106e7c6711d87a4fa46e1

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