Salt Workflow Input¶
Documentation¶
- Class name:
SaltInput
- Category:
SALT/IO
- Output node:
True
The SaltInput node is designed to facilitate the creation and management of inputs for workflows within the Salt AI platform. It allows for the specification of various input types, including strings, numbers, booleans, and files, and supports additional features such as image and mask inputs, setting allowed values, and specifying whether user overrides are required. This node plays a crucial role in customizing and controlling the flow of data into Salt AI workflows, ensuring that inputs are correctly defined and processed according to the workflow's requirements.
Input types¶
Required¶
input_name
- Specifies the name of the input. This name is used to identify the input within the workflow, making it easier to reference and manage.
- Comfy dtype:
STRING
- Python dtype:
str
input_desc
- Provides a description for the input. This description helps to clarify the purpose and expected content of the input, aiding in the workflow's documentation and usability.
- Comfy dtype:
STRING
- Python dtype:
str
input_type
- Defines the type of the input. This can range from basic types like strings and numbers to more complex types like images and files, allowing for versatile input handling in the workflow.
- Comfy dtype:
COMBO[STRING]
- Python dtype:
list[str]
input_value
- The actual value for the input. Depending on the input type, this could be text, a numerical value, an image path, etc., serving as the primary data that the workflow will process.
- Comfy dtype:
STRING
- Python dtype:
str
Optional¶
input_image
- An optional image input. When provided, this allows the workflow to directly process an image, adding a visual data processing capability.
- Comfy dtype:
IMAGE
- Python dtype:
Image
input_mask
- An optional mask input. This is used in conjunction with image inputs to apply specific processing or transformations based on the mask.
- Comfy dtype:
MASK
- Python dtype:
Mask
input_allowed_values
- Specifies allowed values for the input. This is useful for inputs that should only accept a predefined set of values, ensuring data validity.
- Comfy dtype:
STRING
- Python dtype:
str
user_override_required
- Indicates whether a user override is required for the input. This can be used to enforce user interaction for certain inputs, ensuring that specific conditions are met before proceeding.
- Comfy dtype:
BOOLEAN
- Python dtype:
bool
relative_path
- Determines whether the input value should be treated as a relative path. This is relevant for file inputs, affecting how the file path is interpreted and handled within the workflow.
- Comfy dtype:
BOOLEAN
- Python dtype:
bool
Output types¶
value
- Comfy dtype:
*
- unknown
- Python dtype:
unknown
- Comfy dtype:
ui
- Returns a UI dictionary containing metadata and results related to the input processing. This includes information such as the input's unique ID, any relevant asset IDs, and the processed input data, facilitating integration with the Salt AI platform's UI components.
Usage tips¶
- Infra type:
CPU
- Common nodes: unknown
Source code¶
class SaltInput:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"input_name": ("STRING", {}),
"input_desc": ("STRING", {}),
"input_type": (["STRING", "FLOAT", "INT", "BOOLEAN", "IMAGE", "MASK", "SEED", "FILE"],),
"input_value": ("STRING", {"multiline": True, "dynamicPrompts": False})
},
"optional": {
"input_image": ("IMAGE",),
"input_mask": ("MASK",),
"input_allowed_values": ("STRING", {"default": ""}),
"user_override_required": ("BOOLEAN", {"default": False}),
"relative_path": ("BOOLEAN", {"default": False})
},
"hidden": {"unique_id": "UNIQUE_ID"},
}
OUTPUT_NODE = True
RETURN_TYPES = (WILDCARD,)
RETURN_NAMES = ("value",)
FUNCTION = "input"
CATEGORY = "SALT/IO"
def input(
self,
input_name,
input_desc,
input_value,
input_type,
input_image=None,
input_mask=None,
input_allowed_values="",
user_override_required=False,
relative_path=False,
unique_id=0,
):
src_image = None
src_file = None
is_asset = False
# Is an asset type
if input_type in ["IMAGE", "MASK", "FILE"]:
is_asset = True
# UI Output
ui = {
"ui": {
"salt_input": [{
"id": unique_id,
"name": input_name or "input_" + str(unique_id),
"description": input_desc or "",
"asset": is_asset or False,
"type": input_type or "string",
"value": input_value or "",
}]
}
}
out = ""
if is_asset:
# Input value must be evaluated first to override input images/masks
if input_value.strip():
input_value = input_value.strip()
# Load image from path from input_value
if input_value.endswith(('.png', '.jpeg', '.jpg', '.gif', '.webp', '.tiff')):
try:
src_image = Image.open(input_value).convert("RGBA")
except Exception as e:
errmsg = f"Error loading image from specified path {input_value}: {e}"
logger.warning(errmsg)
# Passthrough input_value (which should be a path from Salt Backend)
elif input_type == "FILE":
src_file = input_value # if os.path.exists(input_value) else "None"
if relative_path:
src_file = get_relative_path(src_file)
# Log value to console
log_values(unique_id, input_name, input_type, src_file)
return {"ui": ui, "result": (src_file,)}
else:
errmsg = "Invalid node configuration! Do you mean to use `IMAGE`, `MASK`, or `FILE` input_types?"
logger.error(errmsg)
raise AttributeError(errmsg)
elif isinstance(input_image, torch.Tensor):
# Input `IMAGE` is provided, so we act like a passthrough
return (input_image, ui)
elif isinstance(input_mask, torch.Tensor):
# Input `MASK` is provided, so we act like a passthrough
return (input_mask, ui)
if src_image:
if input_type == "MASK":
# If it's a mask and the image has an alpha channel, extract it
if src_image.mode == "RGBA":
alpha_channel = src_image.split()[-1]
src_image = pil2mask(alpha_channel.convert("L"))
# If no alpha channel, convert the whole image to grayscale as a mask (could be bitwise representation)
else:
src_image = pil2mask(src_image.convert("L"))
elif input_type == "IMAGE":
# Ensure image is in RGB for `IMAGE`` data type
src_image = pil2tensor(src_image.convert("RGB"))
else:
# Gracefully allow execution to continue, provided a black image (to hopefully signal issue?)
errmsg = "Unable to determine IMAGE or MASK to load! Returning image blank"
logger.warning(errmsg)
src_blank = Image.new("RGB", (512, 512), (0, 0, 0))
if input_type == "IMAGE":
src_image = pil2tensor(src_blank)
else:
src_image = pil2mask(src_blank)
# Log value to console
log_values(unique_id, input_name, input_type, src_image)
return (src_image, ui)
# We're still here? We must be dealing with a primitive value
if input_allowed_values != "" and input_value.strip() not in [o.strip() for o in input_allowed_values.split(',')]:
errmsg = 'The provided input is not a supported value'
logger.warning(errmsg)
raise ValueError(errmsg)
match input_type:
case "STRING":
out = str(input_value)
case "INT":
out = int(input_value)
case "SEED":
out = int(input_value)
case "FLOAT":
out = float(input_value)
case "BOOLEAN":
out = bool_str(input_value)
case _:
out = input_value
# Log value to console
log_values(unique_id, input_name, input_type, out)
return (out, ui)