Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b857b557f3 | ||
|
|
1666f78311 |
@@ -8,16 +8,6 @@ class ComfyUIDeployExternalBoolean:
|
|||||||
{"multiline": False, "default": "input_bool"},
|
{"multiline": False, "default": "input_bool"},
|
||||||
),
|
),
|
||||||
"default_value": ("BOOLEAN", {"default": False})
|
"default_value": ("BOOLEAN", {"default": False})
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +16,7 @@ class ComfyUIDeployExternalBoolean:
|
|||||||
|
|
||||||
FUNCTION = "run"
|
FUNCTION = "run"
|
||||||
|
|
||||||
def run(self, input_id, default_value=None, display_name=None, description=None):
|
def run(self, input_id, default_value=None):
|
||||||
print(f"Node '{input_id}' processing with switch set to {default_value}")
|
print(f"Node '{input_id}' processing with switch set to {default_value}")
|
||||||
return [default_value]
|
return [default_value]
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,6 @@ class ComfyUIDeployExternalCheckpoint:
|
|||||||
},
|
},
|
||||||
"optional": {
|
"optional": {
|
||||||
"default_value": (folder_paths.get_filename_list("checkpoints"), ),
|
"default_value": (folder_paths.get_filename_list("checkpoints"), ),
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +33,7 @@ class ComfyUIDeployExternalCheckpoint:
|
|||||||
|
|
||||||
CATEGORY = "deploy"
|
CATEGORY = "deploy"
|
||||||
|
|
||||||
def run(self, input_id, default_value=None, display_name=None, description=None):
|
def run(self, input_id, default_value=None):
|
||||||
import requests
|
import requests
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
|||||||
@@ -1,108 +0,0 @@
|
|||||||
from PIL import Image, ImageOps
|
|
||||||
import numpy as np
|
|
||||||
import torch
|
|
||||||
import folder_paths
|
|
||||||
|
|
||||||
|
|
||||||
class AnyType(str):
|
|
||||||
def __ne__(self, __value: object) -> bool:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
WILDCARD = AnyType("*")
|
|
||||||
|
|
||||||
|
|
||||||
class ComfyUIDeployExternalFaceModel:
|
|
||||||
@classmethod
|
|
||||||
def INPUT_TYPES(s):
|
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"input_id": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": "input_reactor_face_model"},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"default_face_model_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"face_model_save_name": ( # if `default_face_model_name` is a link to download a file, we will attempt to save it with this name
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
"face_model_url": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = (WILDCARD,)
|
|
||||||
RETURN_NAMES = ("path",)
|
|
||||||
|
|
||||||
FUNCTION = "run"
|
|
||||||
|
|
||||||
CATEGORY = "deploy"
|
|
||||||
|
|
||||||
def run(
|
|
||||||
self,
|
|
||||||
input_id,
|
|
||||||
default_face_model_name=None,
|
|
||||||
face_model_save_name=None,
|
|
||||||
display_name=None,
|
|
||||||
description=None,
|
|
||||||
face_model_url=None,
|
|
||||||
):
|
|
||||||
import requests
|
|
||||||
import os
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
if face_model_url and face_model_url.startswith("http"):
|
|
||||||
if face_model_save_name:
|
|
||||||
existing_face_models = folder_paths.get_filename_list("reactor/faces")
|
|
||||||
# Check if face_model_save_name exists in the list
|
|
||||||
if face_model_save_name in existing_face_models:
|
|
||||||
print(f"using face model: {face_model_save_name}")
|
|
||||||
return (face_model_save_name,)
|
|
||||||
else:
|
|
||||||
face_model_save_name = str(uuid.uuid4()) + ".safetensors"
|
|
||||||
print(face_model_save_name)
|
|
||||||
print(folder_paths.folder_names_and_paths["reactor/faces"][0][0])
|
|
||||||
destination_path = os.path.join(
|
|
||||||
folder_paths.folder_names_and_paths["reactor/faces"][0][0],
|
|
||||||
face_model_save_name,
|
|
||||||
)
|
|
||||||
|
|
||||||
print(destination_path)
|
|
||||||
print(
|
|
||||||
"Downloading external face model - "
|
|
||||||
+ face_model_url
|
|
||||||
+ " to "
|
|
||||||
+ destination_path
|
|
||||||
)
|
|
||||||
response = requests.get(
|
|
||||||
face_model_url,
|
|
||||||
headers={"User-Agent": "Mozilla/5.0"},
|
|
||||||
allow_redirects=True,
|
|
||||||
)
|
|
||||||
with open(destination_path, "wb") as out_file:
|
|
||||||
out_file.write(response.content)
|
|
||||||
return (face_model_save_name,)
|
|
||||||
else:
|
|
||||||
print(f"using face model: {default_face_model_name}")
|
|
||||||
return (default_face_model_name,)
|
|
||||||
|
|
||||||
|
|
||||||
NODE_CLASS_MAPPINGS = {"ComfyUIDeployExternalFaceModel": ComfyUIDeployExternalFaceModel}
|
|
||||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
|
||||||
"ComfyUIDeployExternalFaceModel": "External Face Model (ComfyUI Deploy)"
|
|
||||||
}
|
|
||||||
@@ -15,14 +15,6 @@ class ComfyUIDeployExternalImage:
|
|||||||
},
|
},
|
||||||
"optional": {
|
"optional": {
|
||||||
"default_value": ("IMAGE",),
|
"default_value": ("IMAGE",),
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +25,7 @@ class ComfyUIDeployExternalImage:
|
|||||||
|
|
||||||
CATEGORY = "image"
|
CATEGORY = "image"
|
||||||
|
|
||||||
def run(self, input_id, default_value=None, display_name=None, description=None):
|
def run(self, input_id, default_value=None):
|
||||||
image = default_value
|
image = default_value
|
||||||
try:
|
try:
|
||||||
if input_id.startswith('http'):
|
if input_id.startswith('http'):
|
||||||
|
|||||||
@@ -15,14 +15,6 @@ class ComfyUIDeployExternalImageAlpha:
|
|||||||
},
|
},
|
||||||
"optional": {
|
"optional": {
|
||||||
"default_value": ("IMAGE",),
|
"default_value": ("IMAGE",),
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +25,7 @@ class ComfyUIDeployExternalImageAlpha:
|
|||||||
|
|
||||||
CATEGORY = "image"
|
CATEGORY = "image"
|
||||||
|
|
||||||
def run(self, input_id, default_value=None, display_name=None, description=None):
|
def run(self, input_id, default_value=None):
|
||||||
image = default_value
|
image = default_value
|
||||||
try:
|
try:
|
||||||
if input_id.startswith('http'):
|
if input_id.startswith('http'):
|
||||||
|
|||||||
@@ -21,14 +21,6 @@ class ComfyUIDeployExternalImageBatch:
|
|||||||
},
|
},
|
||||||
"optional": {
|
"optional": {
|
||||||
"default_value": ("IMAGE",),
|
"default_value": ("IMAGE",),
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,34 +31,14 @@ class ComfyUIDeployExternalImageBatch:
|
|||||||
|
|
||||||
CATEGORY = "image"
|
CATEGORY = "image"
|
||||||
|
|
||||||
def process_image(self, image):
|
def run(self, input_id, images=None, default_value=None):
|
||||||
image = ImageOps.exif_transpose(image)
|
|
||||||
image = image.convert("RGB")
|
|
||||||
image = np.array(image).astype(np.float32) / 255.0
|
|
||||||
image_tensor = torch.from_numpy(image)[None,]
|
|
||||||
return image_tensor
|
|
||||||
|
|
||||||
def run(self, input_id, images=None, default_value=None, display_name=None, description=None):
|
|
||||||
import requests
|
|
||||||
import zipfile
|
|
||||||
import io
|
|
||||||
|
|
||||||
processed_images = []
|
processed_images = []
|
||||||
try:
|
try:
|
||||||
images_list = json.loads(images) # Assuming images is a JSON array string
|
images_list = json.loads(images) # Assuming images is a JSON array string
|
||||||
print(images_list)
|
print(images_list)
|
||||||
for img_input in images_list:
|
for img_input in images_list:
|
||||||
if img_input.startswith('http') and img_input.endswith('.zip'):
|
if img_input.startswith('http'):
|
||||||
print("Fetching zip file from url: ", img_input)
|
import requests
|
||||||
response = requests.get(img_input)
|
|
||||||
zip_file = zipfile.ZipFile(io.BytesIO(response.content))
|
|
||||||
for file_name in zip_file.namelist():
|
|
||||||
if file_name.lower().endswith(('.png', '.jpg', '.jpeg')):
|
|
||||||
with zip_file.open(file_name) as file:
|
|
||||||
image = Image.open(file)
|
|
||||||
image = self.process_image(image)
|
|
||||||
processed_images.append(image)
|
|
||||||
elif img_input.startswith('http'):
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
print("Fetching image from url: ", img_input)
|
print("Fetching image from url: ", img_input)
|
||||||
response = requests.get(img_input)
|
response = requests.get(img_input)
|
||||||
|
|||||||
@@ -4,15 +4,12 @@ import numpy as np
|
|||||||
import torch
|
import torch
|
||||||
import folder_paths
|
import folder_paths
|
||||||
|
|
||||||
|
|
||||||
class AnyType(str):
|
class AnyType(str):
|
||||||
def __ne__(self, __value: object) -> bool:
|
def __ne__(self, __value: object) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
WILDCARD = AnyType("*")
|
WILDCARD = AnyType("*")
|
||||||
|
|
||||||
|
|
||||||
class ComfyUIDeployExternalLora:
|
class ComfyUIDeployExternalLora:
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
@@ -25,22 +22,6 @@ class ComfyUIDeployExternalLora:
|
|||||||
},
|
},
|
||||||
"optional": {
|
"optional": {
|
||||||
"default_lora_name": (folder_paths.get_filename_list("loras"),),
|
"default_lora_name": (folder_paths.get_filename_list("loras"),),
|
||||||
"lora_save_name": ( # if `default_lora_name` is a link to download a file, we will attempt to save it with this name
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
"lora_url": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,55 +32,30 @@ class ComfyUIDeployExternalLora:
|
|||||||
|
|
||||||
CATEGORY = "deploy"
|
CATEGORY = "deploy"
|
||||||
|
|
||||||
def run(
|
def run(self, input_id, default_lora_name=None):
|
||||||
self,
|
|
||||||
input_id,
|
|
||||||
default_lora_name=None,
|
|
||||||
lora_save_name=None,
|
|
||||||
display_name=None,
|
|
||||||
description=None,
|
|
||||||
lora_url=None,
|
|
||||||
):
|
|
||||||
import requests
|
import requests
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
if lora_url:
|
if default_lora_name.startswith("http"):
|
||||||
if lora_url.startswith("http"):
|
unique_filename = str(uuid.uuid4()) + ".safetensors"
|
||||||
if lora_save_name:
|
print(unique_filename)
|
||||||
existing_loras = folder_paths.get_filename_list("loras")
|
print(folder_paths.folder_names_and_paths["loras"][0][0])
|
||||||
# Check if lora_save_name exists in the list
|
destination_path = os.path.join(
|
||||||
if lora_save_name in existing_loras:
|
folder_paths.folder_names_and_paths["loras"][0][0], unique_filename
|
||||||
print(f"using lora: {lora_save_name}")
|
)
|
||||||
return (lora_save_name,)
|
print(destination_path)
|
||||||
else:
|
print("Downloading external lora - " + input_id + " to " + destination_path)
|
||||||
lora_save_name = str(uuid.uuid4()) + ".safetensors"
|
response = requests.get(
|
||||||
print(lora_save_name)
|
input_id,
|
||||||
print(folder_paths.folder_names_and_paths["loras"][0][0])
|
headers={"User-Agent": "Mozilla/5.0"},
|
||||||
destination_path = os.path.join(
|
allow_redirects=True,
|
||||||
folder_paths.folder_names_and_paths["loras"][0][0], lora_save_name
|
)
|
||||||
)
|
with open(destination_path, "wb") as out_file:
|
||||||
print(destination_path)
|
out_file.write(response.content)
|
||||||
print(
|
return (unique_filename,)
|
||||||
"Downloading external lora - "
|
|
||||||
+ lora_url
|
|
||||||
+ " to "
|
|
||||||
+ destination_path
|
|
||||||
)
|
|
||||||
response = requests.get(
|
|
||||||
lora_url,
|
|
||||||
headers={"User-Agent": "Mozilla/5.0"},
|
|
||||||
allow_redirects=True,
|
|
||||||
)
|
|
||||||
with open(destination_path, "wb") as out_file:
|
|
||||||
out_file.write(response.content)
|
|
||||||
print(f"Ext Lora loading: {lora_url} to {lora_save_name}")
|
|
||||||
return (lora_save_name,)
|
|
||||||
else:
|
|
||||||
print(f"Ext Lora loading: {lora_url}")
|
|
||||||
return (lora_url,)
|
|
||||||
else:
|
else:
|
||||||
print(f"Ext Lora loading: {default_lora_name}")
|
print(f"using lora: {default_lora_name}")
|
||||||
return (default_lora_name,)
|
return (default_lora_name,)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,15 +16,7 @@ class ComfyUIDeployExternalNumber:
|
|||||||
"optional": {
|
"optional": {
|
||||||
"default_value": (
|
"default_value": (
|
||||||
"FLOAT",
|
"FLOAT",
|
||||||
{"multiline": True, "display": "number", "default": 0, "min": -2147483647, "max": 2147483647, "step": 0.01},
|
{"multiline": True, "display": "number", "default": 0, "step": 0.01},
|
||||||
),
|
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +28,7 @@ class ComfyUIDeployExternalNumber:
|
|||||||
|
|
||||||
CATEGORY = "number"
|
CATEGORY = "number"
|
||||||
|
|
||||||
def run(self, input_id, default_value=None, display_name=None, description=None):
|
def run(self, input_id, default_value=None):
|
||||||
try:
|
try:
|
||||||
float_value = float(input_id)
|
float_value = float(input_id)
|
||||||
print("my number", float_value)
|
print("my number", float_value)
|
||||||
|
|||||||
@@ -16,15 +16,7 @@ class ComfyUIDeployExternalNumberInt:
|
|||||||
"optional": {
|
"optional": {
|
||||||
"default_value": (
|
"default_value": (
|
||||||
"INT",
|
"INT",
|
||||||
{"multiline": True, "display": "number", "min": -2147483647, "max": 2147483647, "default": 0},
|
{"multiline": True, "display": "number", "default": 0},
|
||||||
),
|
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +28,7 @@ class ComfyUIDeployExternalNumberInt:
|
|||||||
|
|
||||||
CATEGORY = "number"
|
CATEGORY = "number"
|
||||||
|
|
||||||
def run(self, input_id, default_value=None, display_name=None, description=None):
|
def run(self, input_id, default_value=None):
|
||||||
if not input_id or (isinstance(input_id, str) and not input_id.strip().isdigit()):
|
if not input_id or (isinstance(input_id, str) and not input_id.strip().isdigit()):
|
||||||
return [default_value]
|
return [default_value]
|
||||||
return [int(input_id)]
|
return [int(input_id)]
|
||||||
|
|||||||
@@ -11,23 +11,15 @@ class ComfyUIDeployExternalNumberSlider:
|
|||||||
"optional": {
|
"optional": {
|
||||||
"default_value": (
|
"default_value": (
|
||||||
"FLOAT",
|
"FLOAT",
|
||||||
{"multiline": True, "display": "number", "min": -2147483647, "max": 2147483647, "default": 0.5, "step": 0.01},
|
{"multiline": True, "display": "number", "default": 0.5, "step": 0.01},
|
||||||
),
|
),
|
||||||
"min_value": (
|
"min_value": (
|
||||||
"FLOAT",
|
"FLOAT",
|
||||||
{"multiline": True, "display": "number", "min": -2147483647, "max": 2147483647, "default": 0, "step": 0.01},
|
{"multiline": True, "display": "number", "default": 0, "step": 0.01},
|
||||||
),
|
),
|
||||||
"max_value": (
|
"max_value": (
|
||||||
"FLOAT",
|
"FLOAT",
|
||||||
{"multiline": True, "display": "number", "min": -2147483647, "max": 2147483647, "default": 1, "step": 0.01},
|
{"multiline": True, "display": "number", "default": 1, "step": 0.01},
|
||||||
),
|
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +31,7 @@ class ComfyUIDeployExternalNumberSlider:
|
|||||||
|
|
||||||
CATEGORY = "number"
|
CATEGORY = "number"
|
||||||
|
|
||||||
def run(self, input_id, default_value=None, min_value=0, max_value=1, display_name=None, description=None):
|
def run(self, input_id, default_value=None, min_value=0, max_value=1):
|
||||||
try:
|
try:
|
||||||
float_value = float(input_id)
|
float_value = float(input_id)
|
||||||
if min_value <= float_value <= max_value:
|
if min_value <= float_value <= max_value:
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
class StringFunction:
|
|
||||||
@classmethod
|
|
||||||
def INPUT_TYPES(s):
|
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"action": (["append", "replace"], {}),
|
|
||||||
"tidy_tags": (["yes", "no"], {}),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"text_a": ("STRING", {"multiline": True, "dynamicPrompts": False}),
|
|
||||||
"text_b": ("STRING", {"multiline": True, "dynamicPrompts": False}),
|
|
||||||
"text_c": ("STRING", {"multiline": True, "dynamicPrompts": False}),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = ("STRING",)
|
|
||||||
FUNCTION = "exec"
|
|
||||||
CATEGORY = "utils"
|
|
||||||
OUTPUT_NODE = True
|
|
||||||
|
|
||||||
def exec(self, action, tidy_tags, text_a="", text_b="", text_c=""):
|
|
||||||
tidy_tags = tidy_tags == "yes"
|
|
||||||
out = ""
|
|
||||||
if action == "append":
|
|
||||||
out = (", " if tidy_tags else "").join(
|
|
||||||
filter(None, [text_a, text_b, text_c])
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
if text_c is None:
|
|
||||||
text_c = ""
|
|
||||||
if text_b.startswith("/") and text_b.endswith("/"):
|
|
||||||
regex = text_b[1:-1]
|
|
||||||
out = re.sub(regex, text_c, text_a)
|
|
||||||
else:
|
|
||||||
out = text_a.replace(text_b, text_c)
|
|
||||||
if tidy_tags:
|
|
||||||
out = re.sub(r"\s{2,}", " ", out)
|
|
||||||
out = out.replace(" ,", ",")
|
|
||||||
out = re.sub(r",{2,}", ",", out)
|
|
||||||
out = out.strip()
|
|
||||||
return {"ui": {"text": (out,)}, "result": (out,)}
|
|
||||||
|
|
||||||
|
|
||||||
NODE_CLASS_MAPPINGS = {
|
|
||||||
"ComfyUIDeployStringCombine": StringFunction,
|
|
||||||
}
|
|
||||||
|
|
||||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
|
||||||
"ComfyUIDeployStringCombine": "String Combine (ComfyUI Deploy)",
|
|
||||||
}
|
|
||||||
@@ -18,14 +18,6 @@ class ComfyUIDeployExternalText:
|
|||||||
"STRING",
|
"STRING",
|
||||||
{"multiline": True, "default": ""},
|
{"multiline": True, "default": ""},
|
||||||
),
|
),
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +28,7 @@ class ComfyUIDeployExternalText:
|
|||||||
|
|
||||||
CATEGORY = "text"
|
CATEGORY = "text"
|
||||||
|
|
||||||
def run(self, input_id, default_value=None, display_name=None, description=None):
|
def run(self, input_id, default_value=None):
|
||||||
return [default_value]
|
return [default_value]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
class AnyType(str):
|
|
||||||
def __ne__(self, __value: object) -> bool:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
WILDCARD = AnyType("*")
|
|
||||||
|
|
||||||
class ComfyUIDeployExternalTextAny:
|
|
||||||
@classmethod
|
|
||||||
def INPUT_TYPES(s):
|
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"input_id": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": "input_text"},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
"optional": {
|
|
||||||
"default_value": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = (WILDCARD,)
|
|
||||||
RETURN_NAMES = ("text",)
|
|
||||||
|
|
||||||
FUNCTION = "run"
|
|
||||||
|
|
||||||
CATEGORY = "text"
|
|
||||||
|
|
||||||
def run(self, input_id, default_value=None, display_name=None, description=None):
|
|
||||||
return [default_value]
|
|
||||||
|
|
||||||
|
|
||||||
NODE_CLASS_MAPPINGS = {"ComfyUIDeployExternalTextAny": ComfyUIDeployExternalTextAny}
|
|
||||||
NODE_DISPLAY_NAME_MAPPINGS = {"ComfyUIDeployExternalTextAny": "External Text Any (ComfyUI Deploy)"}
|
|
||||||
@@ -764,15 +764,7 @@ class ComfyUIDeployExternalVideo:
|
|||||||
"optional": {
|
"optional": {
|
||||||
"meta_batch": ("VHS_BatchManager",),
|
"meta_batch": ("VHS_BatchManager",),
|
||||||
"vae": ("VAE",),
|
"vae": ("VAE",),
|
||||||
"default_video": (sorted(files),),
|
"default_value": (sorted(files),),
|
||||||
"display_name": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": False, "default": ""},
|
|
||||||
),
|
|
||||||
"description": (
|
|
||||||
"STRING",
|
|
||||||
{"multiline": True, "default": ""},
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
"hidden": {
|
"hidden": {
|
||||||
"unique_id": "UNIQUE_ID"
|
"unique_id": "UNIQUE_ID"
|
||||||
@@ -804,6 +796,8 @@ class ComfyUIDeployExternalVideo:
|
|||||||
meta_batch = kwargs.get("meta_batch")
|
meta_batch = kwargs.get("meta_batch")
|
||||||
unique_id = kwargs.get("unique_id")
|
unique_id = kwargs.get("unique_id")
|
||||||
|
|
||||||
|
video = kwargs.get("default_value")
|
||||||
|
video_path = folder_paths.get_annotated_filepath(video.strip('"'))
|
||||||
|
|
||||||
input_dir = folder_paths.get_input_directory()
|
input_dir = folder_paths.get_input_directory()
|
||||||
if input_id.startswith("http"):
|
if input_id.startswith("http"):
|
||||||
@@ -833,11 +827,8 @@ class ComfyUIDeployExternalVideo:
|
|||||||
leave=True,
|
leave=True,
|
||||||
):
|
):
|
||||||
out_file.write(chunk)
|
out_file.write(chunk)
|
||||||
else:
|
|
||||||
video = kwargs.get("default_video", None)
|
print("video path: ", video_path)
|
||||||
if video is None:
|
|
||||||
raise "No default video given and no external video provided"
|
|
||||||
video_path = folder_paths.get_annotated_filepath(video.strip('"'))
|
|
||||||
|
|
||||||
return load_video_cv(
|
return load_video_cv(
|
||||||
video=video_path,
|
video=video_path,
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
import folder_paths
|
|
||||||
class AnyType(str):
|
|
||||||
def __ne__(self, __value: object) -> bool:
|
|
||||||
return False
|
|
||||||
|
|
||||||
from os import walk
|
|
||||||
|
|
||||||
WILDCARD = AnyType("*")
|
|
||||||
|
|
||||||
MODEL_EXTENSIONS = {
|
|
||||||
"safetensors": "SafeTensors file format",
|
|
||||||
"ckpt": "Checkpoint file",
|
|
||||||
"pth": "PyTorch serialized file",
|
|
||||||
"pkl": "Pickle file",
|
|
||||||
"onnx": "ONNX file",
|
|
||||||
}
|
|
||||||
|
|
||||||
def fetch_files(path):
|
|
||||||
for (dirpath, dirnames, filenames) in walk(path):
|
|
||||||
fs = []
|
|
||||||
if len(dirnames) > 0:
|
|
||||||
for dirname in dirnames:
|
|
||||||
fs.extend(fetch_files(f"{dirpath}/{dirname}"))
|
|
||||||
for filename in filenames:
|
|
||||||
# Remove "./models/" from the beginning of dirpath
|
|
||||||
relative_dirpath = dirpath.replace("./models/", "", 1)
|
|
||||||
file_path = f"{relative_dirpath}/{filename}"
|
|
||||||
|
|
||||||
# Only add files that are known model extensions
|
|
||||||
file_extension = filename.split('.')[-1].lower()
|
|
||||||
if file_extension in MODEL_EXTENSIONS:
|
|
||||||
fs.append(file_path)
|
|
||||||
|
|
||||||
return fs
|
|
||||||
allModels = fetch_files("./models")
|
|
||||||
|
|
||||||
class ComfyUIDeployModalList:
|
|
||||||
@classmethod
|
|
||||||
def INPUT_TYPES(s):
|
|
||||||
return {
|
|
||||||
"required": {
|
|
||||||
"model": (allModels, ),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_TYPES = (WILDCARD,)
|
|
||||||
RETURN_NAMES = ("model",)
|
|
||||||
|
|
||||||
FUNCTION = "run"
|
|
||||||
|
|
||||||
CATEGORY = "model"
|
|
||||||
|
|
||||||
def run(self, model=""):
|
|
||||||
# Split the model path by '/' and select the last item
|
|
||||||
model_name = model.split('/')[-1]
|
|
||||||
return [model_name]
|
|
||||||
|
|
||||||
|
|
||||||
NODE_CLASS_MAPPINGS = {"ComfyUIDeployModelList": ComfyUIDeployModalList}
|
|
||||||
NODE_DISPLAY_NAME_MAPPINGS = {"ComfyUIDeployModelList": "Model List (ComfyUI Deploy)"}
|
|
||||||
+354
-1084
File diff suppressed because it is too large
Load Diff
+17
-37
@@ -6,12 +6,10 @@ from PIL import Image, ImageOps
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from pydantic import BaseModel as PydanticBaseModel
|
from pydantic import BaseModel as PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class BaseModel(PydanticBaseModel):
|
class BaseModel(PydanticBaseModel):
|
||||||
class Config:
|
class Config:
|
||||||
arbitrary_types_allowed = True
|
arbitrary_types_allowed = True
|
||||||
|
|
||||||
|
|
||||||
class Status(Enum):
|
class Status(Enum):
|
||||||
NOT_STARTED = "not-started"
|
NOT_STARTED = "not-started"
|
||||||
RUNNING = "running"
|
RUNNING = "running"
|
||||||
@@ -19,7 +17,6 @@ class Status(Enum):
|
|||||||
FAILED = "failed"
|
FAILED = "failed"
|
||||||
UPLOADING = "uploading"
|
UPLOADING = "uploading"
|
||||||
|
|
||||||
|
|
||||||
class StreamingPrompt(BaseModel):
|
class StreamingPrompt(BaseModel):
|
||||||
workflow_api: Any
|
workflow_api: Any
|
||||||
auth_token: str
|
auth_token: str
|
||||||
@@ -27,52 +24,42 @@ class StreamingPrompt(BaseModel):
|
|||||||
running_prompt_ids: set[str] = set()
|
running_prompt_ids: set[str] = set()
|
||||||
status_endpoint: Optional[str]
|
status_endpoint: Optional[str]
|
||||||
file_upload_endpoint: Optional[str]
|
file_upload_endpoint: Optional[str]
|
||||||
workflow: Any
|
|
||||||
gpu_event_id: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
class SimplePrompt(BaseModel):
|
class SimplePrompt(BaseModel):
|
||||||
status_endpoint: Optional[str]
|
status_endpoint: Optional[str]
|
||||||
file_upload_endpoint: Optional[str]
|
file_upload_endpoint: Optional[str]
|
||||||
|
|
||||||
token: Optional[str]
|
|
||||||
|
|
||||||
workflow_api: dict
|
workflow_api: dict
|
||||||
status: Status = Status.NOT_STARTED
|
status: Status = Status.NOT_STARTED
|
||||||
progress: set = set()
|
progress: set = set()
|
||||||
last_updated_node: Optional[str] = None
|
last_updated_node: Optional[str] = None,
|
||||||
uploading_nodes: set = set()
|
uploading_nodes: set = set()
|
||||||
done: bool = False
|
done: bool = False
|
||||||
is_realtime: bool = False
|
is_realtime: bool = False,
|
||||||
start_time: Optional[float] = None
|
start_time: Optional[float] = None,
|
||||||
gpu_event_id: Optional[str] = None
|
|
||||||
|
|
||||||
|
|
||||||
sockets = dict()
|
sockets = dict()
|
||||||
prompt_metadata: dict[str, SimplePrompt] = {}
|
prompt_metadata: dict[str, SimplePrompt] = {}
|
||||||
streaming_prompt_metadata: dict[str, StreamingPrompt] = {}
|
streaming_prompt_metadata: dict[str, StreamingPrompt] = {}
|
||||||
|
|
||||||
|
|
||||||
class BinaryEventTypes:
|
class BinaryEventTypes:
|
||||||
PREVIEW_IMAGE = 1
|
PREVIEW_IMAGE = 1
|
||||||
UNENCODED_PREVIEW_IMAGE = 2
|
UNENCODED_PREVIEW_IMAGE = 2
|
||||||
|
|
||||||
|
|
||||||
max_output_id_length = 24
|
max_output_id_length = 24
|
||||||
|
|
||||||
|
async def send_image(image_data, sid=None, output_id:str = None):
|
||||||
async def send_image(image_data, sid=None, output_id: str = None):
|
|
||||||
max_length = max_output_id_length
|
max_length = max_output_id_length
|
||||||
output_id = output_id[:max_length]
|
output_id = output_id[:max_length]
|
||||||
padded_output_id = output_id.ljust(max_length, "\x00")
|
padded_output_id = output_id.ljust(max_length, '\x00')
|
||||||
encoded_output_id = padded_output_id.encode("ascii", "replace")
|
encoded_output_id = padded_output_id.encode('ascii', 'replace')
|
||||||
|
|
||||||
image_type = image_data[0]
|
image_type = image_data[0]
|
||||||
image = image_data[1]
|
image = image_data[1]
|
||||||
max_size = image_data[2]
|
max_size = image_data[2]
|
||||||
quality = image_data[3]
|
quality = image_data[3]
|
||||||
if max_size is not None:
|
if max_size is not None:
|
||||||
if hasattr(Image, "Resampling"):
|
if hasattr(Image, 'Resampling'):
|
||||||
resampling = Image.Resampling.BILINEAR
|
resampling = Image.Resampling.BILINEAR
|
||||||
else:
|
else:
|
||||||
resampling = Image.ANTIALIAS
|
resampling = Image.ANTIALIAS
|
||||||
@@ -96,23 +83,17 @@ async def send_image(image_data, sid=None, output_id: str = None):
|
|||||||
position_after = bytesIO.tell()
|
position_after = bytesIO.tell()
|
||||||
bytes_written = position_after - position_before
|
bytes_written = position_after - position_before
|
||||||
print(f"Bytes written: {bytes_written}")
|
print(f"Bytes written: {bytes_written}")
|
||||||
|
|
||||||
image.save(bytesIO, format=image_type, quality=quality, compress_level=1)
|
image.save(bytesIO, format=image_type, quality=quality, compress_level=1)
|
||||||
preview_bytes = bytesIO.getvalue()
|
preview_bytes = bytesIO.getvalue()
|
||||||
await send_bytes(BinaryEventTypes.PREVIEW_IMAGE, preview_bytes, sid=sid)
|
await send_bytes(BinaryEventTypes.PREVIEW_IMAGE, preview_bytes, sid=sid)
|
||||||
|
|
||||||
|
|
||||||
async def send_socket_catch_exception(function, message):
|
async def send_socket_catch_exception(function, message):
|
||||||
try:
|
try:
|
||||||
await function(message)
|
await function(message)
|
||||||
except (
|
except (aiohttp.ClientError, aiohttp.ClientPayloadError, ConnectionResetError) as err:
|
||||||
aiohttp.ClientError,
|
|
||||||
aiohttp.ClientPayloadError,
|
|
||||||
ConnectionResetError,
|
|
||||||
) as err:
|
|
||||||
print("send error:", err)
|
print("send error:", err)
|
||||||
|
|
||||||
|
|
||||||
def encode_bytes(event, data):
|
def encode_bytes(event, data):
|
||||||
if not isinstance(event, int):
|
if not isinstance(event, int):
|
||||||
raise RuntimeError(f"Binary event types must be integers, got {event}")
|
raise RuntimeError(f"Binary event types must be integers, got {event}")
|
||||||
@@ -122,10 +103,9 @@ def encode_bytes(event, data):
|
|||||||
message.extend(data)
|
message.extend(data)
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
async def send_bytes(event, data, sid=None):
|
async def send_bytes(event, data, sid=None):
|
||||||
message = encode_bytes(event, data)
|
message = encode_bytes(event, data)
|
||||||
|
|
||||||
print("sending image to ", event, sid)
|
print("sending image to ", event, sid)
|
||||||
|
|
||||||
if sid is None:
|
if sid is None:
|
||||||
@@ -133,4 +113,4 @@ async def send_bytes(event, data, sid=None):
|
|||||||
for ws in _sockets:
|
for ws in _sockets:
|
||||||
await send_socket_catch_exception(ws.send_bytes, message)
|
await send_socket_catch_exception(ws.send_bytes, message)
|
||||||
elif sid in sockets:
|
elif sid in sockets:
|
||||||
await send_socket_catch_exception(sockets[sid].send_bytes, message)
|
await send_socket_catch_exception(sockets[sid].send_bytes, message)
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "comfyui-deploy"
|
name = "comfyui-deploy"
|
||||||
description = "Open source comfyui deployment platform, a vercel for generative workflow infra."
|
description = "Open source comfyui deployment platform, a vercel for generative workflow infra."
|
||||||
version = "1.1.0"
|
version = "1.0.0"
|
||||||
license = "LICENSE"
|
license = "LICENSE"
|
||||||
dependencies = ["aiofiles", "pydantic", "opencv-python", "imageio-ffmpeg"]
|
dependencies = ["aiofiles", "pydantic", "opencv-python", "imageio-ffmpeg"]
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,4 @@ aiofiles
|
|||||||
pydantic
|
pydantic
|
||||||
opencv-python
|
opencv-python
|
||||||
imageio-ffmpeg
|
imageio-ffmpeg
|
||||||
brotli
|
|
||||||
tabulate
|
|
||||||
# logfire
|
# logfire
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/** @typedef {import('../../../web/scripts/api.js').api} API*/
|
||||||
|
import { api as _api } from '../../scripts/api.js';
|
||||||
|
/** @type {API} */
|
||||||
|
export const api = _api;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/** @typedef {import('../../../web/scripts/app.js').ComfyApp} ComfyApp*/
|
||||||
|
import { app as _app } from '../../scripts/app.js';
|
||||||
|
/** @type {ComfyApp} */
|
||||||
|
export const app = _app;
|
||||||
+92
-792
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
|||||||
|
// /** @typedef {import('../../../web/scripts/api.js').api} API*/
|
||||||
|
// import { api as _api } from "../../scripts/api.js";
|
||||||
|
// /** @type {API} */
|
||||||
|
// export const api = _api;
|
||||||
|
|
||||||
|
/** @typedef {typeof import('../../../web/scripts/widgets.js').ComfyWidgets} Widgets*/
|
||||||
|
import { ComfyWidgets as _ComfyWidgets } from "../../scripts/widgets.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Widgets}
|
||||||
|
*/
|
||||||
|
export const ComfyWidgets = _ComfyWidgets;
|
||||||
|
|
||||||
|
// import { LGraphNode as _LGraphNode } from "../../types/litegraph.js";
|
||||||
|
|
||||||
|
/** @typedef {typeof import('../../../web/types/litegraph.js').LGraphNode} LGraphNode*/
|
||||||
|
/** @type {LGraphNode}*/
|
||||||
|
export const LGraphNode = LiteGraph.LGraphNode;
|
||||||
@@ -6,5 +6,4 @@ export const customInputNodes: Record<string, string> = {
|
|||||||
ComfyUIDeployExternalNumberInt: "integer",
|
ComfyUIDeployExternalNumberInt: "integer",
|
||||||
ComfyUIDeployExternalLora: "string - (public lora download url)",
|
ComfyUIDeployExternalLora: "string - (public lora download url)",
|
||||||
ComfyUIDeployExternalCheckpoint: "string - (public checkpoints download url)",
|
ComfyUIDeployExternalCheckpoint: "string - (public checkpoints download url)",
|
||||||
ComfyUIDeployExternalFaceModel: "string - (public face model download url)",
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -51,9 +51,7 @@ const createRunRoute = createRoute({
|
|||||||
export const registerCreateRunRoute = (app: App) => {
|
export const registerCreateRunRoute = (app: App) => {
|
||||||
app.openapi(createRunRoute, async (c) => {
|
app.openapi(createRunRoute, async (c) => {
|
||||||
const data = c.req.valid("json");
|
const data = c.req.valid("json");
|
||||||
const proto = c.req.headers.get('x-forwarded-proto') || "http";
|
const origin = new URL(c.req.url).origin;
|
||||||
const host = c.req.headers.get('x-forwarded-host') || c.req.headers.get('host');
|
|
||||||
const origin = `${proto}://${host}` || new URL(c.req.url).origin;
|
|
||||||
const apiKeyTokenData = c.get("apiKeyTokenData")!;
|
const apiKeyTokenData = c.get("apiKeyTokenData")!;
|
||||||
|
|
||||||
const { deployment_id, inputs } = data;
|
const { deployment_id, inputs } = data;
|
||||||
|
|||||||
Reference in New Issue
Block a user