bizyengine 1.2.7__py3-none-any.whl → 1.2.8__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.
@@ -8,13 +8,13 @@ import os
8
8
 
9
9
  import numpy as np
10
10
  import requests
11
+ from bizyengine.core import BizyAirMiscBaseNode, pop_api_key_and_prompt_id
12
+ from bizyengine.core.common import client
11
13
  from bizyengine.core.common.env_var import BIZYAIR_SERVER_ADDRESS
12
14
  from bizyengine.core.image_utils import decode_comfy_image, encode_comfy_image
13
15
 
14
- from .utils import get_api_key
15
16
 
16
-
17
- class StableDiffusionXLControlNetUnionPipeline:
17
+ class StableDiffusionXLControlNetUnionPipeline(BizyAirMiscBaseNode):
18
18
  API_URL = f"{BIZYAIR_SERVER_ADDRESS}/supernode/diffusers-v1-stablediffusionxlcontrolnetunionpipeline"
19
19
 
20
20
  @classmethod
@@ -83,14 +83,6 @@ class StableDiffusionXLControlNetUnionPipeline:
83
83
  FUNCTION = "process"
84
84
  CATEGORY = "☁️BizyAir/ControlNet"
85
85
 
86
- @staticmethod
87
- def get_headers():
88
- return {
89
- "accept": "application/json",
90
- "content-type": "application/json",
91
- "authorization": f"Bearer {get_api_key()}",
92
- }
93
-
94
86
  def process(
95
87
  self,
96
88
  openpose_image=None,
@@ -101,6 +93,7 @@ class StableDiffusionXLControlNetUnionPipeline:
101
93
  segment_image=None,
102
94
  **kwargs,
103
95
  ):
96
+ extra_data = pop_api_key_and_prompt_id(kwargs)
104
97
  controlnet_img = {
105
98
  0: openpose_image,
106
99
  1: depth_image,
@@ -143,7 +136,7 @@ class StableDiffusionXLControlNetUnionPipeline:
143
136
  response = requests.post(
144
137
  self.API_URL,
145
138
  json=payload,
146
- headers=self.get_headers(),
139
+ headers=client.headers(api_key=extra_data["api_key"]),
147
140
  )
148
141
 
149
142
  result = response.json()
@@ -6,13 +6,14 @@ from enum import Enum
6
6
  import folder_paths
7
7
  import numpy as np
8
8
  import torch
9
+ from bizyengine.core import BizyAirMiscBaseNode, pop_api_key_and_prompt_id
10
+ from bizyengine.core.common import client
9
11
  from bizyengine.core.common.env_var import BIZYAIR_SERVER_ADDRESS
10
12
  from bizyengine.core.image_utils import decode_base64_to_np, encode_image_to_base64
11
13
  from nodes import LoadImage
12
14
  from PIL import Image, ImageOps, ImageSequence
13
15
 
14
16
  from .route_sam import SAM_COORDINATE
15
- from .utils import get_api_key, send_post_request
16
17
 
17
18
 
18
19
  class INFER_MODE(Enum):
@@ -27,7 +28,7 @@ class EDIT_MODE(Enum):
27
28
  point = 1
28
29
 
29
30
 
30
- class BizyAirSegmentAnythingText:
31
+ class BizyAirSegmentAnythingText(BizyAirMiscBaseNode):
31
32
  API_URL = f"{BIZYAIR_SERVER_ADDRESS}/supernode/sam"
32
33
 
33
34
  @classmethod
@@ -44,7 +45,7 @@ class BizyAirSegmentAnythingText:
44
45
  "FLOAT",
45
46
  {"default": 0.3, "min": 0, "max": 1.0, "step": 0.01},
46
47
  ),
47
- }
48
+ },
48
49
  }
49
50
 
50
51
  RETURN_TYPES = ("IMAGE", "MASK")
@@ -52,8 +53,10 @@ class BizyAirSegmentAnythingText:
52
53
 
