bizyengine 0.4.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bizyengine/__init__.py +35 -0
- bizyengine/bizy_server/__init__.py +7 -0
- bizyengine/bizy_server/api_client.py +763 -0
- bizyengine/bizy_server/errno.py +122 -0
- bizyengine/bizy_server/error_handler.py +3 -0
- bizyengine/bizy_server/execution.py +55 -0
- bizyengine/bizy_server/resp.py +24 -0
- bizyengine/bizy_server/server.py +898 -0
- bizyengine/bizy_server/utils.py +93 -0
- bizyengine/bizyair_extras/__init__.py +24 -0
- bizyengine/bizyair_extras/nodes_advanced_refluxcontrol.py +62 -0
- bizyengine/bizyair_extras/nodes_cogview4.py +31 -0
- bizyengine/bizyair_extras/nodes_comfyui_detail_daemon.py +180 -0
- bizyengine/bizyair_extras/nodes_comfyui_instantid.py +164 -0
- bizyengine/bizyair_extras/nodes_comfyui_layerstyle_advance.py +141 -0
- bizyengine/bizyair_extras/nodes_comfyui_pulid_flux.py +88 -0
- bizyengine/bizyair_extras/nodes_controlnet.py +50 -0
- bizyengine/bizyair_extras/nodes_custom_sampler.py +130 -0
- bizyengine/bizyair_extras/nodes_dataset.py +99 -0
- bizyengine/bizyair_extras/nodes_differential_diffusion.py +16 -0
- bizyengine/bizyair_extras/nodes_flux.py +69 -0
- bizyengine/bizyair_extras/nodes_image_utils.py +93 -0
- bizyengine/bizyair_extras/nodes_ip2p.py +20 -0
- bizyengine/bizyair_extras/nodes_ipadapter_plus/__init__.py +1 -0
- bizyengine/bizyair_extras/nodes_ipadapter_plus/nodes_ipadapter_plus.py +1598 -0
- bizyengine/bizyair_extras/nodes_janus_pro.py +81 -0
- bizyengine/bizyair_extras/nodes_kolors_mz/__init__.py +86 -0
- bizyengine/bizyair_extras/nodes_model_advanced.py +62 -0
- bizyengine/bizyair_extras/nodes_sd3.py +52 -0
- bizyengine/bizyair_extras/nodes_segment_anything.py +256 -0
- bizyengine/bizyair_extras/nodes_segment_anything_utils.py +134 -0
- bizyengine/bizyair_extras/nodes_testing_utils.py +139 -0
- bizyengine/bizyair_extras/nodes_trellis.py +199 -0
- bizyengine/bizyair_extras/nodes_ultimatesdupscale.py +137 -0
- bizyengine/bizyair_extras/nodes_upscale_model.py +32 -0
- bizyengine/bizyair_extras/nodes_wan_video.py +49 -0
- bizyengine/bizyair_extras/oauth_callback/main.py +118 -0
- bizyengine/core/__init__.py +8 -0
- bizyengine/core/commands/__init__.py +1 -0
- bizyengine/core/commands/base.py +27 -0
- bizyengine/core/commands/invoker.py +4 -0
- bizyengine/core/commands/processors/model_hosting_processor.py +0 -0
- bizyengine/core/commands/processors/prompt_processor.py +123 -0
- bizyengine/core/commands/servers/model_server.py +0 -0
- bizyengine/core/commands/servers/prompt_server.py +234 -0
- bizyengine/core/common/__init__.py +8 -0
- bizyengine/core/common/caching.py +198 -0
- bizyengine/core/common/client.py +262 -0
- bizyengine/core/common/env_var.py +101 -0
- bizyengine/core/common/utils.py +93 -0
- bizyengine/core/configs/conf.py +112 -0
- bizyengine/core/configs/models.json +101 -0
- bizyengine/core/configs/models.yaml +329 -0
- bizyengine/core/data_types.py +20 -0
- bizyengine/core/image_utils.py +288 -0
- bizyengine/core/nodes_base.py +159 -0
- bizyengine/core/nodes_io.py +97 -0
- bizyengine/core/path_utils/__init__.py +9 -0
- bizyengine/core/path_utils/path_manager.py +276 -0
- bizyengine/core/path_utils/utils.py +34 -0
- bizyengine/misc/__init__.py +0 -0
- bizyengine/misc/auth.py +83 -0
- bizyengine/misc/llm.py +431 -0
- bizyengine/misc/mzkolors.py +93 -0
- bizyengine/misc/nodes.py +1208 -0
- bizyengine/misc/nodes_controlnet_aux.py +491 -0
- bizyengine/misc/nodes_controlnet_union_sdxl.py +171 -0
- bizyengine/misc/route_sam.py +60 -0
- bizyengine/misc/segment_anything.py +276 -0
- bizyengine/misc/supernode.py +182 -0
- bizyengine/misc/utils.py +218 -0
- bizyengine/version.txt +1 -0
- bizyengine-0.4.2.dist-info/METADATA +12 -0
- bizyengine-0.4.2.dist-info/RECORD +76 -0
- bizyengine-0.4.2.dist-info/WHEEL +5 -0
- bizyengine-0.4.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pip install numpy scikit-image pillow
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import random
|
|
8
|
+
|
|
9
|
+
import folder_paths
|
|
10
|
+
import numpy as np
|
|
11
|
+
from bizyengine.core import NODE_CLASS_MAPPINGS
|
|
12
|
+
from bizyengine.core.image_utils import decode_data, encode_data
|
|
13
|
+
from PIL import Image
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ImagesTest:
|
|
17
|
+
# https://docs.comfy.org/essentials/custom_node_images_and_masks#images
|
|
18
|
+
def __init__(self):
|
|
19
|
+
self.output_dir = folder_paths.get_temp_directory()
|
|
20
|
+
self.type = "temp"
|
|
21
|
+
self.prefix_append = "_temp_" + "".join(
|
|
22
|
+
random.choice("abcdefghijklmnopqrstupvxyz") for x in range(5)
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def INPUT_TYPES(s):
|
|
27
|
+
return {
|
|
28
|
+
"required": {
|
|
29
|
+
"images1": ("IMAGE",),
|
|
30
|
+
"images2": ("IMAGE",),
|
|
31
|
+
"ssim_threshold": ("STRING", {"default": "0.9"}),
|
|
32
|
+
"raise_if_diff": (["enable", "disable"],),
|
|
33
|
+
"image_id": ("STRING", {"default": "ComfyUI"}),
|
|
34
|
+
},
|
|
35
|
+
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
RETURN_TYPES = ()
|
|
39
|
+
FUNCTION = "save_images"
|
|
40
|
+
|
|
41
|
+
OUTPUT_NODE = True
|
|
42
|
+
|
|
43
|
+
CATEGORY = "images_test"
|
|
44
|
+
|
|
45
|
+
def save_images(
|
|
46
|
+
self,
|
|
47
|
+
images1,
|
|
48
|
+
images2,
|
|
49
|
+
ssim_threshold: float,
|
|
50
|
+
raise_if_diff: str,
|
|
51
|
+
image_id="ComfyUI",
|
|
52
|
+
prompt=None,
|
|
53
|
+
extra_pnginfo=None,
|
|
54
|
+
):
|
|
55
|
+
from skimage.metrics import structural_similarity as ssim
|
|
56
|
+
|
|
57
|
+
assert len(images1) == len(images2)
|
|
58
|
+
filename_prefix = image_id[:]
|
|
59
|
+
filename_prefix += self.prefix_append
|
|
60
|
+
(
|
|
61
|
+
full_output_folder,
|
|
62
|
+
filename,
|
|
63
|
+
counter,
|
|
64
|
+
subfolder,
|
|
65
|
+
filename_prefix,
|
|
66
|
+
) = folder_paths.get_save_image_path(
|
|
67
|
+
filename_prefix,
|
|
68
|
+
self.output_dir,
|
|
69
|
+
images1[0].shape[1],
|
|
70
|
+
images1[0].shape[0],
|
|
71
|
+
)
|
|
72
|
+
results = list()
|
|
73
|
+
for image1, image2 in zip(images1, images2):
|
|
74
|
+
|
|
75
|
+
# image diff
|
|
76
|
+
image = image1.cpu() - image2.cpu()
|
|
77
|
+
|
|
78
|
+
i = 255.0 * image.cpu().numpy()
|
|
79
|
+
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
|
|
80
|
+
metadata = None
|
|
81
|
+
file = f"{filename}_{counter:05}_.png"
|
|
82
|
+
img.save(
|
|
83
|
+
os.path.join(full_output_folder, file),
|
|
84
|
+
pnginfo=metadata,
|
|
85
|
+
compress_level=4,
|
|
86
|
+
)
|
|
87
|
+
results.append(
|
|
88
|
+
{"filename": file, "subfolder": subfolder, "type": self.type}
|
|
89
|
+
)
|
|
90
|
+
counter += 1
|
|
91
|
+
|
|
92
|
+
max_diff = image.abs().max().item()
|
|
93
|
+
|
|
94
|
+
img1 = self.image_to_numpy(image1)
|
|
95
|
+
img2 = self.image_to_numpy(image2)
|
|
96
|
+
ssim = ssim(img1, img2, channel_axis=2)
|
|
97
|
+
|
|
98
|
+
print(
|
|
99
|
+
"\033[91m"
|
|
100
|
+
f"[ShowImageDiff {image_id}] Max value of diff is {max_diff}, image simularity is {ssim:.6f}"
|
|
101
|
+
+ "\033[0m"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
if raise_if_diff == "enable":
|
|
105
|
+
assert ssim > float(
|
|
106
|
+
ssim_threshold
|
|
107
|
+
), f"Image diff is too large, ssim is {ssim}, "
|
|
108
|
+
|
|
109
|
+
return {"ui": {"images": results}}
|
|
110
|
+
|
|
111
|
+
def image_to_numpy(self, image):
|
|
112
|
+
i = 255.0 * image.cpu().numpy()
|
|
113
|
+
img = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
|
|
114
|
+
return np.array(img)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class ImageEncodeDecodeTest:
|
|
118
|
+
@classmethod
|
|
119
|
+
def INPUT_TYPES(s):
|
|
120
|
+
return {
|
|
121
|
+
"required": {"image": ("IMAGE",)},
|
|
122
|
+
"optional": {
|
|
123
|
+
"lossless": (
|
|
124
|
+
"BOOLEAN",
|
|
125
|
+
{"default": False, "label_on": "yes", "label_off": "no"},
|
|
126
|
+
),
|
|
127
|
+
},
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
CATEGORY = "images_test"
|
|
131
|
+
FUNCTION = "test"
|
|
132
|
+
RETURN_TYPES = ("IMAGE",)
|
|
133
|
+
|
|
134
|
+
def test(self, image, lossless=False):
|
|
135
|
+
return (decode_data(encode_data(image, lossless=lossless)),)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
NODE_CLASS_MAPPINGS["Tools_ImagesTest"] = ImagesTest
|
|
139
|
+
NODE_CLASS_MAPPINGS["Tools_ImageEncodeDecodeTest"] = ImageEncodeDecodeTest
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import uuid
|
|
3
|
+
|
|
4
|
+
import folder_paths
|
|
5
|
+
import requests
|
|
6
|
+
import torch
|
|
7
|
+
from bizyengine.core import BizyAirBaseNode
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BizyAir_IF_TrellisCheckpointLoader(BizyAirBaseNode):
|
|
11
|
+
"""
|
|
12
|
+
Node to manage the loading of the TRELLIS model.
|
|
13
|
+
Follows ComfyUI conventions for model management.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def INPUT_TYPES(cls):
|
|
18
|
+
"""Define input types with device-specific options."""
|
|
19
|
+
device_options = ["cuda"]
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
"required": {
|
|
23
|
+
"model_name": (["TRELLIS-image-large"],),
|
|
24
|
+
"dinov2_model": (
|
|
25
|
+
["dinov2_vitl14_reg", "dinov2_vitg14_reg"],
|
|
26
|
+
{
|
|
27
|
+
"default": "dinov2_vitl14_reg",
|
|
28
|
+
"tooltip": "Select the Dinov2 model to use for the image to 3D conversion. Smaller models work but better results with larger models.",
|
|
29
|
+
},
|
|
30
|
+
),
|
|
31
|
+
"use_fp16": ("BOOLEAN", {"default": True}),
|
|
32
|
+
"attn_backend": (
|
|
33
|
+
["sage", "xformers", "flash_attn", "sdpa", "naive"],
|
|
34
|
+
{
|
|
35
|
+
"default": "sage",
|
|
36
|
+
"tooltip": "Select the attention backend to use for the image to 3D conversion. Sage is experimental but faster",
|
|
37
|
+
},
|
|
38
|
+
),
|
|
39
|
+
"smooth_k": (
|
|
40
|
+
"BOOLEAN",
|
|
41
|
+
{
|
|
42
|
+
"default": True,
|
|
43
|
+
"tooltip": "Smooth k for sage attention. This is a hyperparameter that controls the smoothness of the attention distribution. It is a boolean value that determines whether to use smooth k or not. Smooth k is a hyperparameter that controls the smoothness of the attention distribution. It is a boolean value that determines whether to use smooth k or not.",
|
|
44
|
+
},
|
|
45
|
+
),
|
|
46
|
+
"spconv_algo": (
|
|
47
|
+
["implicit_gemm", "native"],
|
|
48
|
+
{
|
|
49
|
+
"default": "implicit_gemm",
|
|
50
|
+
"tooltip": "Select the spconv algorithm to use for the image to 3D conversion. Implicit gemm is the best but slower. Native is the fastest but less accurate.",
|
|
51
|
+
},
|
|
52
|
+
),
|
|
53
|
+
"main_device": (device_options, {"default": device_options[0]}),
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
RETURN_TYPES = ("TRELLIS_MODEL",)
|
|
58
|
+
RETURN_NAMES = ("model",)
|
|
59
|
+
CATEGORY = "☁️BizyAir/Trellis"
|
|
60
|
+
NODE_DISPLAY_NAME = "☁️BizyAir Load Trellis"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class BizyAir_IF_TrellisImageTo3D(BizyAirBaseNode):
|
|
64
|
+
@classmethod
|
|
65
|
+
def INPUT_TYPES(s):
|
|
66
|
+
return {
|
|
67
|
+
"required": {
|
|
68
|
+
"model": ("TRELLIS_MODEL",),
|
|
69
|
+
"mode": (
|
|
70
|
+
["single", "multi"],
|
|
71
|
+
{
|
|
72
|
+
"default": "single",
|
|
73
|
+
"tooltip": "Mode. single is a single image. with multi you can provide multiple reference angles for the 3D model",
|
|
74
|
+
},
|
|
75
|
+
),
|
|
76
|
+
"images": ("IMAGE", {"list": True}),
|
|
77
|
+
"seed": ("INT", {"default": 0, "min": 0, "max": 0x7FFFFFFF}),
|
|
78
|
+
"ss_guidance_strength": (
|
|
79
|
+
"FLOAT",
|
|
80
|
+
{"default": 7.5, "min": 0.0, "max": 12.0, "step": 0.1},
|
|
81
|
+
),
|
|
82
|
+
"ss_sampling_steps": ("INT", {"default": 12, "min": 1, "max": 50}),
|
|
83
|
+
"slat_guidance_strength": (
|
|
84
|
+
"FLOAT",
|
|
85
|
+
{"default": 3.0, "min": 0.0, "max": 12.0, "step": 0.1},
|
|
86
|
+
),
|
|
87
|
+
"slat_sampling_steps": ("INT", {"default": 12, "min": 1, "max": 50}),
|
|
88
|
+
"multimode": (
|
|
89
|
+
["stochastic", "multidiffusion"],
|
|
90
|
+
{"default": "stochastic"},
|
|
91
|
+
),
|
|
92
|
+
},
|
|
93
|
+
"optional": {
|
|
94
|
+
"masks": ("MASK", {"list": True}),
|
|
95
|
+
},
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
RETURN_TYPES = (
|
|
99
|
+
"trellis_gaussian",
|
|
100
|
+
"trellis_mesh",
|
|
101
|
+
)
|
|
102
|
+
CATEGORY = "☁️BizyAir/Trellis"
|
|
103
|
+
NODE_DISPLAY_NAME = "☁️BizyAir Trellis Predict"
|
|
104
|
+
OUTPUT_NODE = True
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class BizyAir_Trans3D2GlbFile(BizyAirBaseNode):
|
|
108
|
+
@classmethod
|
|
109
|
+
def INPUT_TYPES(cls):
|
|
110
|
+
return {
|
|
111
|
+
"required": {
|
|
112
|
+
"trellis_gaussian": ("trellis_gaussian", {"forceInput": True}),
|
|
113
|
+
"trellis_mesh": ("trellis_mesh", {"forceInput": True}),
|
|
114
|
+
"mesh_simplify": (
|
|
115
|
+
"FLOAT",
|
|
116
|
+
{
|
|
117
|
+
"default": 0.95,
|
|
118
|
+
"min": 0.9,
|
|
119
|
+
"max": 1.0,
|
|
120
|
+
"step": 0.01,
|
|
121
|
+
"tooltip": "Simplify the mesh. the lower the value more polygons the mesh will have",
|
|
122
|
+
},
|
|
123
|
+
),
|
|
124
|
+
"texture_size": (
|
|
125
|
+
"INT",
|
|
126
|
+
{
|
|
127
|
+
"default": 1024,
|
|
128
|
+
"min": 512,
|
|
129
|
+
"max": 2048,
|
|
130
|
+
"step": 512,
|
|
131
|
+
"tooltip": "Texture size. the higher the value the more detailed the texture will be",
|
|
132
|
+
},
|
|
133
|
+
),
|
|
134
|
+
"texture_mode": (
|
|
135
|
+
["blank", "fast", "opt"],
|
|
136
|
+
{
|
|
137
|
+
"default": "fast",
|
|
138
|
+
"tooltip": "Texture mode. blank is no texture. fast is a fast texture. opt is a high quality texture",
|
|
139
|
+
},
|
|
140
|
+
),
|
|
141
|
+
"save_glb": (
|
|
142
|
+
"BOOLEAN",
|
|
143
|
+
{
|
|
144
|
+
"default": True,
|
|
145
|
+
"tooltip": "Save the GLB file this is the 3D model",
|
|
146
|
+
},
|
|
147
|
+
),
|
|
148
|
+
"save_texture": (
|
|
149
|
+
"BOOLEAN",
|
|
150
|
+
{"default": False, "tooltip": "Save the texture file"},
|
|
151
|
+
),
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
CATEGORY = "☁️BizyAir/Trellis"
|
|
156
|
+
NODE_DISPLAY_NAME = "☁️BizyAir Generate Glb With Trellis"
|
|
157
|
+
RETURN_TYPES = ("STRING", "IMAGE")
|
|
158
|
+
RETURN_NAMES = ("url", "texture_image")
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class BizyAirDownloadFile(BizyAirBaseNode):
|
|
162
|
+
NODE_DISPLAY_NAME = "☁️BizyAir Download File"
|
|
163
|
+
|
|
164
|
+
@classmethod
|
|
165
|
+
def INPUT_TYPES(cls):
|
|
166
|
+
return {
|
|
167
|
+
"required": {
|
|
168
|
+
"url": ("STRING", {"default": ""}),
|
|
169
|
+
"file_name": ("STRING", {"default": "default"}),
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
CATEGORY = "☁️BizyAir/Trellis"
|
|
174
|
+
FUNCTION = "main"
|
|
175
|
+
|
|
176
|
+
RETURN_TYPES = ("STRING",)
|
|
177
|
+
RETURN_NAMES = ("path",)
|
|
178
|
+
OUTPUT_NODE = True
|
|
179
|
+
OUTPUT_IS_LIST = (False,)
|
|
180
|
+
|
|
181
|
+
def main(self, url, file_name):
|
|
182
|
+
assert url is not None
|
|
183
|
+
file_name = file_name + ".glb"
|
|
184
|
+
out_dir = os.path.join(folder_paths.get_output_directory(), "trellis_output")
|
|
185
|
+
os.makedirs(out_dir, exist_ok=True)
|
|
186
|
+
local_path = os.path.join(out_dir, file_name)
|
|
187
|
+
output = os.path.join("trellis_output", file_name)
|
|
188
|
+
response = requests.get(url)
|
|
189
|
+
if response.status_code == 200:
|
|
190
|
+
with open(local_path, "wb") as file:
|
|
191
|
+
file.write(response.content)
|
|
192
|
+
print("download finished in {}".format(local_path))
|
|
193
|
+
else:
|
|
194
|
+
print(f"download error: {response.status_code}")
|
|
195
|
+
return (output,)
|
|
196
|
+
|
|
197
|
+
@classmethod
|
|
198
|
+
def IS_CHANGED(self, url, file_name, *args, **kwargs):
|
|
199
|
+
return uuid.uuid4().hex
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
import comfy
|
|
4
|
+
from bizyengine.core import BizyAirBaseNode, BizyAirNodeIO
|
|
5
|
+
from bizyengine.core.data_types import CONDITIONING, MODEL, UPSCALE_MODEL, VAE
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class USDUMode(Enum):
|
|
9
|
+
LINEAR = 0
|
|
10
|
+
CHESS = 1
|
|
11
|
+
NONE = 2
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class USDUSFMode(Enum):
|
|
15
|
+
NONE = 0
|
|
16
|
+
BAND_PASS = 1
|
|
17
|
+
HALF_TILE = 2
|
|
18
|
+
HALF_TILE_PLUS_INTERSECTIONS = 3
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
MAX_RESOLUTION = 8192
|
|
22
|
+
# The modes available for Ultimate SD Upscale
|
|
23
|
+
MODES = {
|
|
24
|
+
"Linear": USDUMode.LINEAR,
|
|
25
|
+
"Chess": USDUMode.CHESS,
|
|
26
|
+
"None": USDUMode.NONE,
|
|
27
|
+
}
|
|
28
|
+
# The seam fix modes
|
|
29
|
+
SEAM_FIX_MODES = {
|
|
30
|
+
"None": USDUSFMode.NONE,
|
|
31
|
+
"Band Pass": USDUSFMode.BAND_PASS,
|
|
32
|
+
"Half Tile": USDUSFMode.HALF_TILE,
|
|
33
|
+
"Half Tile + Intersections": USDUSFMode.HALF_TILE_PLUS_INTERSECTIONS,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def USDU_base_inputs():
|
|
38
|
+
required = [
|
|
39
|
+
("image", ("IMAGE",)),
|
|
40
|
+
# Sampling Params
|
|
41
|
+
("model", (MODEL,)),
|
|
42
|
+
("positive", (CONDITIONING,)),
|
|
43
|
+
("negative", (CONDITIONING,)),
|
|
44
|
+
("vae", (VAE,)),
|
|
45
|
+
("upscale_by", ("FLOAT", {"default": 2, "min": 0.05, "max": 4, "step": 0.05})),
|
|
46
|
+
("seed", ("INT", {"default": 0, "min": 0, "max": 0xFFFFFFFFFFFFFFFF})),
|
|
47
|
+
("steps", ("INT", {"default": 20, "min": 1, "max": 10000, "step": 1})),
|
|
48
|
+
("cfg", ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0})),
|
|
49
|
+
("sampler_name", (comfy.samplers.KSampler.SAMPLERS,)),
|
|
50
|
+
("scheduler", (comfy.samplers.KSampler.SCHEDULERS,)),
|
|
51
|
+
("denoise", ("FLOAT", {"default": 0.2, "min": 0.0, "max": 1.0, "step": 0.01})),
|
|
52
|
+
# Upscale Params
|
|
53
|
+
("upscale_model", (UPSCALE_MODEL,)),
|
|
54
|
+
("mode_type", (list(MODES.keys()),)),
|
|
55
|
+
(
|
|
56
|
+
"tile_width",
|
|
57
|
+
("INT", {"default": 512, "min": 64, "max": MAX_RESOLUTION, "step": 8}),
|
|
58
|
+
),
|
|
59
|
+
(
|
|
60
|
+
"tile_height",
|
|
61
|
+
("INT", {"default": 512, "min": 64, "max": MAX_RESOLUTION, "step": 8}),
|
|
62
|
+
),
|
|
63
|
+
("mask_blur", ("INT", {"default": 8, "min": 0, "max": 64, "step": 1})),
|
|
64
|
+
(
|
|
65
|
+
"tile_padding",
|
|
66
|
+
("INT", {"default": 32, "min": 0, "max": MAX_RESOLUTION, "step": 8}),
|
|
67
|
+
),
|
|
68
|
+
# Seam fix params
|
|
69
|
+
("seam_fix_mode", (list(SEAM_FIX_MODES.keys()),)),
|
|
70
|
+
(
|
|
71
|
+
"seam_fix_denoise",
|
|
72
|
+
("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
|
73
|
+
),
|
|
74
|
+
(
|
|
75
|
+
"seam_fix_width",
|
|
76
|
+
("INT", {"default": 64, "min": 0, "max": MAX_RESOLUTION, "step": 8}),
|
|
77
|
+
),
|
|
78
|
+
("seam_fix_mask_blur", ("INT", {"default": 8, "min": 0, "max": 64, "step": 1})),
|
|
79
|
+
(
|
|
80
|
+
"seam_fix_padding",
|
|
81
|
+
("INT", {"default": 16, "min": 0, "max": MAX_RESOLUTION, "step": 8}),
|
|
82
|
+
),
|
|
83
|
+
# Misc
|
|
84
|
+
("force_uniform_tiles", ("BOOLEAN", {"default": True})),
|
|
85
|
+
("tiled_decode", ("BOOLEAN", {"default": False})),
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
optional = []
|
|
89
|
+
|
|
90
|
+
return required, optional
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def prepare_inputs(required: list, optional: list = None):
|
|
94
|
+
inputs = {}
|
|
95
|
+
if required:
|
|
96
|
+
inputs["required"] = {}
|
|
97
|
+
for name, type in required:
|
|
98
|
+
inputs["required"][name] = type
|
|
99
|
+
if optional:
|
|
100
|
+
inputs["optional"] = {}
|
|
101
|
+
for name, type in optional:
|
|
102
|
+
inputs["optional"][name] = type
|
|
103
|
+
return inputs
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def remove_input(inputs: list, input_name: str):
|
|
107
|
+
for i, (n, _) in enumerate(inputs):
|
|
108
|
+
if n == input_name:
|
|
109
|
+
del inputs[i]
|
|
110
|
+
break
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def rename_input(inputs: list, old_name: str, new_name: str):
|
|
114
|
+
for i, (n, t) in enumerate(inputs):
|
|
115
|
+
if n == old_name:
|
|
116
|
+
inputs[i] = (new_name, t)
|
|
117
|
+
break
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class UltimateSDUpscale(BizyAirBaseNode):
|
|
121
|
+
@classmethod
|
|
122
|
+
def INPUT_TYPES(s):
|
|
123
|
+
required, optional = USDU_base_inputs()
|
|
124
|
+
return prepare_inputs(required, optional)
|
|
125
|
+
|
|
126
|
+
RETURN_TYPES = ("IMAGE",)
|
|
127
|
+
FUNCTION = "upscale"
|
|
128
|
+
CATEGORY = "image/upscaling"
|
|
129
|
+
|
|
130
|
+
def upscale(self, **kwargs):
|
|
131
|
+
model: BizyAirNodeIO = kwargs.get("model")
|
|
132
|
+
new_model = model.copy(self.assigned_id)
|
|
133
|
+
new_model.add_node_data(
|
|
134
|
+
class_type="UltimateSDUpscale",
|
|
135
|
+
inputs=kwargs,
|
|
136
|
+
)
|
|
137
|
+
return new_model.send_request()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import bizyengine.core.path_utils as folder_paths
|
|
2
|
+
from bizyengine.core import BizyAirBaseNode, BizyAirNodeIO
|
|
3
|
+
from bizyengine.core.data_types import UPSCALE_MODEL
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class UpscaleModelLoader(BizyAirBaseNode):
|
|
7
|
+
@classmethod
|
|
8
|
+
def INPUT_TYPES(s):
|
|
9
|
+
return {
|
|
10
|
+
"required": {
|
|
11
|
+
"model_name": (folder_paths.get_filename_list("upscale_models"),),
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
RETURN_TYPES = (UPSCALE_MODEL,)
|
|
16
|
+
# FUNCTION = "load_model"
|
|
17
|
+
CATEGORY = "loaders"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ImageUpscaleWithModel(BizyAirBaseNode):
|
|
21
|
+
@classmethod
|
|
22
|
+
def INPUT_TYPES(s):
|
|
23
|
+
return {
|
|
24
|
+
"required": {
|
|
25
|
+
"upscale_model": (UPSCALE_MODEL,),
|
|
26
|
+
"image": ("IMAGE",),
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
RETURN_TYPES = ("IMAGE",)
|
|
31
|
+
# FUNCTION = "upscale"
|
|
32
|
+
CATEGORY = "image/upscaling"
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from bizyengine.core import BizyAirBaseNode
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Wan_Model_Loader(BizyAirBaseNode):
|
|
5
|
+
@classmethod
|
|
6
|
+
def INPUT_TYPES(cls):
|
|
7
|
+
return {
|
|
8
|
+
"required": {
|
|
9
|
+
"ckpt_name": (("Wan2.1-T2V-1.3B",),),
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
RETURN_TYPES = ("WAN_MODEL",)
|
|
14
|
+
RETURN_NAMES = ("model",)
|
|
15
|
+
CATEGORY = "WanT2V"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Wan_T2V_Pipeline(BizyAirBaseNode):
|
|
19
|
+
@classmethod
|
|
20
|
+
def INPUT_TYPES(cls):
|
|
21
|
+
return {
|
|
22
|
+
"required": {
|
|
23
|
+
"model": ("WAN_MODEL",),
|
|
24
|
+
"prompt": (
|
|
25
|
+
"STRING",
|
|
26
|
+
{
|
|
27
|
+
"multiline": True,
|
|
28
|
+
"default": "Two anthropomorphic cats in comfy boxing gear and bright gloves fight intensely on a spotlighted stage.",
|
|
29
|
+
},
|
|
30
|
+
),
|
|
31
|
+
"resolution": (
|
|
32
|
+
["480*832", "832*480", "624*624", "704*544", "544*704"],
|
|
33
|
+
{"default": "480*832"},
|
|
34
|
+
),
|
|
35
|
+
"sampling_steps": ("INT", {"default": 50, "min": 1, "max": 50}),
|
|
36
|
+
"guidance_scale": ("FLOAT", {"default": 6.0, "min": 0, "max": 20}),
|
|
37
|
+
"shift_scale": ("FLOAT", {"default": 8.0, "min": 0, "max": 20}),
|
|
38
|
+
"seed": ("INT", {"default": -1, "min": -1, "max": 0xFFFFFFFFFFFFFFFF}),
|
|
39
|
+
"negative_prompt": (
|
|
40
|
+
"STRING",
|
|
41
|
+
{"multiline": True, "default": "Low quality, blurry"},
|
|
42
|
+
),
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
RETURN_TYPES = ("STRING",)
|
|
47
|
+
RETURN_NAMES = ("video_url",)
|
|
48
|
+
CATEGORY = "WanT2V"
|
|
49
|
+
# FUNCTION = "generate_video"
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import asyncio
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
import aiohttp
|
|
6
|
+
from aiohttp import web
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Set up command-line argument parsing
|
|
10
|
+
def parse_arguments():
|
|
11
|
+
parser = argparse.ArgumentParser(description="OAuth Callback Server")
|
|
12
|
+
parser.add_argument(
|
|
13
|
+
"--account_endpoint",
|
|
14
|
+
type=str,
|
|
15
|
+
default="https://account.siliconflow.cn",
|
|
16
|
+
help="The account endpoint URL",
|
|
17
|
+
)
|
|
18
|
+
parser.add_argument(
|
|
19
|
+
"--cloud_endpoint",
|
|
20
|
+
type=str,
|
|
21
|
+
default="https://cloud.siliconflow.cn",
|
|
22
|
+
help="The cloud endpoint URL",
|
|
23
|
+
)
|
|
24
|
+
parser.add_argument(
|
|
25
|
+
"--client_id",
|
|
26
|
+
type=str,
|
|
27
|
+
default="SFaJLLq0y6CAMoyDm81aMu",
|
|
28
|
+
help="The client ID for OAuth",
|
|
29
|
+
)
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"--secret",
|
|
32
|
+
type=str,
|
|
33
|
+
required=True,
|
|
34
|
+
help="The secret for OAuth",
|
|
35
|
+
)
|
|
36
|
+
parser.add_argument(
|
|
37
|
+
"--port",
|
|
38
|
+
type=int,
|
|
39
|
+
default=8080,
|
|
40
|
+
help="The port to run the server on",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
return parser.parse_args()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
args = parse_arguments()
|
|
47
|
+
ACCOUNT_ENDPOINT = args.account_endpoint
|
|
48
|
+
CLOUD_ENDPOINT = args.cloud_endpoint
|
|
49
|
+
client_id = args.client_id
|
|
50
|
+
secret = args.secret
|
|
51
|
+
port = args.port # Added the port argument
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
async def fetch_api_key(request):
|
|
55
|
+
code = request.rel_url.query.get("code")
|
|
56
|
+
|
|
57
|
+
if not code:
|
|
58
|
+
return web.Response(text="Missing 'code' parameter", status=400)
|
|
59
|
+
|
|
60
|
+
token_fetch_url = f"{ACCOUNT_ENDPOINT}/api/open/oauth"
|
|
61
|
+
|
|
62
|
+
# Prepare the payload
|
|
63
|
+
payload = {"clientId": client_id, "secret": secret, "code": code}
|
|
64
|
+
|
|
65
|
+
async with aiohttp.ClientSession() as session:
|
|
66
|
+
# Make the first POST request to fetch the token
|
|
67
|
+
async with session.post(token_fetch_url, json=payload) as response:
|
|
68
|
+
if not response.ok:
|
|
69
|
+
return web.Response(text="Failed to fetch access token", status=500)
|
|
70
|
+
|
|
71
|
+
token_json = await response.json()
|
|
72
|
+
access_token = (
|
|
73
|
+
token_json["data"]["access_token"] if token_json.get("status") else None
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
if not access_token:
|
|
77
|
+
return web.Response(text="Failed to retrieve access token", status=500)
|
|
78
|
+
|
|
79
|
+
print("access_token", access_token)
|
|
80
|
+
|
|
81
|
+
api_key_url = f"{CLOUD_ENDPOINT}/api/oauth/apikeys"
|
|
82
|
+
headers = {"Authorization": f"token {access_token}"}
|
|
83
|
+
|
|
84
|
+
# Make the second POST request to fetch API keys
|
|
85
|
+
async with session.post(api_key_url, headers=headers) as api_key_response:
|
|
86
|
+
api_keys_data = await api_key_response.json()
|
|
87
|
+
print("apiKeysData", api_keys_data)
|
|
88
|
+
|
|
89
|
+
if api_keys_data.get("data"):
|
|
90
|
+
return web.Response(
|
|
91
|
+
text=f"""
|
|
92
|
+
<html>
|
|
93
|
+
<head>
|
|
94
|
+
<title>BizyAir</title>
|
|
95
|
+
</head>
|
|
96
|
+
<body>
|
|
97
|
+
<h1>Just a moment...</h1>
|
|
98
|
+
<script>
|
|
99
|
+
window.opener.postMessage({json.dumps(api_keys_data["data"])}, '*');
|
|
100
|
+
</script>
|
|
101
|
+
</body>
|
|
102
|
+
</html>
|
|
103
|
+
""",
|
|
104
|
+
content_type="text/html",
|
|
105
|
+
)
|
|
106
|
+
else:
|
|
107
|
+
return web.Response(text="Failed to fetch API key", status=500)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
async def init_app():
|
|
111
|
+
app = web.Application()
|
|
112
|
+
app.router.add_get("/bizyair/oauth_callback", fetch_api_key)
|
|
113
|
+
return app
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
if __name__ == "__main__":
|
|
117
|
+
app = asyncio.run(init_app())
|
|
118
|
+
web.run_app(app, port=port) # Use the port argument here
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import bizyengine.core.path_utils as path_utils
|
|
2
|
+
from bizyengine.core.common import set_api_key, validate_api_key
|
|
3
|
+
from bizyengine.core.nodes_base import (
|
|
4
|
+
NODE_CLASS_MAPPINGS,
|
|
5
|
+
NODE_DISPLAY_NAME_MAPPINGS,
|
|
6
|
+
BizyAirBaseNode,
|
|
7
|
+
)
|
|
8
|
+
from bizyengine.core.nodes_io import BizyAirNodeIO, create_node_data
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from . import invoker
|