Initial commit

This commit is contained in:
Drustan Hawk
2023-10-19 07:03:46 +02:00
commit 147d648192
9 changed files with 171 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 120
+4
View File
@@ -0,0 +1,4 @@
venv/
__pycache__/
.vscode/*
+4
View File
@@ -0,0 +1,4 @@
[mypy]
strict = True
mypy_path = src
packages = primitivetypes
+8
View File
@@ -0,0 +1,8 @@
# primitive-types
This repository contains typed primitives for ComfyUI in the form of the following nodes:
- `int`
- `float`
- `string`
- `string` (multiline)
The motivation for these primitives is that the standard primitive node cannot be routed. As a result, if you have a configuration node, e.g., `CFG`, you must connect it directly to the sampler node. However, with an `int` node, you can route it (several times if you wish)
+1
View File
@@ -0,0 +1 @@
from .src.primitivetypes.export import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS # noqa: F401
View File
+69
View File
@@ -0,0 +1,69 @@
from abc import ABC, abstractmethod
from typing import Any, Generic, Literal, NotRequired, TypedDict, TypeVar
Number = TypeVar("Number", int, float)
TypeString = Literal["INT", "FLOAT", "STRING"]
class NumberInputDict(TypedDict, Generic[Number]):
default: Number
min: NotRequired[Number]
max: NotRequired[Number]
step: Number
display: Literal["number", "slider"]
class StringInputDict(TypedDict):
default: str
multiline: bool
class InputDict(TypedDict):
required: dict[
str,
(
tuple[TypeString | list[TypeString]] |
tuple[TypeString, NumberInputDict[int] | NumberInputDict[float] | StringInputDict]
)
]
hidden: NotRequired[dict[
str,
(
tuple[TypeString | list[TypeString]] |
tuple[TypeString, NumberInputDict[int] | NumberInputDict[float] | StringInputDict]
)
]]
optional: NotRequired[dict[
str,
(
tuple[TypeString | list[TypeString]] |
tuple[TypeString, NumberInputDict[int] | NumberInputDict[float] | StringInputDict]
)
]]
class Node(ABC):
FUNCTION = "execute"
OUTPUT_NODE = False
@property
@abstractmethod
def RETURN_TYPES(self) -> tuple[TypeString, ...]:
pass
@property
@abstractmethod
def CATEGORY(self) -> str:
pass
@classmethod
@abstractmethod
def INPUT_TYPES(cls) -> InputDict:
pass
@abstractmethod
def execute(self) -> tuple[Any, ...] | None:
pass
+17
View File
@@ -0,0 +1,17 @@
from .nodes import Int, Float, String, StringMultiline
NODE_CLASS_MAPPINGS = {
"int": Int,
"float": Float,
"string": String,
"string_multiline": StringMultiline
}
NODE_DISPLAY_NAME_MAPPINGS = {
"int": "int",
"float": "float",
"string": "string",
"string_multiline": "string (multiline)"
}
+66
View File
@@ -0,0 +1,66 @@
from typing import TypeVar
from .base import Node, InputDict
T = TypeVar("T")
class CategoryTyped:
CATEGORY = "utils/Primitive Types"
class PassthroughExecute:
FUNCTION = "execute"
def execute(self, *values: T) -> tuple[T, ...] | None:
if values:
return tuple(values)
return None
class Int(PassthroughExecute, CategoryTyped, Node):
@classmethod
def INPUT_TYPES(cls) -> InputDict:
return dict(
required=dict(
value=("INT", dict(default=0, step=1, display="number"))
)
)
RETURN_TYPES = ("INT",)
class Float(PassthroughExecute, CategoryTyped, Node):
@classmethod
def INPUT_TYPES(cls) -> InputDict:
return dict(
required=dict(
value=("FLOAT", dict(default=0, min=0, max=4096, step=1, display="number"))
)
)
RETURN_TYPES = ("FLOAT",)
class String(PassthroughExecute, CategoryTyped, Node):
@classmethod
def INPUT_TYPES(cls) -> InputDict:
return dict(
required=dict(
text=("STRING", dict(default="", multiline=False))
)
)
RETURN_TYPES = ("STRING",)
class StringMultiline(PassthroughExecute, CategoryTyped, Node):
@classmethod
def INPUT_TYPES(cls) -> InputDict:
return dict(
required=dict(
text=("STRING", dict(default="", multiline=True))
)
)
RETURN_TYPES = ("STRING",)