53
54
  CATEGORY = "☁️BizyAir/segment-anything"
54
55
 
55
- def text_sam(self, image, prompt, box_threshold, text_threshold):
56
- API_KEY = get_api_key()
56
+ def text_sam(self, image, prompt, box_threshold, text_threshold, **kwargs):
57
+ extra_data = pop_api_key_and_prompt_id(kwargs)
58
+ headers = client.headers(api_key=extra_data["api_key"])
59
+
57
60
  SIZE_LIMIT = 1536
58
61
  device = image.device
59
62
  _, w, h, c = image.shape
@@ -70,19 +73,20 @@ class BizyAirSegmentAnythingText:
70
73
  "text_threshold": text_threshold,
71
74
  },
72
75
  }
73
- auth = f"Bearer {API_KEY}"
74
- headers = {
75
- "accept": "application/json",
76
- "content-type": "application/json",
77
- "authorization": auth,
78
- }
79
76
  image = image.squeeze(0).numpy()
80
77
  image_pil = Image.fromarray((image * 255).astype(np.uint8))
81
78
  input_image = encode_image_to_base64(image_pil, format="webp")
82
79
  payload["image"] = input_image
83
-
84
- ret: str = send_post_request(self.API_URL, payload=payload, headers=headers)
85
- ret = json.loads(ret)
80
+ if "prompt_id" in extra_data:
81
+ payload["prompt_id"] = extra_data["prompt_id"]
82
+ data = json.dumps(payload).encode("utf-8")
83
+
84
+ ret = client.send_request(
85
+ url=self.API_URL,
86
+ data=data,
87
+ headers=headers,
88
+ callback=None,
89
+ )
86
90
 
87
91
  try:
88
92
  if "result" in ret:
@@ -117,7 +121,7 @@ class BizyAirSegmentAnythingText:
117
121
  return (img, img_mask)
118
122
 
119
123
 
120
- class BizyAirSegmentAnythingPointBox:
124
+ class BizyAirSegmentAnythingPointBox(BizyAirMiscBaseNode):
121
125
  API_URL = f"{BIZYAIR_SERVER_ADDRESS}/supernode/sam"
122
126
 
123
127
  @classmethod
@@ -141,8 +145,10 @@ class BizyAirSegmentAnythingPointBox:
141
145
 
142
146
  CATEGORY = "☁️BizyAir/segment-anything"
143
147
 
144
- def apply(self, image, is_point):
145
- API_KEY = get_api_key()
148
+ def apply(self, image, is_point, **kwargs):
149
+ extra_data = pop_api_key_and_prompt_id(kwargs)
150
+ headers = client.headers(api_key=extra_data["api_key"])
151
+
146
152
  SIZE_LIMIT = 1536
147
153
 
148
154
  # 加载原始图像
@@ -201,20 +207,18 @@ class BizyAirSegmentAnythingPointBox:
201
207
  },
202
208
  }
203
209
 
204
- auth = f"Bearer {API_KEY}"
205
- headers = {
206
- "accept": "application/json",
207
- "content-type": "application/json",
208
- "authorization": auth,
209
- }
210
210
  # 处理用于API的图像
211
211
  api_image = image_to_process.squeeze(0).numpy()
212
212
  image_pil = Image.fromarray((api_image * 255).astype(np.uint8))
213
213
  input_image = encode_image_to_base64(image_pil, format="webp")
214
214
  payload["image"] = input_image
215
+ if "prompt_id" in extra_data:
216
+ payload["prompt_id"] = extra_data["prompt_id"]
217
+ data = json.dumps(payload).encode("utf-8")
215
218
 
216
- ret: str = send_post_request(self.API_URL, payload=payload, headers=headers)
217
- ret = json.loads(ret)
219
+ ret = client.send_request(
220
+ url=self.API_URL, data=data, headers=headers, callback=None
221
+ )
218
222
 
219
223
  try:
220
224
  if "result" in ret:
