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.
Files changed (76) hide show
  1. bizyengine/__init__.py +35 -0
  2. bizyengine/bizy_server/__init__.py +7 -0
  3. bizyengine/bizy_server/api_client.py +763 -0
  4. bizyengine/bizy_server/errno.py +122 -0
  5. bizyengine/bizy_server/error_handler.py +3 -0
  6. bizyengine/bizy_server/execution.py +55 -0
  7. bizyengine/bizy_server/resp.py +24 -0
  8. bizyengine/bizy_server/server.py +898 -0
  9. bizyengine/bizy_server/utils.py +93 -0
  10. bizyengine/bizyair_extras/__init__.py +24 -0
  11. bizyengine/bizyair_extras/nodes_advanced_refluxcontrol.py +62 -0
  12. bizyengine/bizyair_extras/nodes_cogview4.py +31 -0
  13. bizyengine/bizyair_extras/nodes_comfyui_detail_daemon.py +180 -0
  14. bizyengine/bizyair_extras/nodes_comfyui_instantid.py +164 -0
  15. bizyengine/bizyair_extras/nodes_comfyui_layerstyle_advance.py +141 -0
  16. bizyengine/bizyair_extras/nodes_comfyui_pulid_flux.py +88 -0
  17. bizyengine/bizyair_extras/nodes_controlnet.py +50 -0
  18. bizyengine/bizyair_extras/nodes_custom_sampler.py +130 -0
  19. bizyengine/bizyair_extras/nodes_dataset.py +99 -0
  20. bizyengine/bizyair_extras/nodes_differential_diffusion.py +16 -0
  21. bizyengine/bizyair_extras/nodes_flux.py +69 -0
  22. bizyengine/bizyair_extras/nodes_image_utils.py +93 -0
  23. bizyengine/bizyair_extras/nodes_ip2p.py +20 -0
  24. bizyengine/bizyair_extras/nodes_ipadapter_plus/__init__.py +1 -0
  25. bizyengine/bizyair_extras/nodes_ipadapter_plus/nodes_ipadapter_plus.py +1598 -0
  26. bizyengine/bizyair_extras/nodes_janus_pro.py +81 -0
  27. bizyengine/bizyair_extras/nodes_kolors_mz/__init__.py +86 -0
  28. bizyengine/bizyair_extras/nodes_model_advanced.py +62 -0
  29. bizyengine/bizyair_extras/nodes_sd3.py +52 -0
  30. bizyengine/bizyair_extras/nodes_segment_anything.py +256 -0
  31. bizyengine/bizyair_extras/nodes_segment_anything_utils.py +134 -0
  32. bizyengine/bizyair_extras/nodes_testing_utils.py +139 -0
  33. bizyengine/bizyair_extras/nodes_trellis.py +199 -0
  34. bizyengine/bizyair_extras/nodes_ultimatesdupscale.py +137 -0
  35. bizyengine/bizyair_extras/nodes_upscale_model.py +32 -0
  36. bizyengine/bizyair_extras/nodes_wan_video.py +49 -0
  37. bizyengine/bizyair_extras/oauth_callback/main.py +118 -0
  38. bizyengine/core/__init__.py +8 -0
  39. bizyengine/core/commands/__init__.py +1 -0
  40. bizyengine/core/commands/base.py +27 -0
  41. bizyengine/core/commands/invoker.py +4 -0
  42. bizyengine/core/commands/processors/model_hosting_processor.py +0 -0
  43. bizyengine/core/commands/processors/prompt_processor.py +123 -0
  44. bizyengine/core/commands/servers/model_server.py +0 -0
  45. bizyengine/core/commands/servers/prompt_server.py +234 -0
  46. bizyengine/core/common/__init__.py +8 -0
  47. bizyengine/core/common/caching.py +198 -0
  48. bizyengine/core/common/client.py +262 -0
  49. bizyengine/core/common/env_var.py +101 -0
  50. bizyengine/core/common/utils.py +93 -0
  51. bizyengine/core/configs/conf.py +112 -0
  52. bizyengine/core/configs/models.json +101 -0
  53. bizyengine/core/configs/models.yaml +329 -0
  54. bizyengine/core/data_types.py +20 -0
  55. bizyengine/core/image_utils.py +288 -0
  56. bizyengine/core/nodes_base.py +159 -0
  57. bizyengine/core/nodes_io.py +97 -0
  58. bizyengine/core/path_utils/__init__.py +9 -0
  59. bizyengine/core/path_utils/path_manager.py +276 -0
  60. bizyengine/core/path_utils/utils.py +34 -0
  61. bizyengine/misc/__init__.py +0 -0
  62. bizyengine/misc/auth.py +83 -0
  63. bizyengine/misc/llm.py +431 -0
  64. bizyengine/misc/mzkolors.py +93 -0
  65. bizyengine/misc/nodes.py +1208 -0
  66. bizyengine/misc/nodes_controlnet_aux.py +491 -0
  67. bizyengine/misc/nodes_controlnet_union_sdxl.py +171 -0
  68. bizyengine/misc/route_sam.py +60 -0
  69. bizyengine/misc/segment_anything.py +276 -0
  70. bizyengine/misc/supernode.py +182 -0
  71. bizyengine/misc/utils.py +218 -0
  72. bizyengine/version.txt +1 -0
  73. bizyengine-0.4.2.dist-info/METADATA +12 -0
  74. bizyengine-0.4.2.dist-info/RECORD +76 -0
  75. bizyengine-0.4.2.dist-info/WHEEL +5 -0
  76. 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