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,60 @@
1
+ import json
2
+ import os
3
+ from enum import Enum
4
+
5
+ from aiohttp import web
6
+
7
+ BIZYAIR_DEBUG = os.getenv("BIZYAIR_DEBUG", False)
8
+ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
9
+
10
+ SHOW_CASES = {}
11
+ SAM_COORDINATE = {}
12
+ IS_RESET_SAM = False
13
+
14
+
15
+ class EDIT_MODE(Enum):
16
+ box = 0
17
+ point = 1
18
+
19
+
20
+ from server import PromptServer
21
+
22
+
23
+ @PromptServer.instance.routes.post("/bizyair/postsam")
24
+ async def save_sam(request):
25
+ global IS_RESET_SAM
26
+ IS_RESET_SAM = False
27
+ post = await request.post()
28
+ SAM_COORDINATE["nums"] = post.get("nums")
29
+ SAM_COORDINATE["mode"] = json.loads(post.get("mode"))
30
+ if SAM_COORDINATE["mode"] == EDIT_MODE.point.value:
31
+ SAM_COORDINATE["point_coords"] = json.loads(post.get("coords"))
32
+ elif SAM_COORDINATE["mode"] == EDIT_MODE.box.value:
33
+ SAM_COORDINATE["box_coords"] = json.loads(post.get("coords"))
34
+ SAM_COORDINATE["filename"] = post.get("filename")
35
+
36
+ return web.Response(status=200)
37
+
38
+
39
+ @PromptServer.instance.routes.get("/bizyair/getsam")
40
+ async def get_sam(request):
41
+ return web.Response(
42
+ text=json.dumps(SAM_COORDINATE, ensure_ascii=False),
43
+ content_type="application/json",
44
+ )
45
+
46
+
47
+ @PromptServer.instance.routes.get("/bizyair/resetsam")
48
+ async def reset_sam(request):
49
+ global IS_RESET_SAM
50
+ IS_RESET_SAM = True
51
+ return web.Response(status=200)
52
+
53
+
54
+ @PromptServer.instance.routes.get("/bizyair/isresetsam")
55
+ async def isreset_sam(request):
56
+ status = {"isresetsam": IS_RESET_SAM}
57
+ return web.Response(
58
+ text=json.dumps(status),
59
+ content_type="application/json",
60
+ )
@@ -0,0 +1,276 @@
1
+ import hashlib
2
+ import json
3
+ import os
4
+ from enum import Enum
5
+
6
+ import folder_paths
7
+ import numpy as np
8
+ import torch
9
+ from bizyengine.core.common.env_var import BIZYAIR_SERVER_ADDRESS
10
+ from bizyengine.core.image_utils import decode_base64_to_np, encode_image_to_base64
11
+ from nodes import LoadImage
12
+ from PIL import Image, ImageOps, ImageSequence
13
+
14
+ from .route_sam import SAM_COORDINATE
15
+ from .utils import get_api_key, send_post_request
16
+
17
+
18
+ class INFER_MODE(Enum):
19
+ auto = 0
20
+ text = 1
21
+ points_box = 2
22
+ batched_boxes = 3
23
+
24
+
25
+ class EDIT_MODE(Enum):
26
+ box = 0
27
+ point = 1
28
+
29
+
30
+ class BizyAirSegmentAnythingText:
31
+ API_URL = f"{BIZYAIR_SERVER_ADDRESS}/supernode/sam"
32
+
33
+ @classmethod
34
+ def INPUT_TYPES(s):
35
+ return {
36
+ "required": {
37
+ "image": ("IMAGE",),
38
+ "prompt": ("STRING", {}),
39
+ "box_threshold": (
40
+ "FLOAT",
41
+ {"default": 0.3, "min": 0, "max": 1.0, "step": 0.01},
42
+ ),
43
+ "text_threshold": (
44
+ "FLOAT",
45
+ {"default": 0.3, "min": 0, "max": 1.0, "step": 0.01},
46
+ ),
47
+ }
48
+ }
49
+
50
+ RETURN_TYPES = ("IMAGE", "MASK")
51
+ FUNCTION = "text_sam"
52
+
53
+ CATEGORY = "☁️BizyAir/segment-anything"
54
+
55
+ def text_sam(self, image, prompt, box_threshold, text_threshold):
56
+ API_KEY = get_api_key()
57
+ SIZE_LIMIT = 1536
58
+ device = image.device
59
+ _, w, h, c = image.shape
60
+ assert (
61
+ w <= SIZE_LIMIT and h <= SIZE_LIMIT
62
+ ), f"width and height must be less than {SIZE_LIMIT}x{SIZE_LIMIT}, but got {w} and {h}"
63
+
64
+ payload = {
65
+ "image": None,
66
+ "mode": 1, # 文本分割模式
67
+ "params": {
68
+ "prompt": prompt,
69
+ "box_threshold": box_threshold,
70
+ "text_threshold": text_threshold,
71
+ },
72
+ }
73
+ auth = f"Bearer {API_KEY}"
74
+ headers = {
75
+ "accept": "application/json",
76
+ "content-type": "application/json",
77
+ "authorization": auth,
78
+ }
79
+ image = image.squeeze(0).numpy()
80
+ image_pil = Image.fromarray((image * 255).astype(np.uint8))
81
+ input_image = encode_image_to_base64(image_pil, format="webp")
82
+ payload["image"] = input_image
83
+
84
+ ret: str = send_post_request(self.API_URL, payload=payload, headers=headers)
85
+ ret = json.loads(ret)
86
+
87
+ try:
88
+ if "result" in ret:
89
+ ret = json.loads(ret["result"])
90
+ except Exception as e:
91
+ raise Exception(f"Unexpected response: {ret} {e=}")
92
+
93
+ if ret["status"] == "error":
94
+ raise Exception(ret["message"])
95
+
96
+ msg = ret["data"]
97
+ if msg["type"] not in ("bizyair",):
98
+ raise Exception(f"Unexpected response type: {msg}")
99
+
100
+ if "error" in msg:
101
+ raise Exception(f"Error happens: {msg}")
102
+
103
+ img = msg["image"]
104
+ mask_image = msg["mask_image"]
105
+
106
+ img = (
107
+ (torch.from_numpy(decode_base64_to_np(img)).float() / 255.0)
108
+ .unsqueeze(0)
109
+ .to(device)
110
+ )
111
+ img_mask = (
112
+ torch.from_numpy(decode_base64_to_np(mask_image)).float() / 255.0
113
+ ).to(device)
114
+ img_mask = img_mask.mean(dim=-1)
115
+ img_mask = img_mask.unsqueeze(0)
116
+
117
+ return (img, img_mask)
118
+
119
+
120
+ class BizyAirSegmentAnythingPointBox:
121
+ API_URL = f"{BIZYAIR_SERVER_ADDRESS}/supernode/sam"
122
+
123
+ @classmethod
124
+ def INPUT_TYPES(s):
125
+ input_dir = folder_paths.get_input_directory()
126
+ files = [
127
+ f
128
+ for f in os.listdir(input_dir)
129
+ if os.path.isfile(os.path.join(input_dir, f))
130
+ ]
131
+ return {
132
+ "required": {
133
+ "image": (sorted(files), {"image_upload": True}),
134
+ "is_point": ("BOOLEAN", {"default": True}),
135
+ },
136
+ }
137
+
138
+ RETURN_TYPES = ("IMAGE", "MASK", "IMAGE")
139
+ RETURN_NAMES = ("processed_image", "mask", "original_image")
140
+ FUNCTION = "apply"
141
+
142
+ CATEGORY = "☁️BizyAir/segment-anything"
143
+
144
+ def apply(self, image, is_point):
145
+ API_KEY = get_api_key()
146
+ SIZE_LIMIT = 1536
147
+
148
+ # 加载原始图像
149
+ original_image, _ = LoadImage().load_image(image)
150
+ # 直接克隆原始图像用于处理和透传
151
+ image_to_process = original_image.clone()
152
+
153
+ device = image_to_process.device
154
+ _, w, h, c = image_to_process.shape
155
+ assert (
156
+ w <= SIZE_LIMIT and h <= SIZE_LIMIT
157
+ ), f"width and height must be less than {SIZE_LIMIT}x{SIZE_LIMIT}, but got {w} and {h}"
158
+
159
+ if is_point:
160
+ coordinates = [
161
+ eval(SAM_COORDINATE["point_coords"][key])
162
+ for key in SAM_COORDINATE["point_coords"]
163
+ ]
164
+
165
+ input_points = [
166
+ [float(coord["startx"]), float(coord["starty"])]
167
+ for coord in coordinates
168
+ ]
169
+
170
+ input_label = [coord["pointType"] for coord in coordinates]
171
+ payload = {
172
+ "image": None,
173
+ "mode": INFER_MODE.points_box.value,
174
+ "params": {
175
+ "input_points": json.dumps(input_points),
176
+ "input_label": json.dumps(input_label),
177
+ "input_boxes": None,
178
+ },
179
+ }
180
+ else:
181
+ coordinates = [
182
+ eval(SAM_COORDINATE["box_coords"][key])
183
+ for key in SAM_COORDINATE["box_coords"]
184
+ ]
185
+ input_box = [
186
+ [
187
+ float(coord["startx"]),
188
+ float(coord["starty"]),
189
+ float(coord["endx"]),
190
+ float(coord["endy"]),
191
+ ]
192
+ for coord in coordinates
193
+ ]
194
+
195
+ payload = {
196
+ "image": None,
197
+ "mode": INFER_MODE.batched_boxes.value,
198
+ "params": {
199
+ "input_points": None,
200
+ "input_label": None,
201
+ "input_boxes": json.dumps(input_box),
202
+ },
203
+ }
204
+
205
+ auth = f"Bearer {API_KEY}"
206
+ headers = {
207
+ "accept": "application/json",
208
+ "content-type": "application/json",
209
+ "authorization": auth,
210
+ }
211
+ # 处理用于API的图像
212
+ api_image = image_to_process.squeeze(0).numpy()
213
+ image_pil = Image.fromarray((api_image * 255).astype(np.uint8))
214
+ input_image = encode_image_to_base64(image_pil, format="webp")
215
+ payload["image"] = input_image
216
+
217
+ ret: str = send_post_request(self.API_URL, payload=payload, headers=headers)
218
+ ret = json.loads(ret)
219
+
220
+ try:
221
+ if "result" in ret:
222
+ ret = json.loads(ret["result"])
223
+ except Exception as e:
224
+ raise Exception(f"Unexpected response: {ret} {e=}")
225
+
226
+ if ret["status"] == "error":
227
+ raise Exception(ret["message"])
228
+
229
+ msg = ret["data"]
230
+ if msg["type"] not in ("bizyair",):
231
+ raise Exception(f"Unexpected response type: {msg}")
232
+
233
+ if "error" in msg:
234
+ raise Exception(f"Error happens: {msg}")
235
+
236
+ img = msg["image"]
237
+ mask_image = msg["mask_image"]
238
+
239
+ processed_img = (
240
+ (torch.from_numpy(decode_base64_to_np(img)).float() / 255.0)
241
+ .unsqueeze(0)
242
+ .to(device)
243
+ )
244
+ img_mask = (
245
+ torch.from_numpy(decode_base64_to_np(mask_image)).float() / 255.0
246
+ ).to(device)
247
+ img_mask = img_mask.mean(dim=-1)
248
+ img_mask = img_mask.unsqueeze(0)
249
+
250
+ # 直接返回克隆的原始图像,无需转换
251
+ return (processed_img, img_mask, image_to_process)
252
+
253
+ @classmethod
254
+ def IS_CHANGED(s, image, is_point):
255
+ image_path = folder_paths.get_annotated_filepath(image)
256
+ m = hashlib.sha256()
257
+ with open(image_path, "rb") as f:
258
+ m.update(f.read())
259
+ return m.digest().hex()
260
+
261
+ @classmethod
262
+ def VALIDATE_INPUTS(s, image, is_point):
263
+ if not folder_paths.exists_annotated_filepath(image):
264
+ return "Invalid image file: {}".format(image)
265
+
266
+ return True
267
+
268
+
269
+ NODE_CLASS_MAPPINGS = {
270
+ "BizyAirSegmentAnythingText": BizyAirSegmentAnythingText,
271
+ "BizyAirSegmentAnythingPointBox": BizyAirSegmentAnythingPointBox,
272
+ }
273
+ NODE_DISPLAY_NAME_MAPPINGS = {
274
+ "BizyAirSegmentAnythingText": "☁️BizyAir Text Guided SAM",
275
+ "BizyAirSegmentAnythingPointBox": "☁️BizyAir Point-Box Guided SAM",
276
+ }
@@ -0,0 +1,182 @@
1
+ import hashlib
2
+ import json
3
+ import os
4
+ import uuid
5
+ from enum import Enum
6
+
7
+ import folder_paths
8
+ import node_helpers
9
+ import numpy as np
10
+ import torch
11
+ from bizyengine.core.common.env_var import BIZYAIR_SERVER_ADDRESS
12
+ from bizyengine.core.image_utils import (
13
+ decode_base64_to_np,
14
+ decode_data,
15
+ encode_data,
16
+ encode_image_to_base64,
17
+ )
18
+ from nodes import LoadImage
19
+ from PIL import Image, ImageOps, ImageSequence
20
+
21
+ from .utils import (
22
+ decode_and_deserialize,
23
+ get_api_key,
24
+ send_post_request,
25
+ serialize_and_encode,
26
+ )
27
+
28
+
29
+ class RemoveBackground:
30
+ API_URL = f"{BIZYAIR_SERVER_ADDRESS}/supernode/removebg"
31
+
32
+ @classmethod
33
+ def INPUT_TYPES(s):
34
+ return {
35
+ "required": {
36
+ "image": ("IMAGE",),
37
+ }
38
+ }
39
+
40
+ RETURN_TYPES = ("IMAGE", "MASK")
41
+ FUNCTION = "remove_background"
42
+
43
+ CATEGORY = "☁️BizyAir"
44
+
45
+ def remove_background(self, image):
46
+ API_KEY = get_api_key()
47
+ device = image.device
48
+ _, h, w, _ = image.shape
49
+ assert (
50
+ w <= 1536 and h <= 1536
51
+ ), f"width and height must be less than 1536, but got {w} and {h}"
52
+
53
+ payload = {
54
+ "is_compress": True,
55
+ "image": None,
56
+ }
57
+ auth = f"Bearer {API_KEY}"
58
+ headers = {
59
+ "accept": "application/json",
60
+ "content-type": "application/json",
61
+ "authorization": auth,
62
+ }
63
+ input_image, compress = serialize_and_encode(image, compress=True)
64
+ payload["image"] = input_image
65
+ payload["is_compress"] = compress
66
+
67
+ response: str = send_post_request(
68
+ self.API_URL, payload=payload, headers=headers
69
+ )
70
+ tensors = decode_and_deserialize(response)
71
+ t_images = tensors["images"].to(device)
72
+ t_mask = tensors["mask"].to(device)
73
+ return (t_images, t_mask)
74
+
75
+
76
+ class GenerateLightningImage:
77
+ API_URL = f"{BIZYAIR_SERVER_ADDRESS}/supernode/realvis4lightning"
78
+
79
+ @classmethod
80
+ def INPUT_TYPES(s):
81
+ return {
82
+ "required": {
83
+ "prompt": (
84
+ "STRING",
85
+ {"multiline": True, "dynamicPrompts": True, "default": "a dog"},
86
+ ),
87
+ "seed": ("INT", {"default": 1, "min": 0, "max": 0xFFFFFFFFFFFFFFFF}),
88
+ "width": ("INT", {"default": 1024, "min": 16, "max": 1024, "step": 8}),
89
+ "height": ("INT", {"default": 1024, "min": 16, "max": 1024, "step": 8}),
90
+ "cfg": (
91
+ "FLOAT",
92
+ {
93
+ "default": 1.5,
94
+ "min": 0.0,
95
+ "max": 10.0,
96
+ "step": 0.1,
97
+ "round": 0.01,
98
+ },
99
+ ),
100
+ "batch_size": ("INT", {"default": 1, "min": 1, "max": 4}),
101
+ }
102
+ }
103
+
104
+ RETURN_TYPES = ("IMAGE",)
105
+ FUNCTION = "generate_image"
106
+
107
+ CATEGORY = "☁️BizyAir"
108
+
109
+ def generate_image(self, prompt, seed, width, height, cfg, batch_size):
110
+ API_KEY = get_api_key()
111
+ assert (
112
+ width <= 1024 and height <= 1024
113
+ ), f"width and height must be less than 1024, but got {width} and {height}"
114
+
115
+ payload = {
116
+ "batch_size": batch_size,
117
+ "width": width,
118
+ "height": height,
119
+ "prompt": prompt,
120
+ "cfg": cfg,
121
+ "seed": seed,
122
+ }
123
+ auth = f"Bearer {API_KEY}"
124
+ headers = {
125
+ "accept": "application/json",
126
+ "content-type": "application/json",
127
+ "authorization": auth,
128
+ }
129
+
130
+ response: str = send_post_request(
131
+ self.API_URL, payload=payload, headers=headers
132
+ )
133
+ tensors_np = decode_and_deserialize(response)
134
+ tensors = torch.from_numpy(tensors_np)
135
+
136
+ return (tensors,)
137
+
138
+
139
+ class ToggleServerEndpoint:
140
+ BIZYAIR_SERVER_ENDPOINTS = [
141
+ "https://bizyair-api-st.siliconflow.cn/x/v1",
142
+ "https://bizyair-api.siliconflow.cn/x/v1",
143
+ ]
144
+
145
+ def __init__(self):
146
+ self.current_index = 0
147
+
148
+ @classmethod
149
+ def INPUT_TYPES(s):
150
+ return {
151
+ "required": {
152
+ "endpoint": (s.BIZYAIR_SERVER_ENDPOINTS,),
153
+ }
154
+ }
155
+
156
+ RETURN_TYPES = ()
157
+ FUNCTION = "toggle_endpoint"
158
+ OUTPUT_NODE = True
159
+
160
+ CATEGORY = "☁️BizyAir"
161
+
162
+ def toggle_endpoint(self, endpoint):
163
+ BIZYAIR_SERVER_ADDRESS.address = endpoint
164
+ from server import PromptServer
165
+
166
+ PromptServer.instance.send_sync(
167
+ "bizyair.server.endpoint.switch",
168
+ {"message": f"Switch server endpoint to {endpoint}"},
169
+ )
170
+ return ()
171
+
172
+
173
+ NODE_CLASS_MAPPINGS = {
174
+ "BizyAirRemoveBackground": RemoveBackground,
175
+ "BizyAirGenerateLightningImage": GenerateLightningImage,
176
+ "BizyAirToggleServerEndpoint": ToggleServerEndpoint,
177
+ }
178
+ NODE_DISPLAY_NAME_MAPPINGS = {
179
+ "BizyAirRemoveBackground": "☁️BizyAir Remove Image Background",
180
+ "BizyAirGenerateLightningImage": "☁️BizyAir Generate Photorealistic Images",
181
+ "BizyAirToggleServerEndpoint": "☁️BizyAir Switch Server Endpoint",
182
+ }