@@ -8,6 +8,8 @@ import folder_paths
8
8
  import node_helpers
9
9
  import numpy as np
10
10
  import torch
11
+ from bizyengine.core import BizyAirMiscBaseNode
12
+ from bizyengine.core.common import client
11
13
  from bizyengine.core.common.env_var import BIZYAIR_SERVER_ADDRESS
12
14
  from bizyengine.core.image_utils import (
13
15
  decode_base64_to_np,
@@ -20,13 +22,12 @@ from PIL import Image, ImageOps, ImageSequence
20
22
 
21
23
  from .utils import (
22
24
  decode_and_deserialize,
23
- get_api_key,
24
- send_post_request,
25
+ pop_api_key_and_prompt_id,
25
26
  serialize_and_encode,
26
27
  )
27
28
 
28
29
 
29
- class RemoveBackground:
30
+ class RemoveBackground(BizyAirMiscBaseNode):
30
31
  API_URL = f"{BIZYAIR_SERVER_ADDRESS}/supernode/removebg"
31
32
 
32
33
  @classmethod
@@ -34,7 +35,7 @@ class RemoveBackground:
34
35
  return {
35
36
  "required": {
36
37
  "image": ("IMAGE",),
37
- }
38
+ },
38
39
  }
39
40
 
40
41
  RETURN_TYPES = ("IMAGE", "MASK")
@@ -42,8 +43,10 @@ class RemoveBackground:
42
43
 
43
44
  CATEGORY = "☁️BizyAir"
44
45
 
45
- def remove_background(self, image):
46
- API_KEY = get_api_key()
46
+ def remove_background(self, image, **kwargs):
47
+ extra_data = pop_api_key_and_prompt_id(kwargs)
48
+ headers = client.headers(api_key=extra_data["api_key"])
49
+
47
50
  device = image.device
48
51
  _, h, w, _ = image.shape
49
52
  assert (
@@ -54,26 +57,27 @@ class RemoveBackground:
54
57
  "is_compress": True,
55
58
  "image": None,
56
59
  }
57
- auth = f"Bearer {API_KEY}"
58
- headers = {
59
- "accept": "application/json",
60
- "content-type": "application/json",
61
- "authorization": auth,
62
- }
63
60
  input_image, compress = serialize_and_encode(image, compress=True)
64
61
  payload["image"] = input_image
65
62
  payload["is_compress"] = compress
66
-
67
- response: str = send_post_request(
68
- self.API_URL, payload=payload, headers=headers
63
+ if "prompt_id" in extra_data:
64
+ payload["prompt_id"] = extra_data["prompt_id"]
65
+ data = json.dumps(payload).encode("utf-8")
66
+
67
+ tensors = client.send_request(
68
+ url=self.API_URL,
69
+ data=data,
70
+ headers=headers,
71
+ callback=None,
72
+ response_handler=decode_and_deserialize,
69
73
  )
70
- tensors = decode_and_deserialize(response)
74
+
71
75
  t_images = tensors["images"].to(device)
72
76
  t_mask = tensors["mask"].to(device)
73
77
  return (t_images, t_mask)
74
78
 
75
79
 
76
- class GenerateLightningImage:
80
+ class GenerateLightningImage(BizyAirMiscBaseNode):
77
81
  API_URL = f"{BIZYAIR_SERVER_ADDRESS}/supernode/realvis4lightning"
78
82
 
79
83
  @classmethod
@@ -98,7 +102,7 @@ class GenerateLightningImage:
98
102
  },
99
103
  ),
100
104
  "batch_size": ("INT", {"default": 1, "min": 1, "max": 4}),
101
- }
105
+ },
102
106
  }
103
107
 
104
108
  RETURN_TYPES = ("IMAGE",)
@@ -106,8 +110,10 @@ class GenerateLightningImage:
106
110
 
107
111
  CATEGORY = "☁️BizyAir"
108
112
 
