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
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import base64
|
|
2
|
-
import io
|
|
3
|
-
import json
|
|
4
|
-
import logging
|
|
5
|
-
import re
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
|
|
8
|
-
import requests
|
|
9
|
-
import torch
|
|
10
|
-
from bizyairsdk import bytesio_to_image_tensor, tensor_to_base64_string
|
|
11
|
-
|
|
12
|
-
from bizyengine.core import BizyAirBaseNode, pop_api_key_and_prompt_id
|
|
13
|
-
from bizyengine.core.common import client
|
|
14
|
-
from bizyengine.core.common.env_var import BIZYAIR_SERVER_ADDRESS
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def download_png(url: str) -> bytes:
|
|
18
|
-
"""下载 PNG 图片"""
|
|
19
|
-
resp = requests.get(url, stream=True, timeout=30)
|
|
20
|
-
resp.raise_for_status() # 非 2xx 会抛异常
|
|
21
|
-
return resp.content
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class Seedream4(BizyAirBaseNode):
|
|
25
|
-
def __init__(self):
|
|
26
|
-
pass
|
|
27
|
-
|
|
28
|
-
@classmethod
|
|
29
|
-
def INPUT_TYPES(s):
|
|
30
|
-
return {
|
|
31
|
-
"required": {
|
|
32
|
-
"prompt": (
|
|
33
|
-
"STRING",
|
|
34
|
-
{
|
|
35
|
-
"multiline": True,
|
|
36
|
-
"default": "",
|
|
37
|
-
},
|
|
38
|
-
),
|
|
39
|
-
"size": (
|
|
40
|
-
[
|
|
41
|
-
"1K Square (1024x1024)",
|
|
42
|
-
"2K Square (2048x2048)",
|
|
43
|
-
"4K Square (4096x4096)",
|
|
44
|
-
"HD 16:9 (1920x1080)",
|
|
45
|
-
"2K 16:9 (2560x1440)",
|
|
46
|
-
"4K 16:9 (3840x2160)",
|
|
47
|
-
"Portrait 9:16 (1080x1920)",
|
|
48
|
-
"Portrait 3:4 (1536x2048)",
|
|
49
|
-
"Landscape 4:3 (2048x1536)",
|
|
50
|
-
"Ultra-wide 21:9 (3440x1440)",
|
|
51
|
-
"Custom",
|
|
52
|
-
],
|
|
53
|
-
{
|
|
54
|
-
"default": "HD 16:9 (1920x1080)",
|
|
55
|
-
},
|
|
56
|
-
),
|
|
57
|
-
"custom_width": ("INT", {"default": 1920, "min": 1024, "max": 4096}),
|
|
58
|
-
"custom_height": ("INT", {"default": 1080, "min": 1024, "max": 4096}),
|
|
59
|
-
"model": (
|
|
60
|
-
["doubao-seedream-4-0-250828"],
|
|
61
|
-
{"default": "doubao-seedream-4-0-250828"},
|
|
62
|
-
),
|
|
63
|
-
},
|
|
64
|
-
"optional": {
|
|
65
|
-
"image": ("IMAGE",),
|
|
66
|
-
"image2": ("IMAGE",),
|
|
67
|
-
"image3": ("IMAGE",),
|
|
68
|
-
"image4": ("IMAGE",),
|
|
69
|
-
"image5": ("IMAGE",),
|
|
70
|
-
"image6": ("IMAGE",),
|
|
71
|
-
"image7": ("IMAGE",),
|
|
72
|
-
"image8": ("IMAGE",),
|
|
73
|
-
"image9": ("IMAGE",),
|
|
74
|
-
"image10": ("IMAGE",),
|
|
75
|
-
},
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
RETURN_TYPES = ("IMAGE",)
|
|
79
|
-
FUNCTION = "execute"
|
|
80
|
-
OUTPUT_NODE = False
|
|
81
|
-
CATEGORY = "☁️BizyAir/External APIs/Doubao"
|
|
82
|
-
|
|
83
|
-
def execute(self, **kwargs):
|
|
84
|
-
try:
|
|
85
|
-
model = kwargs.get("model", "doubao-seedream-4-0-250828")
|
|
86
|
-
url = f"{BIZYAIR_SERVER_ADDRESS}/proxy_inference/Doubao/{model}"
|
|
87
|
-
extra_data = pop_api_key_and_prompt_id(kwargs)
|
|
88
|
-
|
|
89
|
-
prompt = kwargs.get("prompt", "")
|
|
90
|
-
size = kwargs.get("size", "1K Square (1024x1024)")
|
|
91
|
-
|
|
92
|
-
match size:
|
|
93
|
-
case "1K Square (1024x1024)":
|
|
94
|
-
width = 1024
|
|
95
|
-
height = 1024
|
|
96
|
-
case "2K Square (2048x2048)":
|
|
97
|
-
width = 2048
|
|
98
|
-
height = 2048
|
|
99
|
-
case "4K Square (4096x4096)":
|
|
100
|
-
width = 4096
|
|
101
|
-
height = 4096
|
|
102
|
-
case "HD 16:9 (1920x1080)":
|
|
103
|
-
width = 1920
|
|
104
|
-
height = 1080
|
|
105
|
-
case "2K 16:9 (2560x1440)":
|
|
106
|
-
width = 2560
|
|
107
|
-
height = 1440
|
|
108
|
-
case "4K 16:9 (3840x2160)":
|
|
109
|
-
width = 3840
|
|
110
|
-
height = 2160
|
|
111
|
-
case "Portrait 9:16 (1080x1920)":
|
|
112
|
-
width = 1080
|
|
113
|
-
height = 1920
|
|
114
|
-
case "Portrait 3:4 (1536x2048)":
|
|
115
|
-
width = 1536
|
|
116
|
-
height = 2048
|
|
117
|
-
case "Landscape 4:3 (2048x1536)":
|
|
118
|
-
width = 2048
|
|
119
|
-
height = 1536
|
|
120
|
-
case "Ultra-wide 21:9 (3440x1440)":
|
|
121
|
-
width = 3440
|
|
122
|
-
height = 1440
|
|
123
|
-
case "Custom":
|
|
124
|
-
width = kwargs.get("custom_width", 1920)
|
|
125
|
-
height = kwargs.get("custom_height", 1080)
|
|
126
|
-
|
|
127
|
-
case _:
|
|
128
|
-
raise ValueError(f"Invalid size: {size}")
|
|
129
|
-
|
|
130
|
-
sizeStr = f"{width}x{height}"
|
|
131
|
-
|
|
132
|
-
images = []
|
|
133
|
-
total_size = 0
|
|
134
|
-
for _, img in enumerate(
|
|
135
|
-
[
|
|
136
|
-
kwargs.get("image", None),
|
|
137
|
-
kwargs.get("image2", None),
|
|
138
|
-
kwargs.get("image3", None),
|
|
139
|
-
kwargs.get("image4", None),
|
|
140
|
-
kwargs.get("image5", None),
|
|
141
|
-
kwargs.get("image6", None),
|
|
142
|
-
kwargs.get("image7", None),
|
|
143
|
-
kwargs.get("image8", None),
|
|
144
|
-
kwargs.get("image9", None),
|
|
145
|
-
kwargs.get("image10", None),
|
|
146
|
-
],
|
|
147
|
-
1,
|
|
148
|
-
):
|
|
149
|
-
if img is not None:
|
|
150
|
-
# 都当作PNG就行
|
|
151
|
-
b64_data = tensor_to_base64_string(img)
|
|
152
|
-
if len(b64_data) > 10 * 1024 * 1024:
|
|
153
|
-
raise ValueError(
|
|
154
|
-
"Image size is too large, Seedream 4.0 only supports up to 10MB"
|
|
155
|
-
)
|
|
156
|
-
images.append(f"data:image/png;base64,{b64_data}")
|
|
157
|
-
total_size += len(b64_data)
|
|
158
|
-
if total_size > 50 * 1024 * 1024:
|
|
159
|
-
raise ValueError(
|
|
160
|
-
"Total size of images is too large, BizyAir only supports up to 50MB"
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
data = {
|
|
164
|
-
"prompt": prompt,
|
|
165
|
-
"size": sizeStr,
|
|
166
|
-
"image": images,
|
|
167
|
-
"model": model,
|
|
168
|
-
"watermark": False,
|
|
169
|
-
"response_format": "url",
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
json_payload = json.dumps(data).encode("utf-8")
|
|
173
|
-
headers = client.headers(api_key=extra_data["api_key"])
|
|
174
|
-
headers["X-BIZYAIR-PROMPT-ID"] = extra_data["prompt_id"]
|
|
175
|
-
resp = client.send_request(
|
|
176
|
-
url=url,
|
|
177
|
-
data=json_payload,
|
|
178
|
-
headers=headers,
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
# 结果会包含图片URL,客户端这里负责下载
|
|
182
|
-
if not "data" in resp:
|
|
183
|
-
raise ValueError(f"Invalid response: {resp}")
|
|
184
|
-
if not "url" in resp["data"][0]:
|
|
185
|
-
raise ValueError(f"Invalid response: {resp}")
|
|
186
|
-
|
|
187
|
-
image_data = download_png(resp["data"][0]["url"])
|
|
188
|
-
return (bytesio_to_image_tensor(io.BytesIO(image_data)),)
|
|
189
|
-
|
|
190
|
-
except Exception as e:
|
|
191
|
-
logging.error(f"Seedream 4.0 API error: {e}")
|
|
192
|
-
raise e
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import io
|
|
2
|
-
import json
|
|
3
|
-
import logging
|
|
4
|
-
import time
|
|
5
|
-
|
|
6
|
-
import requests
|
|
7
|
-
from bizyairsdk import tensor_to_bytesio
|
|
8
|
-
from comfy_api.latest._input_impl import VideoFromFile
|
|
9
|
-
|
|
10
|
-
from bizyengine.bizyair_extras.nodes_veo3 import _GRSAI_FAILED_STATUS
|
|
11
|
-
from bizyengine.bizyair_extras.utils.audio import save_audio
|
|
12
|
-
from bizyengine.core import BizyAirBaseNode, pop_api_key_and_prompt_id
|
|
13
|
-
from bizyengine.core.common import client
|
|
14
|
-
from bizyengine.core.common.client import send_request
|
|
15
|
-
from bizyengine.core.common.env_var import BIZYAIR_X_SERVER
|
|
16
|
-
|
|
17
|
-
from .utils.aliyun_oss import parse_upload_token, upload_file_without_sdk
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def sora2_create_task_and_wait_for_completion(data, model, prompt, headers):
|
|
21
|
-
# 创建任务
|
|
22
|
-
create_task_url = f"{BIZYAIR_X_SERVER}/proxy_inference/GRSAI/{model}"
|
|
23
|
-
json_payload = json.dumps(data).encode("utf-8")
|
|
24
|
-
logging.debug(f"json_payload: {json_payload}")
|
|
25
|
-
create_api_resp = send_request(
|
|
26
|
-
url=create_task_url,
|
|
27
|
-
data=json_payload,
|
|
28
|
-
headers=headers,
|
|
29
|
-
)
|
|
30
|
-
logging.debug(f"create task api resp: {create_api_resp}")
|
|
31
|
-
|
|
32
|
-
# 检查任务创建是否成功
|
|
33
|
-
if (
|
|
34
|
-
"code" not in create_api_resp
|
|
35
|
-
or create_api_resp["code"] != 0
|
|
36
|
-
or "data" not in create_api_resp
|
|
37
|
-
or "id" not in create_api_resp["data"]
|
|
38
|
-
):
|
|
39
|
-
raise ValueError(f"Invalid response: {create_api_resp}")
|
|
40
|
-
|
|
41
|
-
# 轮询获取结果,最多等待1小时
|
|
42
|
-
task_id = create_api_resp["data"]["id"]
|
|
43
|
-
logging.info(f"Sora2 task created, task_id: {task_id}")
|
|
44
|
-
start_time = time.time()
|
|
45
|
-
status_url = f"{BIZYAIR_X_SERVER}/proxy_inference/GRSAI/{model}/{task_id}"
|
|
46
|
-
while time.time() - start_time < 3600:
|
|
47
|
-
time.sleep(10)
|
|
48
|
-
try:
|
|
49
|
-
status_api_resp = send_request(
|
|
50
|
-
method="GET",
|
|
51
|
-
url=status_url,
|
|
52
|
-
headers=headers,
|
|
53
|
-
)
|
|
54
|
-
logging.debug(f"status api resp: {status_api_resp}")
|
|
55
|
-
except Exception as e:
|
|
56
|
-
logging.error(f"Sora2 task {task_id} status api error: {e}")
|
|
57
|
-
continue
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
"data" in status_api_resp
|
|
61
|
-
and "status" in status_api_resp["data"]
|
|
62
|
-
and status_api_resp["data"]["status"] == "succeeded"
|
|
63
|
-
and "results" in status_api_resp["data"]
|
|
64
|
-
and len(status_api_resp["data"]["results"]) > 0
|
|
65
|
-
and "url" in status_api_resp["data"]["results"][0]
|
|
66
|
-
and status_api_resp["data"]["results"][0]["url"]
|
|
67
|
-
):
|
|
68
|
-
video_url = status_api_resp["data"]["results"][0]["url"]
|
|
69
|
-
logging.info(f"Sora2 task {task_id} success, video_url: {video_url}")
|
|
70
|
-
# 下载视频
|
|
71
|
-
video_resp = requests.get(video_url, stream=True, timeout=3600)
|
|
72
|
-
video_resp.raise_for_status() # 非 2xx 会抛异常
|
|
73
|
-
return (VideoFromFile(io.BytesIO(video_resp.content)),)
|
|
74
|
-
if (
|
|
75
|
-
"data" not in status_api_resp
|
|
76
|
-
or "status" not in status_api_resp["data"]
|
|
77
|
-
or "code" not in status_api_resp
|
|
78
|
-
or status_api_resp["code"] != 0
|
|
79
|
-
):
|
|
80
|
-
raise ValueError(f"Invalid response: {status_api_resp}")
|
|
81
|
-
if status_api_resp["data"]["status"] in _GRSAI_FAILED_STATUS:
|
|
82
|
-
raise ValueError(f"Sora2 task failed: {status_api_resp}")
|
|
83
|
-
logging.debug(
|
|
84
|
-
f"Sora2 task {task_id} status: {status_api_resp['data']['status']}"
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
raise ValueError(f"Sora2 task timed out, request ID: {task_id}")
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class Sora_V2_I2V_API(BizyAirBaseNode):
|
|
91
|
-
@classmethod
|
|
92
|
-
def INPUT_TYPES(cls):
|
|
93
|
-
return {
|
|
94
|
-
"required": {
|
|
95
|
-
"prompt": (
|
|
96
|
-
"STRING",
|
|
97
|
-
{
|
|
98
|
-
"multiline": True,
|
|
99
|
-
"default": "",
|
|
100
|
-
},
|
|
101
|
-
),
|
|
102
|
-
"image": ("IMAGE", {"tooltip": "首帧图片"}),
|
|
103
|
-
"model": (["sora-2"], {"default": "sora-2"}),
|
|
104
|
-
},
|
|
105
|
-
"optional": {
|
|
106
|
-
"aspect_ratio": (
|
|
107
|
-
["9:16", "16:9"],
|
|
108
|
-
{"default": "16:9"},
|
|
109
|
-
),
|
|
110
|
-
"duration": ([10, 15], {"default": 10}),
|
|
111
|
-
"size": (["small", "large"], {"default": "small"}),
|
|
112
|
-
},
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
NODE_DISPLAY_NAME = "Sora2 Image To Video"
|
|
116
|
-
RETURN_TYPES = ("VIDEO",)
|
|
117
|
-
RETURN_NAMES = ("video",)
|
|
118
|
-
CATEGORY = "☁️BizyAir/External APIs/Sora"
|
|
119
|
-
FUNCTION = "api_call"
|
|
120
|
-
|
|
121
|
-
def api_call(self, image, model, prompt, **kwargs):
|
|
122
|
-
extra_data = pop_api_key_and_prompt_id(kwargs)
|
|
123
|
-
headers = client.headers(api_key=extra_data["api_key"])
|
|
124
|
-
prompt_id = extra_data["prompt_id"]
|
|
125
|
-
headers["X-BIZYAIR-PROMPT-ID"] = prompt_id
|
|
126
|
-
headers["X-Bizyair-Async-Result"] = "enable"
|
|
127
|
-
|
|
128
|
-
# 参数
|
|
129
|
-
aspect_ratio = kwargs.get("aspect_ratio", "16:9")
|
|
130
|
-
duration = kwargs.get("duration", 10)
|
|
131
|
-
size = kwargs.get("size", "small")
|
|
132
|
-
|
|
133
|
-
input = {
|
|
134
|
-
"webHook": "-1",
|
|
135
|
-
"aspectRatio": aspect_ratio,
|
|
136
|
-
"duration": duration,
|
|
137
|
-
"size": size,
|
|
138
|
-
"model": model,
|
|
139
|
-
}
|
|
140
|
-
if prompt is not None and prompt.strip() != "":
|
|
141
|
-
input["prompt"] = prompt
|
|
142
|
-
else:
|
|
143
|
-
raise ValueError("Prompt is required")
|
|
144
|
-
|
|
145
|
-
# 上传图片
|
|
146
|
-
if image is not None:
|
|
147
|
-
oss_token_url = f"{BIZYAIR_X_SERVER}/upload/token?file_name={prompt_id}.png&file_type=inputs"
|
|
148
|
-
token_resp = send_request("GET", oss_token_url, headers=headers)
|
|
149
|
-
auth_info = parse_upload_token(token_resp)
|
|
150
|
-
input["url"] = upload_file_without_sdk(
|
|
151
|
-
tensor_to_bytesio(image), **auth_info
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
# 调用API
|
|
155
|
-
return sora2_create_task_and_wait_for_completion(
|
|
156
|
-
data=input, model=model, prompt=prompt, headers=headers
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
class Sora_V2_T2V_API(BizyAirBaseNode):
|
|
161
|
-
@classmethod
|
|
162
|
-
def INPUT_TYPES(cls):
|
|
163
|
-
return {
|
|
164
|
-
"required": {
|
|
165
|
-
"prompt": (
|
|
166
|
-
"STRING",
|
|
167
|
-
{
|
|
168
|
-
"multiline": True,
|
|
169
|
-
"default": "",
|
|
170
|
-
},
|
|
171
|
-
),
|
|
172
|
-
"model": (["sora-2"], {"default": "sora-2"}),
|
|
173
|
-
},
|
|
174
|
-
"optional": {
|
|
175
|
-
"aspect_ratio": (
|
|
176
|
-
["9:16", "16:9"],
|
|
177
|
-
{"default": "16:9"},
|
|
178
|
-
),
|
|
179
|
-
"duration": ([10, 15], {"default": 10}),
|
|
180
|
-
"size": (["small", "large"], {"default": "small"}),
|
|
181
|
-
},
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
NODE_DISPLAY_NAME = "Sora2 Text To Video"
|
|
185
|
-
RETURN_TYPES = ("VIDEO",)
|
|
186
|
-
RETURN_NAMES = ("video",)
|
|
187
|
-
CATEGORY = "☁️BizyAir/External APIs/Sora"
|
|
188
|
-
FUNCTION = "api_call"
|
|
189
|
-
|
|
190
|
-
def api_call(self, prompt, model, **kwargs):
|
|
191
|
-
extra_data = pop_api_key_and_prompt_id(kwargs)
|
|
192
|
-
headers = client.headers(api_key=extra_data["api_key"])
|
|
193
|
-
prompt_id = extra_data["prompt_id"]
|
|
194
|
-
headers["X-BIZYAIR-PROMPT-ID"] = prompt_id
|
|
195
|
-
headers["X-Bizyair-Async-Result"] = "enable"
|
|
196
|
-
|
|
197
|
-
# 参数
|
|
198
|
-
aspect_ratio = kwargs.get("aspect_ratio", "16:9")
|
|
199
|
-
duration = kwargs.get("duration", 10)
|
|
200
|
-
size = kwargs.get("size", "small")
|
|
201
|
-
|
|
202
|
-
input = {
|
|
203
|
-
"webHook": "-1",
|
|
204
|
-
"aspectRatio": aspect_ratio,
|
|
205
|
-
"duration": duration,
|
|
206
|
-
"size": size,
|
|
207
|
-
"model": model,
|
|
208
|
-
}
|
|
209
|
-
if prompt is not None and prompt.strip() != "":
|
|
210
|
-
input["prompt"] = prompt
|
|
211
|
-
else:
|
|
212
|
-
raise ValueError("Prompt is required")
|
|
213
|
-
|
|
214
|
-
# 调用API
|
|
215
|
-
return sora2_create_task_and_wait_for_completion(
|
|
216
|
-
data=input, model=model, prompt=prompt, headers=headers
|
|
217
|
-
)
|