bizyengine 1.2.68__py3-none-any.whl → 1.2.69__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/bizyair_extras/__init__.py +1 -5
- bizyengine/bizyair_extras/third_party_api/__init__.py +15 -0
- bizyengine/bizyair_extras/third_party_api/nodes_doubao.py +404 -0
- bizyengine/bizyair_extras/third_party_api/nodes_flux.py +173 -0
- bizyengine/bizyair_extras/third_party_api/nodes_gemini.py +403 -0
- bizyengine/bizyair_extras/third_party_api/nodes_gpt.py +101 -0
- bizyengine/bizyair_extras/third_party_api/nodes_hailuo.py +115 -0
- bizyengine/bizyair_extras/third_party_api/nodes_kling.py +404 -0
- bizyengine/bizyair_extras/third_party_api/nodes_sora.py +218 -0
- bizyengine/bizyair_extras/third_party_api/nodes_veo3.py +193 -0
- bizyengine/bizyair_extras/third_party_api/nodes_wan_api.py +198 -0
- bizyengine/bizyair_extras/third_party_api/trd_nodes_base.py +182 -0
- bizyengine/core/__init__.py +1 -0
- bizyengine/version.txt +1 -1
- {bizyengine-1.2.68.dist-info → bizyengine-1.2.69.dist-info}/METADATA +2 -2
- {bizyengine-1.2.68.dist-info → bizyengine-1.2.69.dist-info}/RECORD +18 -12
- bizyengine/bizyair_extras/nodes_gemini.py +0 -605
- bizyengine/bizyair_extras/nodes_seedream.py +0 -192
- bizyengine/bizyair_extras/nodes_sora2.py +0 -217
- bizyengine/bizyair_extras/nodes_veo3.py +0 -294
- bizyengine/bizyair_extras/nodes_wan_api.py +0 -299
- {bizyengine-1.2.68.dist-info → bizyengine-1.2.69.dist-info}/WHEEL +0 -0
- {bizyengine-1.2.68.dist-info → bizyengine-1.2.69.dist-info}/top_level.txt +0 -0
|
@@ -10,7 +10,6 @@ modules = [
|
|
|
10
10
|
".nodes_dataset",
|
|
11
11
|
".nodes_differential_diffusion",
|
|
12
12
|
".nodes_flux",
|
|
13
|
-
".nodes_gemini",
|
|
14
13
|
".nodes_hunyuan3d",
|
|
15
14
|
".nodes_image_utils",
|
|
16
15
|
".nodes_ip2p",
|
|
@@ -22,19 +21,16 @@ modules = [
|
|
|
22
21
|
".nodes_reactor",
|
|
23
22
|
".nodes_sam2",
|
|
24
23
|
".nodes_sd3",
|
|
25
|
-
".nodes_seedream",
|
|
26
24
|
".nodes_segment_anything",
|
|
27
25
|
".nodes_testing_utils",
|
|
28
26
|
".nodes_trellis",
|
|
29
27
|
".nodes_ultimatesdupscale",
|
|
30
28
|
".nodes_upscale_model",
|
|
31
29
|
".nodes_utils",
|
|
32
|
-
".nodes_wan_api",
|
|
33
30
|
".nodes_wan_i2v",
|
|
34
31
|
".nodes_wan_video",
|
|
35
32
|
".route_bizyair_tools",
|
|
36
|
-
".
|
|
37
|
-
".nodes_sora2",
|
|
33
|
+
".third_party_api",
|
|
38
34
|
]
|
|
39
35
|
from bizyengine.core.common.utils import safe_star_import
|
|
40
36
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
modules = [
|
|
2
|
+
".nodes_hailuo",
|
|
3
|
+
".nodes_gemini",
|
|
4
|
+
".nodes_gpt",
|
|
5
|
+
".nodes_kling",
|
|
6
|
+
".nodes_doubao",
|
|
7
|
+
".nodes_flux",
|
|
8
|
+
".nodes_sora",
|
|
9
|
+
".nodes_veo3",
|
|
10
|
+
".nodes_wan_api",
|
|
11
|
+
]
|
|
12
|
+
from bizyengine.core.common.utils import safe_star_import
|
|
13
|
+
|
|
14
|
+
for mod in modules:
|
|
15
|
+
safe_star_import(mod, package=__package__)
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
from bizyairsdk import tensor_to_bytesio
|
|
2
|
+
|
|
3
|
+
from .trd_nodes_base import BizyAirTrdApiBaseNode
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Seedream4(BizyAirTrdApiBaseNode):
|
|
7
|
+
RETURN_TYPES = ("IMAGE",)
|
|
8
|
+
RETURN_NAMES = ("images",)
|
|
9
|
+
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
10
|
+
NODE_DISPLAY_NAME = "Seedream4"
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def INPUT_TYPES(s):
|
|
14
|
+
return {
|
|
15
|
+
"required": {
|
|
16
|
+
"prompt": (
|
|
17
|
+
"STRING",
|
|
18
|
+
{
|
|
19
|
+
"multiline": True,
|
|
20
|
+
"default": "",
|
|
21
|
+
},
|
|
22
|
+
),
|
|
23
|
+
"size": (
|
|
24
|
+
[
|
|
25
|
+
"1K Square (1024x1024)",
|
|
26
|
+
"2K Square (2048x2048)",
|
|
27
|
+
"4K Square (4096x4096)",
|
|
28
|
+
"HD 16:9 (1920x1080)",
|
|
29
|
+
"2K 16:9 (2560x1440)",
|
|
30
|
+
"4K 16:9 (3840x2160)",
|
|
31
|
+
"Portrait 9:16 (1080x1920)",
|
|
32
|
+
"Portrait 3:4 (1536x2048)",
|
|
33
|
+
"Landscape 4:3 (2048x1536)",
|
|
34
|
+
"Ultra-wide 21:9 (3440x1440)",
|
|
35
|
+
"Custom",
|
|
36
|
+
],
|
|
37
|
+
{
|
|
38
|
+
"default": "HD 16:9 (1920x1080)",
|
|
39
|
+
},
|
|
40
|
+
),
|
|
41
|
+
"custom_width": ("INT", {"default": 1920, "min": 1024, "max": 4096}),
|
|
42
|
+
"custom_height": ("INT", {"default": 1080, "min": 1024, "max": 4096}),
|
|
43
|
+
"model": (
|
|
44
|
+
["doubao-seedream-4-0-250828"],
|
|
45
|
+
{"default": "doubao-seedream-4-0-250828"},
|
|
46
|
+
),
|
|
47
|
+
},
|
|
48
|
+
"optional": {
|
|
49
|
+
"image": ("IMAGE",),
|
|
50
|
+
"image2": ("IMAGE",),
|
|
51
|
+
"image3": ("IMAGE",),
|
|
52
|
+
"image4": ("IMAGE",),
|
|
53
|
+
"image5": ("IMAGE",),
|
|
54
|
+
"image6": ("IMAGE",),
|
|
55
|
+
"image7": ("IMAGE",),
|
|
56
|
+
"image8": ("IMAGE",),
|
|
57
|
+
"image9": ("IMAGE",),
|
|
58
|
+
"image10": ("IMAGE",),
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
63
|
+
model = kwargs.get("model", "doubao-seedream-4-0-250828")
|
|
64
|
+
prompt = kwargs.get("prompt", "")
|
|
65
|
+
size = kwargs.get("size", "1K Square (1024x1024)")
|
|
66
|
+
|
|
67
|
+
match size:
|
|
68
|
+
case "1K Square (1024x1024)":
|
|
69
|
+
width = 1024
|
|
70
|
+
height = 1024
|
|
71
|
+
case "2K Square (2048x2048)":
|
|
72
|
+
width = 2048
|
|
73
|
+
height = 2048
|
|
74
|
+
case "4K Square (4096x4096)":
|
|
75
|
+
width = 4096
|
|
76
|
+
height = 4096
|
|
77
|
+
case "HD 16:9 (1920x1080)":
|
|
78
|
+
width = 1920
|
|
79
|
+
height = 1080
|
|
80
|
+
case "2K 16:9 (2560x1440)":
|
|
81
|
+
width = 2560
|
|
82
|
+
height = 1440
|
|
83
|
+
case "4K 16:9 (3840x2160)":
|
|
84
|
+
width = 3840
|
|
85
|
+
height = 2160
|
|
86
|
+
case "Portrait 9:16 (1080x1920)":
|
|
87
|
+
width = 1080
|
|
88
|
+
height = 1920
|
|
89
|
+
case "Portrait 3:4 (1536x2048)":
|
|
90
|
+
width = 1536
|
|
91
|
+
height = 2048
|
|
92
|
+
case "Landscape 4:3 (2048x1536)":
|
|
93
|
+
width = 2048
|
|
94
|
+
height = 1536
|
|
95
|
+
case "Ultra-wide 21:9 (3440x1440)":
|
|
96
|
+
width = 3440
|
|
97
|
+
height = 1440
|
|
98
|
+
case "Custom":
|
|
99
|
+
width = kwargs.get("custom_width", 1920)
|
|
100
|
+
height = kwargs.get("custom_height", 1080)
|
|
101
|
+
|
|
102
|
+
case _:
|
|
103
|
+
raise ValueError(f"Invalid size: {size}")
|
|
104
|
+
|
|
105
|
+
sizeStr = f"{width}x{height}"
|
|
106
|
+
|
|
107
|
+
images = []
|
|
108
|
+
total_size = 0
|
|
109
|
+
for i, img in enumerate(
|
|
110
|
+
[
|
|
111
|
+
kwargs.get("image", None),
|
|
112
|
+
kwargs.get("image2", None),
|
|
113
|
+
kwargs.get("image3", None),
|
|
114
|
+
kwargs.get("image4", None),
|
|
115
|
+
kwargs.get("image5", None),
|
|
116
|
+
kwargs.get("image6", None),
|
|
117
|
+
kwargs.get("image7", None),
|
|
118
|
+
kwargs.get("image8", None),
|
|
119
|
+
kwargs.get("image9", None),
|
|
120
|
+
kwargs.get("image10", None),
|
|
121
|
+
],
|
|
122
|
+
1,
|
|
123
|
+
):
|
|
124
|
+
if img is not None:
|
|
125
|
+
# 都当作PNG就行
|
|
126
|
+
bio = tensor_to_bytesio(image=img, total_pixels=4096 * 4096)
|
|
127
|
+
length = bio.getbuffer().nbytes
|
|
128
|
+
if length > 10 * 1024 * 1024:
|
|
129
|
+
raise ValueError(
|
|
130
|
+
"Image size is too large, Seedream 4.0 only supports up to 10MB"
|
|
131
|
+
)
|
|
132
|
+
total_size += length
|
|
133
|
+
if total_size > 50 * 1024 * 1024:
|
|
134
|
+
raise ValueError(
|
|
135
|
+
"Total size of images is too large, BizyAir only supports up to 50MB"
|
|
136
|
+
)
|
|
137
|
+
images.append(self.upload_file(bio, f"{prompt_id}_{i}.png", headers))
|
|
138
|
+
|
|
139
|
+
data = {
|
|
140
|
+
"prompt": prompt,
|
|
141
|
+
"size": sizeStr,
|
|
142
|
+
"image": images,
|
|
143
|
+
"model": model,
|
|
144
|
+
"watermark": False,
|
|
145
|
+
"response_format": "url",
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return data, model
|
|
149
|
+
|
|
150
|
+
def handle_outputs(self, outputs):
|
|
151
|
+
images = self.combine_images(outputs[1])
|
|
152
|
+
return (images,)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class Seededit3(BizyAirTrdApiBaseNode):
|
|
156
|
+
RETURN_TYPES = ("IMAGE",)
|
|
157
|
+
RETURN_NAMES = ("image",)
|
|
158
|
+
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
159
|
+
NODE_DISPLAY_NAME = "Seededit3"
|
|
160
|
+
|
|
161
|
+
@classmethod
|
|
162
|
+
def INPUT_TYPES(cls):
|
|
163
|
+
return {
|
|
164
|
+
"required": {
|
|
165
|
+
"image": ("IMAGE",),
|
|
166
|
+
"prompt": (
|
|
167
|
+
"STRING",
|
|
168
|
+
{
|
|
169
|
+
"multiline": True,
|
|
170
|
+
"default": "",
|
|
171
|
+
},
|
|
172
|
+
),
|
|
173
|
+
"model": (
|
|
174
|
+
["doubao-seededit-3-0-i2i-250628"],
|
|
175
|
+
{"default": "doubao-seededit-3-0-i2i-250628"},
|
|
176
|
+
),
|
|
177
|
+
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
178
|
+
"guidance_scale": ("FLOAT", {"default": 5.5, "min": 1.0, "max": 10.0}),
|
|
179
|
+
},
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
183
|
+
model = kwargs.get("model", "doubao-seededit-3-0-i2i-250628")
|
|
184
|
+
prompt = kwargs.get("prompt", "")
|
|
185
|
+
image = kwargs.get("image", None)
|
|
186
|
+
seed = kwargs.get("seed", -1)
|
|
187
|
+
guidance_scale = kwargs.get("guidance_scale", 5.5)
|
|
188
|
+
if image is None:
|
|
189
|
+
raise ValueError("Image is required")
|
|
190
|
+
# 上传图片
|
|
191
|
+
image_url = self.upload_file(
|
|
192
|
+
tensor_to_bytesio(image=image, total_pixels=4096 * 4096),
|
|
193
|
+
f"{prompt_id}.png",
|
|
194
|
+
headers,
|
|
195
|
+
)
|
|
196
|
+
data = {
|
|
197
|
+
"prompt": prompt,
|
|
198
|
+
"model": model,
|
|
199
|
+
"image": image_url,
|
|
200
|
+
"seed": seed,
|
|
201
|
+
"guidance_scale": guidance_scale,
|
|
202
|
+
"size": "adaptive",
|
|
203
|
+
"response_format": "url",
|
|
204
|
+
"watermark": False,
|
|
205
|
+
}
|
|
206
|
+
return data, model
|
|
207
|
+
|
|
208
|
+
def handle_outputs(self, outputs):
|
|
209
|
+
images = self.combine_images(outputs[1])
|
|
210
|
+
return (images,)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class Seedance_1_0_T2V_API(BizyAirTrdApiBaseNode):
|
|
214
|
+
RETURN_TYPES = ("VIDEO",)
|
|
215
|
+
RETURN_NAMES = ("video",)
|
|
216
|
+
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
217
|
+
NODE_DISPLAY_NAME = "Seedance 1.0 Pro Text To Video"
|
|
218
|
+
|
|
219
|
+
@classmethod
|
|
220
|
+
def INPUT_TYPES(cls):
|
|
221
|
+
return {
|
|
222
|
+
"required": {
|
|
223
|
+
"prompt": (
|
|
224
|
+
"STRING",
|
|
225
|
+
{
|
|
226
|
+
"multiline": True,
|
|
227
|
+
"default": "",
|
|
228
|
+
},
|
|
229
|
+
),
|
|
230
|
+
"model": (
|
|
231
|
+
[
|
|
232
|
+
"doubao-seedance-1-0-pro-250528",
|
|
233
|
+
"doubao-seedance-1-0-pro-fast-251015",
|
|
234
|
+
],
|
|
235
|
+
{"default": "doubao-seedance-1-0-pro-250528"},
|
|
236
|
+
),
|
|
237
|
+
"resolution": (
|
|
238
|
+
["480p", "720p", "1080p"],
|
|
239
|
+
{
|
|
240
|
+
"default": "1080p",
|
|
241
|
+
"tooltip": "分辨率+比例共同决定视频尺寸,具体尺寸请参考官方文档说明",
|
|
242
|
+
},
|
|
243
|
+
),
|
|
244
|
+
"ratio": (
|
|
245
|
+
["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "adaptive"],
|
|
246
|
+
{
|
|
247
|
+
"default": "adaptive",
|
|
248
|
+
"tooltip": "比例+分辨率共同决定视频尺寸,具体尺寸请参考官方文档说明",
|
|
249
|
+
},
|
|
250
|
+
),
|
|
251
|
+
"duration": ("INT", {"default": 12, "min": 2, "max": 12}),
|
|
252
|
+
"fps": (
|
|
253
|
+
[24],
|
|
254
|
+
{
|
|
255
|
+
"default": 24,
|
|
256
|
+
"tooltip": "帧率固定24",
|
|
257
|
+
},
|
|
258
|
+
),
|
|
259
|
+
"camerafixed": (
|
|
260
|
+
"BOOLEAN",
|
|
261
|
+
{
|
|
262
|
+
"default": False,
|
|
263
|
+
"tooltip": "平台可能在提示词中追加固定摄像机指令(效果不保证) ",
|
|
264
|
+
},
|
|
265
|
+
),
|
|
266
|
+
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
267
|
+
},
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
271
|
+
model = kwargs.get("model", "doubao-seedance-1-0-pro-250528")
|
|
272
|
+
prompt = kwargs.get("prompt", "")
|
|
273
|
+
resolution = kwargs.get("resolution", "1080p")
|
|
274
|
+
ratio = kwargs.get("ratio", "adaptive")
|
|
275
|
+
duration = kwargs.get("duration", 12)
|
|
276
|
+
camerafixed = kwargs.get("camerafixed", False)
|
|
277
|
+
seed = kwargs.get("seed", -1)
|
|
278
|
+
if prompt is None or prompt.strip() == "":
|
|
279
|
+
raise ValueError("Prompt is required")
|
|
280
|
+
data = {
|
|
281
|
+
"prompt": prompt,
|
|
282
|
+
"model": model,
|
|
283
|
+
"resolution": resolution,
|
|
284
|
+
"ratio": ratio,
|
|
285
|
+
"duration": duration,
|
|
286
|
+
"camerafixed": camerafixed,
|
|
287
|
+
"seed": seed,
|
|
288
|
+
"watermark": False,
|
|
289
|
+
"fps": 24,
|
|
290
|
+
}
|
|
291
|
+
return data, "doubao-seedance-1-0"
|
|
292
|
+
|
|
293
|
+
def handle_outputs(self, outputs):
|
|
294
|
+
return (outputs[0][0],)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
class Seedance_1_0_I2V_API(BizyAirTrdApiBaseNode):
|
|
298
|
+
RETURN_TYPES = ("VIDEO",)
|
|
299
|
+
RETURN_NAMES = ("video",)
|
|
300
|
+
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
301
|
+
NODE_DISPLAY_NAME = "Seedance 1.0 Pro Image To Video"
|
|
302
|
+
|
|
303
|
+
@classmethod
|
|
304
|
+
def INPUT_TYPES(cls):
|
|
305
|
+
return {
|
|
306
|
+
"required": {
|
|
307
|
+
"first_frame_image": ("IMAGE",),
|
|
308
|
+
"prompt": (
|
|
309
|
+
"STRING",
|
|
310
|
+
{
|
|
311
|
+
"multiline": True,
|
|
312
|
+
"default": "",
|
|
313
|
+
},
|
|
314
|
+
),
|
|
315
|
+
"model": (
|
|
316
|
+
[
|
|
317
|
+
"doubao-seedance-1-0-pro-250528",
|
|
318
|
+
"doubao-seedance-1-0-pro-fast-251015",
|
|
319
|
+
],
|
|
320
|
+
{"default": "doubao-seedance-1-0-pro-250528"},
|
|
321
|
+
),
|
|
322
|
+
"resolution": (
|
|
323
|
+
["480p", "720p", "1080p"],
|
|
324
|
+
{
|
|
325
|
+
"default": "1080p",
|
|
326
|
+
"tooltip": "分辨率+比例共同决定视频尺寸,具体尺寸请参考官方文档说明",
|
|
327
|
+
},
|
|
328
|
+
),
|
|
329
|
+
"ratio": (
|
|
330
|
+
["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "adaptive"],
|
|
331
|
+
{
|
|
332
|
+
"default": "adaptive",
|
|
333
|
+
"tooltip": "比例+分辨率共同决定视频尺寸,具体尺寸请参考官方文档说明",
|
|
334
|
+
},
|
|
335
|
+
),
|
|
336
|
+
"duration": ("INT", {"default": 12, "min": 2, "max": 12}),
|
|
337
|
+
"fps": (
|
|
338
|
+
[24],
|
|
339
|
+
{
|
|
340
|
+
"default": 24,
|
|
341
|
+
"tooltip": "帧率固定24",
|
|
342
|
+
},
|
|
343
|
+
),
|
|
344
|
+
"camerafixed": (
|
|
345
|
+
"BOOLEAN",
|
|
346
|
+
{
|
|
347
|
+
"default": False,
|
|
348
|
+
"tooltip": "平台可能在提示词中追加固定摄像机指令(效果不保证) ",
|
|
349
|
+
},
|
|
350
|
+
),
|
|
351
|
+
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
|
|
352
|
+
},
|
|
353
|
+
"optional": {
|
|
354
|
+
"last_frame_image": ("IMAGE",),
|
|
355
|
+
},
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
359
|
+
model = kwargs.get("model", "doubao-seedance-1-0-pro-250528")
|
|
360
|
+
prompt = kwargs.get("prompt", "")
|
|
361
|
+
resolution = kwargs.get("resolution", "1080p")
|
|
362
|
+
ratio = kwargs.get("ratio", "adaptive")
|
|
363
|
+
duration = kwargs.get("duration", 12)
|
|
364
|
+
camerafixed = kwargs.get("camerafixed", False)
|
|
365
|
+
seed = kwargs.get("seed", -1)
|
|
366
|
+
first_frame_image = kwargs.get("first_frame_image", None)
|
|
367
|
+
last_frame_image = kwargs.get("last_frame_image", None)
|
|
368
|
+
if first_frame_image is None:
|
|
369
|
+
raise ValueError("First frame image is required")
|
|
370
|
+
if (
|
|
371
|
+
last_frame_image is not None
|
|
372
|
+
and model == "doubao-seedance-1-0-pro-fast-251015"
|
|
373
|
+
):
|
|
374
|
+
raise ValueError(
|
|
375
|
+
"Last frame image is not supported for doubao-seedance-1-0-pro-fast-251015"
|
|
376
|
+
)
|
|
377
|
+
first_frame_image_url = self.upload_file(
|
|
378
|
+
tensor_to_bytesio(image=first_frame_image, total_pixels=4096 * 4096),
|
|
379
|
+
f"{prompt_id}_first.png",
|
|
380
|
+
headers,
|
|
381
|
+
)
|
|
382
|
+
data = {
|
|
383
|
+
"prompt": prompt,
|
|
384
|
+
"model": model,
|
|
385
|
+
"resolution": resolution,
|
|
386
|
+
"ratio": ratio,
|
|
387
|
+
"duration": duration,
|
|
388
|
+
"camerafixed": camerafixed,
|
|
389
|
+
"seed": seed,
|
|
390
|
+
"watermark": False,
|
|
391
|
+
"fps": 24,
|
|
392
|
+
"first_frame_image": first_frame_image_url,
|
|
393
|
+
}
|
|
394
|
+
if last_frame_image is not None:
|
|
395
|
+
last_frame_image_url = self.upload_file(
|
|
396
|
+
tensor_to_bytesio(image=last_frame_image, total_pixels=4096 * 4096),
|
|
397
|
+
f"{prompt_id}_last.png",
|
|
398
|
+
headers,
|
|
399
|
+
)
|
|
400
|
+
data["last_frame_image"] = last_frame_image_url
|
|
401
|
+
return data, "doubao-seedance-1-0"
|
|
402
|
+
|
|
403
|
+
def handle_outputs(self, outputs):
|
|
404
|
+
return (outputs[0][0],)
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
from bizyairsdk import tensor_to_bytesio
|
|
2
|
+
|
|
3
|
+
from .trd_nodes_base import BizyAirTrdApiBaseNode
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Flux_Kontext_API(BizyAirTrdApiBaseNode):
|
|
7
|
+
NODE_DISPLAY_NAME = "Flux Kontext API"
|
|
8
|
+
RETURN_TYPES = ("IMAGE",)
|
|
9
|
+
RETURN_NAMES = ("image",)
|
|
10
|
+
CATEGORY = "☁️BizyAir/External APIs/Flux"
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def INPUT_TYPES(cls):
|
|
14
|
+
return {
|
|
15
|
+
"required": {
|
|
16
|
+
"prompt": (
|
|
17
|
+
"STRING",
|
|
18
|
+
{
|
|
19
|
+
"multiline": True,
|
|
20
|
+
"default": "",
|
|
21
|
+
},
|
|
22
|
+
),
|
|
23
|
+
"model": (
|
|
24
|
+
["flux-kontext-pro", "flux-kontext-max"],
|
|
25
|
+
{"default": "flux-kontext-pro"},
|
|
26
|
+
),
|
|
27
|
+
"aspect_ratio": (
|
|
28
|
+
["21:9", "16:9", "4:3", "1:1", "3:4", "9:16"],
|
|
29
|
+
{"default": "16:9"},
|
|
30
|
+
),
|
|
31
|
+
"seed": ("INT", {"default": 0, "min": 0, "max": 2147483647}),
|
|
32
|
+
},
|
|
33
|
+
"optional": {
|
|
34
|
+
"image": ("IMAGE",),
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
39
|
+
prompt = kwargs.get("prompt", "")
|
|
40
|
+
image = kwargs.get("image", None)
|
|
41
|
+
model = kwargs.get("model", "flux-kontext-pro")
|
|
42
|
+
aspect_ratio = kwargs.get("aspect_ratio", "16:9")
|
|
43
|
+
seed = kwargs.get("seed", 0)
|
|
44
|
+
data = {
|
|
45
|
+
"prompt": prompt,
|
|
46
|
+
"model": model,
|
|
47
|
+
"aspect_ratio": aspect_ratio,
|
|
48
|
+
"seed": seed,
|
|
49
|
+
}
|
|
50
|
+
if image is not None:
|
|
51
|
+
image_url = self.upload_file(
|
|
52
|
+
tensor_to_bytesio(image=image, total_pixels=4096 * 4096),
|
|
53
|
+
f"{prompt_id}.png",
|
|
54
|
+
headers,
|
|
55
|
+
)
|
|
56
|
+
data["image"] = image_url
|
|
57
|
+
return data, "flux-kontext"
|
|
58
|
+
|
|
59
|
+
def handle_outputs(self, outputs):
|
|
60
|
+
images = self.combine_images(outputs[1])
|
|
61
|
+
return (images,)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class Flux_2_API(BizyAirTrdApiBaseNode):
|
|
65
|
+
NODE_DISPLAY_NAME = "Flux 2 API"
|
|
66
|
+
RETURN_TYPES = ("IMAGE",)
|
|
67
|
+
RETURN_NAMES = ("image",)
|
|
68
|
+
CATEGORY = "☁️BizyAir/External APIs/Flux"
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
def INPUT_TYPES(cls):
|
|
72
|
+
return {
|
|
73
|
+
"required": {
|
|
74
|
+
"prompt": (
|
|
75
|
+
"STRING",
|
|
76
|
+
{
|
|
77
|
+
"multiline": True,
|
|
78
|
+
"default": "",
|
|
79
|
+
},
|
|
80
|
+
),
|
|
81
|
+
"model": (
|
|
82
|
+
["flux-2-pro", "flux-2-flex"],
|
|
83
|
+
{"default": "flux-2-pro"},
|
|
84
|
+
),
|
|
85
|
+
"seed": ("INT", {"default": 0, "min": 0, "max": 2147483647}),
|
|
86
|
+
"width": (
|
|
87
|
+
"INT",
|
|
88
|
+
{
|
|
89
|
+
"default": 1024,
|
|
90
|
+
"min": 0,
|
|
91
|
+
"step": 16,
|
|
92
|
+
"tooltip": "必须为16的倍数,0代表使用输入图片宽度",
|
|
93
|
+
},
|
|
94
|
+
),
|
|
95
|
+
"height": (
|
|
96
|
+
"INT",
|
|
97
|
+
{
|
|
98
|
+
"default": 1024,
|
|
99
|
+
"min": 0,
|
|
100
|
+
"step": 16,
|
|
101
|
+
"tooltip": "必须为16的倍数,0代表使用输入图片高度",
|
|
102
|
+
},
|
|
103
|
+
),
|
|
104
|
+
"safety_tolerance": (
|
|
105
|
+
"INT",
|
|
106
|
+
{"min": 0, "max": 5, "default": 2, "tooltip": "值越大越宽松"},
|
|
107
|
+
),
|
|
108
|
+
"guidance": (
|
|
109
|
+
"FLOAT",
|
|
110
|
+
{"min": 1.5, "max": 10, "default": 4.5, "tooltip": "仅flex支持"},
|
|
111
|
+
),
|
|
112
|
+
"steps": (
|
|
113
|
+
"INT",
|
|
114
|
+
{"min": 1, "max": 50, "default": 50, "tooltip": "仅flex支持"},
|
|
115
|
+
),
|
|
116
|
+
},
|
|
117
|
+
"optional": {
|
|
118
|
+
"images": ("IMAGE",),
|
|
119
|
+
},
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
def handle_inputs(self, headers, prompt_id, **kwargs):
|
|
123
|
+
images = kwargs.get("images", None)
|
|
124
|
+
prompt = kwargs.get("prompt", "")
|
|
125
|
+
model = kwargs.get("model", "flux-2-pro")
|
|
126
|
+
width = kwargs.get("width", 1024)
|
|
127
|
+
height = kwargs.get("height", 1024)
|
|
128
|
+
safety_tolerance = kwargs.get("safety_tolerance", 2)
|
|
129
|
+
guidance = kwargs.get("guidance", 4.5)
|
|
130
|
+
steps = kwargs.get("steps", 50)
|
|
131
|
+
seed = kwargs.get("seed", 0)
|
|
132
|
+
if images is not None and len(images) > 8 and model == "flux-2-pro":
|
|
133
|
+
raise ValueError("Maximum number of images is 8 for flux-2-pro")
|
|
134
|
+
if images is not None and len(images) > 10 and model == "flux-2-flex":
|
|
135
|
+
raise ValueError("Maximum number of images is 10 for flux-2-flex")
|
|
136
|
+
if width < 0 or height < 0:
|
|
137
|
+
raise ValueError(
|
|
138
|
+
"Width and height must be greater than 0, or supply 0 value to use input image's original size"
|
|
139
|
+
)
|
|
140
|
+
if safety_tolerance < 0 or safety_tolerance > 6:
|
|
141
|
+
raise ValueError("Safety tolerance must be between 0 and 6")
|
|
142
|
+
if guidance < 1.5 or guidance > 10:
|
|
143
|
+
raise ValueError("Guidance must be between 1.5 and 10")
|
|
144
|
+
if steps < 1 or steps > 50:
|
|
145
|
+
raise ValueError("Steps must be between 1 and 50")
|
|
146
|
+
parts = []
|
|
147
|
+
for batch_number, img in enumerate(images if images is not None else []):
|
|
148
|
+
if img is not None:
|
|
149
|
+
url = self.upload_file(
|
|
150
|
+
tensor_to_bytesio(image=img, total_pixels=4096 * 4096),
|
|
151
|
+
f"{prompt_id}_{batch_number}.png",
|
|
152
|
+
headers,
|
|
153
|
+
)
|
|
154
|
+
parts.append(url)
|
|
155
|
+
data = {
|
|
156
|
+
"prompt": prompt,
|
|
157
|
+
"model": model,
|
|
158
|
+
"safety_tolerance": safety_tolerance,
|
|
159
|
+
"guidance": guidance,
|
|
160
|
+
"steps": steps,
|
|
161
|
+
"seed": seed,
|
|
162
|
+
}
|
|
163
|
+
if width > 0:
|
|
164
|
+
data["width"] = width
|
|
165
|
+
if height > 0:
|
|
166
|
+
data["height"] = height
|
|
167
|
+
if len(parts) > 0:
|
|
168
|
+
data["urls"] = parts
|
|
169
|
+
return data, "flux-2"
|
|
170
|
+
|
|
171
|
+
def handle_outputs(self, outputs):
|
|
172
|
+
images = self.combine_images(outputs[1])
|
|
173
|
+
return (images,)
|