109
- def generate_image(self, prompt, seed, width, height, cfg, batch_size):
110
- API_KEY = get_api_key()
113
+ def generate_image(self, prompt, seed, width, height, cfg, batch_size, **kwargs):
114
+ extra_data = pop_api_key_and_prompt_id(kwargs)
115
+ headers = client.headers(api_key=extra_data["api_key"])
116
+
111
117
  assert (
112
118
  width <= 1024 and height <= 1024
113
119
  ), f"width and height must be less than 1024, but got {width} and {height}"
@@ -120,17 +126,17 @@ class GenerateLightningImage:
120
126
  "cfg": cfg,
121
127
  "seed": seed,
122
128
  }
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
129
+ if "prompt_id" in extra_data:
130
+ payload["prompt_id"] = extra_data["prompt_id"]
131
+ data = json.dumps(payload).encode("utf-8")
132
+
133
+ tensors_np = client.send_request(
134
+ url=self.API_URL,
135
+ data=data,
136
+ headers=headers,
137
+ callback=None,
138
+ response_handler=decode_and_deserialize,
132
139
  )
133
- tensors_np = decode_and_deserialize(response)
134
140
  tensors = torch.from_numpy(tensors_np)
135
141
 
136
142
  return (tensors,)
bizyengine/misc/utils.py CHANGED
@@ -8,12 +8,19 @@ import zlib
8
8
  from typing import List, Tuple, Union
9
9
 
10
10
  import numpy as np
11
+ from bizyengine.core import pop_api_key_and_prompt_id
12
+ from bizyengine.core.common import client
11
13
  from bizyengine.core.common.env_var import BIZYAIR_SERVER_ADDRESS
12
14
 
13
15
  BIZYAIR_DEBUG = os.getenv("BIZYAIR_DEBUG", False)
14
16
 
15
17
 
18
+ #
19
+ # TODO: Deprecated, delete this
16
20
  def send_post_request(api_url, payload, headers):
21
+ import warnings
22
+
23
+ warnings.warn(message=f"send_post_request is deprecated")
17
24
  """
18
25
  Sends a POST request to the specified API URL with the given payload and headers.
19
26
 
@@ -123,26 +130,17 @@ def format_bytes(num_bytes: int) -> str:
123
130
  return f"{num_bytes / (1024 * 1024):.2f} MB"
124
131
 
125
132
 
126
- def get_api_key():
127
- from bizyengine.core.common import get_api_key as bcc_get_api_key
128
-
129
- return bcc_get_api_key()
130
-
131
-
132
133
  def get_llm_response(
133
134
  model: str,
134
135
  system_prompt: str,
135
136
  user_prompt: str,
136
137
  max_tokens: int = 1024,
137
138
  temperature: float = 0.7,
139
+ **kwargs,
138
140
  ):
139
141
  api_url = f"{BIZYAIR_SERVER_ADDRESS}/chat/completions"
140
- API_KEY = get_api_key()
141
- headers = {
142
- "accept": "application/json",
143
- "content-type": "application/json",
144
- "Authorization": f"Bearer {API_KEY}",
145
- }
142
+ extra_data = pop_api_key_and_prompt_id(kwargs)
143
+ headers = client.headers(api_key=extra_data["api_key"])
146
144
 
147
145
  payload = {
148
146
  "model": model,
@@ -157,7 +155,16 @@ def get_llm_response(
157
155
  "stream": False,
158
156
  "n": 1,
159
157
  }
160
- response = send_post_request(api_url, headers=headers, payload=payload)
158
+ if "prompt_id" in extra_data:
159
+ payload["prompt_id"] = extra_data["prompt_id"]
160
+ data = json.dumps(payload).encode("utf-8")
161
+
162
+ response = client.send_request(
163
+ url=api_url,
164
+ data=data,
165
+ headers=headers,
166
+ callback=None,
167
+ )
161
168
  return response
162
169
 
163
170
 
@@ -169,14 +176,11 @@ def get_vlm_response(
169
176
  max_tokens: int = 1024,
170
177
  temperature: float = 0.7,
171
178
  detail: str = "auto",
179
+ **kwargs,
172
180
  ):
173
181
  api_url = f"{BIZYAIR_SERVER_ADDRESS}/chat/completions"
174
- API_KEY = get_api_key()
175
- headers = {
176
- "accept": "application/json",
177
- "content-type": "application/json",
178
- "Authorization": f"Bearer {API_KEY}",
179
- }
182
+ extra_data = pop_api_key_and_prompt_id(kwargs)
183
+ headers = client.headers(api_key=extra_data["api_key"])
180
184
 
181
185
  messages = [
182
186
  {
@@ -214,6 +218,14 @@ def get_vlm_response(
214
218
  "stream": False,
215
219
  "n": 1,
216
220
  }
217
-
218
- response = send_post_request(api_url, headers=headers, payload=payload)
221
+ if "prompt_id" in extra_data:
222
+ payload["prompt_id"] = extra_data["prompt_id"]
223
+ data = json.dumps(payload).encode("utf-8")
224
+
225
+ response = client.send_request(
226
+ url=api_url,
227
+ headers=headers,
228
+ data=data,
229
+ callback=None,
230
+ )
219
231
  return response
bizyengine/version.txt CHANGED
@@ -1 +1 @@
1
- 1.2.7
1
+ 1.2.8
@@ -0,0 +1,211 @@
1
+ Metadata-Version: 2.4
2
+ Name: bizyengine
3
+ Version: 1.2.8
4
+ Summary: [a/BizyAir](https://github.com/siliconflow/BizyAir) Comfy Nodes that can run in any environment.
5
+ Author-email: SiliconFlow <yaochi@siliconflow.cn>
6
+ Project-URL: Repository, https://github.com/siliconflow/BizyAir
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: requests
13
+
14
+ ## Server Mode
15
+
16
+ ```bash
17
+ export BIZYAIR_API_KEY="your api key"
18
+ export BIZYAIR_SERVER_MODE=1
19
+ ```
20
+
21
+ ```python
22
+ import json
23
+ import os
24
+ from urllib import request
25
+
26
+ BIZYAIR_API_KEY=os.getenv("BIZYAIR_API_KEY", "")
27
+
28
+ prompt_text = """
29
+ {
30
+ "36": {
31
+ "inputs": {
32
+ "clip_name1": "t5xxl_fp16.safetensors",
33
+ "clip_name2": "clip_l.safetensors",
34
+ "type": "flux"
35
+ },
36
+ "class_type": "BizyAir_DualCLIPLoader",
37
+ "_meta": {
38
+ "title": "☁️BizyAir DualCLIPLoader"
39
+ }
40
+ },
41
+ "37": {
42
+ "inputs": {
43
+ "text": "close up photo of a rabbit, forest in spring, haze, halation, bloom, dramatic atmosphere, centred, rule of thirds, 200mm 1.4f macro shot",
44
+ "clip": [
45
+ "36",
46
+ 0
47
+ ]
48
+ },
49
+ "class_type": "BizyAir_CLIPTextEncode",
50
+ "_meta": {
51
+ "title": "☁️BizyAir CLIP Text Encode (Prompt)"
52
+ }
53
+ },
54
+ "47": {
55
+ "inputs": {
56
+ "model": [
57
+ "48",
58
+ 0
59
+ ],
60
+ "conditioning": [
61
+ "37",
62
+ 0
63
+ ]
64
+ },
65
+ "class_type": "BizyAir_BasicGuider",
66
+ "_meta": {
67
+ "title": "☁️BizyAir BasicGuider"
68
+ }
69
+ },
70
+ "48": {
71
+ "inputs": {
72
+ "unet_name": "flux/pixelwave-flux1-dev.safetensors",
73
+ "weight_dtype": "default"
74
+ },
75
+ "class_type": "BizyAir_UNETLoader",
76
+ "_meta": {
77
+ "title": "☁️BizyAir Load Diffusion Model"
78
+ }
79
+ },
80
+ "50": {
81
+ "inputs": {
82
+ "noise": [
83
+ "59",
84
+ 0
85
+ ],
86
+ "guider": [
87
+ "47",
88
+ 0
89
+ ],
90
+ "sampler": [
91
+ "60",
92
+ 0
93
+ ],
94
+ "sigmas": [
95
+ "58",
96
+ 0
97
+ ],
98
+ "latent_image": [
99
+ "66",
100
+ 0
101
+ ]
102
+ },
103
+ "class_type": "BizyAir_SamplerCustomAdvanced",
104
+ "_meta": {
105
+ "title": "☁️BizyAir SamplerCustomAdvanced"
106
+ }
107
+ },
108
+ "54": {
109
+ "inputs": {
110
+ "samples": [
111
+ "50",
112
+ 0
113
+ ],
114
+ "vae": [
115
+ "55",
116
+ 0
117
+ ]
118
+ },
119
+ "class_type": "BizyAir_VAEDecode",
120
+ "_meta": {
121
+ "title": "☁️BizyAir VAE Decode"
122
+ }
123
+ },
124
+ "55": {
125
+ "inputs": {
126
+ "vae_name": "flux/ae.sft"
127
+ },
128
+ "class_type": "BizyAir_VAELoader",
129
+ "_meta": {
130
+ "title": "☁️BizyAir Load VAE"
131
+ }
132
+ },
133
+ "56": {
134
+ "inputs": {
135
+ "images": [
136
+ "54",
137
+ 0
138
+ ]
139
+ },
140
+ "class_type": "PreviewImage",
141
+ "_meta": {
142
+ "title": "预览图像"
143
+ }
144
+ },
145
+ "58": {
146
+ "inputs": {
147
+ "scheduler": "simple",
148
+ "steps": 20,
149
+ "denoise": 1,
150
+ "model": [
151
+ "48",
152
+ 0
153
+ ]
154
+ },
155
+ "class_type": "BizyAir_BasicScheduler",
156
+ "_meta": {
157
+ "title": "☁️BizyAir BasicScheduler"
158
+ }
159
+ },
160
+ "59": {
161
+ "inputs": {
162
+ "noise_seed": 0
163
+ },
164
+ "class_type": "BizyAir_RandomNoise",
165
+ "_meta": {
166
+ "title": "☁️BizyAir RandomNoise"
167
+ }
168
+ },
169
+ "60": {
170
+ "inputs": {
171
+ "sampler_name": "euler"
172
+ },
173
+ "class_type": "BizyAir_KSamplerSelect",
174
+ "_meta": {
175
+ "title": "☁️BizyAir KSamplerSelect"
176
+ }
177
+ },
178
+ "66": {
179
+ "inputs": {
180
+ "width": 1024,
181
+ "height": 1024,
182
+ "batch_size": 1
183
+ },
184
+ "class_type": "EmptySD3LatentImage",
185
+ "_meta": {
186
+ "title": "空Latent图像(SD3)"
187
+ }
188
+ }
189
+ }
190
+ """
191
+
192
+ def queue_prompt(prompt):
193
+ p = {"prompt": prompt}
194
+ data = json.dumps(p).encode('utf-8')
195
+ req = request.Request("http://127.0.0.1:9111/prompt", data=data)
196
+ request.urlopen(req)
197
+
198
+
199
+ prompt = json.loads(prompt_text)
200
+ param_node = {
201
+ "inputs": {},
202
+ "class_type": "BizyAir_PassParameter",
203
+ "_meta": {
204
+ "title": "☁️BizyAir PassParameter",
205
+ "api_key": BIZYAIR_API_KEY,
206
+ "prompt_id": "a-unique-prompt-id"
207
+ }
208
+ }
209
+ prompt["bizyair_magic_node"]=param_node
210
+ queue_prompt(prompt)
211
+ ```