vectorvein 0.2.63__py3-none-any.whl → 0.2.65__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.
- vectorvein/workflow/graph/workflow.py +169 -0
- vectorvein/workflow/utils/json_to_code.py +4 -1
- {vectorvein-0.2.63.dist-info → vectorvein-0.2.65.dist-info}/METADATA +1 -1
- {vectorvein-0.2.63.dist-info → vectorvein-0.2.65.dist-info}/RECORD +6 -6
- {vectorvein-0.2.63.dist-info → vectorvein-0.2.65.dist-info}/WHEEL +0 -0
- {vectorvein-0.2.63.dist-info → vectorvein-0.2.65.dist-info}/entry_points.txt +0 -0
@@ -3,6 +3,7 @@ from typing import List, Union, Dict, Any, Optional
|
|
3
3
|
|
4
4
|
from .node import Node
|
5
5
|
from .edge import Edge
|
6
|
+
from .port import InputPort, OutputPort
|
6
7
|
from ..utils.layout import layout
|
7
8
|
from ..utils.check import (
|
8
9
|
WorkflowCheckResult,
|
@@ -168,3 +169,171 @@ class Workflow:
|
|
168
169
|
"""
|
169
170
|
layout(self.nodes, self.edges, options)
|
170
171
|
return self
|
172
|
+
|
173
|
+
@classmethod
|
174
|
+
def from_json(cls, json_str: str) -> "Workflow":
|
175
|
+
"""从 JSON 字符串创建工作流对象。
|
176
|
+
|
177
|
+
Args:
|
178
|
+
json_str: JSON 字符串
|
179
|
+
|
180
|
+
Returns:
|
181
|
+
Workflow: 工作流对象
|
182
|
+
"""
|
183
|
+
workflow = cls()
|
184
|
+
data = json.loads(json_str)
|
185
|
+
|
186
|
+
# 创建节点
|
187
|
+
for node_data in data.get("nodes", []):
|
188
|
+
node_type = node_data["type"]
|
189
|
+
category = node_data["category"]
|
190
|
+
task_name = node_data["data"]["task_name"]
|
191
|
+
|
192
|
+
# 尝试动态导入节点类
|
193
|
+
NodeClass = None
|
194
|
+
try:
|
195
|
+
# 如果task_name包含分类信息
|
196
|
+
if "." in task_name:
|
197
|
+
category, _ = task_name.split(".")
|
198
|
+
module_path = f"vectorvein.workflow.nodes.{category}"
|
199
|
+
module = __import__(module_path, fromlist=[node_type])
|
200
|
+
if hasattr(module, node_type):
|
201
|
+
NodeClass = getattr(module, node_type)
|
202
|
+
except (ImportError, AttributeError):
|
203
|
+
pass
|
204
|
+
|
205
|
+
if not NodeClass:
|
206
|
+
raise ValueError(f"Node class not found: {node_type}")
|
207
|
+
# 创建节点实例以获取默认值
|
208
|
+
node_instance = NodeClass()
|
209
|
+
|
210
|
+
# 使用节点实例的基本属性
|
211
|
+
node = Node(
|
212
|
+
node_type=node_type,
|
213
|
+
category=category,
|
214
|
+
task_name=task_name,
|
215
|
+
description=node_data["data"].get(
|
216
|
+
"description", node_instance.description if hasattr(node_instance, "description") else ""
|
217
|
+
),
|
218
|
+
node_id=node_data["id"],
|
219
|
+
position=node_data.get("position", {"x": 0, "y": 0}),
|
220
|
+
seleted_workflow_title=node_data["data"].get("seleted_workflow_title", ""),
|
221
|
+
is_template=node_data["data"].get("is_template", False),
|
222
|
+
initialized=node_data.get("initialized", False),
|
223
|
+
can_add_input_ports=node_data["data"].get("has_inputs", False),
|
224
|
+
can_add_output_ports=node_data["data"].get("has_outputs", False),
|
225
|
+
)
|
226
|
+
|
227
|
+
# 处理端口
|
228
|
+
for port_name, port_data in node_data["data"].get("template", {}).items():
|
229
|
+
# 如果端口已存在于节点实例中,直接修改其属性
|
230
|
+
if port_name in node_instance.ports:
|
231
|
+
# 直接修改原始端口的属性,而不是创建新端口
|
232
|
+
port = node_instance.ports[port_name]
|
233
|
+
|
234
|
+
# 更新端口的属性
|
235
|
+
if "field_type" in port_data:
|
236
|
+
port.port_type = port_data["field_type"]
|
237
|
+
if "required" in port_data:
|
238
|
+
port.required = port_data["required"]
|
239
|
+
if "show" in port_data:
|
240
|
+
port.show = port_data["show"]
|
241
|
+
if "value" in port_data:
|
242
|
+
port.value = port_data["value"]
|
243
|
+
if "options" in port_data:
|
244
|
+
port.options = port_data["options"]
|
245
|
+
if "type" in port_data:
|
246
|
+
port.field_type = port_data["type"]
|
247
|
+
if "max_length" in port_data:
|
248
|
+
port.max_length = port_data["max_length"]
|
249
|
+
if "support_file_types" in port_data and port_data["support_file_types"]:
|
250
|
+
port.support_file_types = port_data["support_file_types"].split(", ")
|
251
|
+
if "multiple" in port_data:
|
252
|
+
port.multiple = port_data["multiple"]
|
253
|
+
if "group" in port_data:
|
254
|
+
port.group = port_data["group"]
|
255
|
+
if "group_collpased" in port_data:
|
256
|
+
port.group_collpased = port_data["group_collpased"]
|
257
|
+
if "has_tooltip" in port_data:
|
258
|
+
port.has_tooltip = port_data["has_tooltip"]
|
259
|
+
if "max" in port_data:
|
260
|
+
port.max = port_data["max"]
|
261
|
+
if "min" in port_data:
|
262
|
+
port.min = port_data["min"]
|
263
|
+
if "list" in port_data:
|
264
|
+
port.list = port_data["list"]
|
265
|
+
else:
|
266
|
+
# 对于新添加的端口,检查是否允许添加
|
267
|
+
port_type = port_data.get("field_type", "text")
|
268
|
+
is_output = port_data.get("is_output", False)
|
269
|
+
|
270
|
+
# 检查节点是否允许添加该类型的端口
|
271
|
+
if (is_output and not node.can_add_output_ports) or (
|
272
|
+
not is_output and not node.can_add_input_ports
|
273
|
+
):
|
274
|
+
# 如果不允许添加,跳过该端口
|
275
|
+
continue
|
276
|
+
|
277
|
+
# 创建并添加新端口
|
278
|
+
if is_output:
|
279
|
+
port = OutputPort(
|
280
|
+
name=port_name,
|
281
|
+
port_type=port_type,
|
282
|
+
required=port_data.get("required", False),
|
283
|
+
show=port_data.get("show", False),
|
284
|
+
value=port_data.get("value"),
|
285
|
+
options=port_data.get("options"),
|
286
|
+
field_type=port_data.get("type"),
|
287
|
+
max_length=port_data.get("max_length"),
|
288
|
+
support_file_types=port_data.get("support_file_types", "").split(", ")
|
289
|
+
if port_data.get("support_file_types")
|
290
|
+
else None,
|
291
|
+
multiple=port_data.get("multiple"),
|
292
|
+
group=port_data.get("group"),
|
293
|
+
group_collpased=port_data.get("group_collpased", False),
|
294
|
+
has_tooltip=port_data.get("has_tooltip", False),
|
295
|
+
max=port_data.get("max"),
|
296
|
+
min=port_data.get("min"),
|
297
|
+
list=port_data.get("list", False),
|
298
|
+
)
|
299
|
+
else:
|
300
|
+
port = InputPort(
|
301
|
+
name=port_name,
|
302
|
+
port_type=port_type,
|
303
|
+
required=port_data.get("required", True),
|
304
|
+
show=port_data.get("show", False),
|
305
|
+
value=port_data.get("value"),
|
306
|
+
options=port_data.get("options"),
|
307
|
+
field_type=port_data.get("type"),
|
308
|
+
max_length=port_data.get("max_length"),
|
309
|
+
support_file_types=port_data.get("support_file_types", "").split(", ")
|
310
|
+
if port_data.get("support_file_types")
|
311
|
+
else None,
|
312
|
+
multiple=port_data.get("multiple"),
|
313
|
+
group=port_data.get("group"),
|
314
|
+
group_collpased=port_data.get("group_collpased", False),
|
315
|
+
has_tooltip=port_data.get("has_tooltip", False),
|
316
|
+
max=port_data.get("max"),
|
317
|
+
min=port_data.get("min"),
|
318
|
+
list=port_data.get("list", False),
|
319
|
+
)
|
320
|
+
|
321
|
+
# 添加新端口到节点
|
322
|
+
node.ports[port_name] = port
|
323
|
+
|
324
|
+
workflow.add_node(node)
|
325
|
+
|
326
|
+
# 创建边
|
327
|
+
for edge_data in data.get("edges", []):
|
328
|
+
edge = Edge(
|
329
|
+
id=edge_data["id"],
|
330
|
+
source=edge_data["source"],
|
331
|
+
source_handle=edge_data["sourceHandle"],
|
332
|
+
target=edge_data["target"],
|
333
|
+
target_handle=edge_data["targetHandle"],
|
334
|
+
animated=edge_data.get("animated", True),
|
335
|
+
type=edge_data.get("type", "default"),
|
336
|
+
)
|
337
|
+
workflow.add_edge(edge)
|
338
|
+
|
339
|
+
return workflow
|
@@ -150,11 +150,14 @@ def generate_python_code(
|
|
150
150
|
|
151
151
|
# 添加节点到工作流
|
152
152
|
node_list = [f" {info['var_name']}," for info in node_instances.values()]
|
153
|
-
|
153
|
+
node_list_str = "\n".join(node_list)
|
154
|
+
code.append(f"workflow.add_nodes([\n{node_list_str}\n])")
|
154
155
|
|
155
156
|
code.append("")
|
156
157
|
for node_info in node_instances.values():
|
157
158
|
for port in node_info["add_ports"]:
|
159
|
+
if "name" not in port:
|
160
|
+
continue
|
158
161
|
params = [
|
159
162
|
f"name={to_python_str(port['name'])}",
|
160
163
|
f"port_type={to_python_str(port['field_type'])}",
|
@@ -1,6 +1,6 @@
|
|
1
|
-
vectorvein-0.2.
|
2
|
-
vectorvein-0.2.
|
3
|
-
vectorvein-0.2.
|
1
|
+
vectorvein-0.2.65.dist-info/METADATA,sha256=uzmiNET17QtrxVT2HdpBs68JBFwNXkDdfIQ_0HG8-b4,4570
|
2
|
+
vectorvein-0.2.65.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
|
3
|
+
vectorvein-0.2.65.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
4
4
|
vectorvein/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
vectorvein/api/__init__.py,sha256=lfY-XA46fgD2iIZTU0VYP8i07AwA03Egj4Qua0vUKrQ,738
|
6
6
|
vectorvein/api/client.py,sha256=xF-leKDQzVyyy9FnIRaz0k4eElYW1XbbzeRLcpnyk90,33047
|
@@ -44,7 +44,7 @@ vectorvein/utilities/retry.py,sha256=6KFS9R2HdhqM3_9jkjD4F36ZSpEx2YNFGOVlpOsUetM
|
|
44
44
|
vectorvein/workflow/graph/edge.py,sha256=1ckyyjCue_PLm7P1ItUfKOy6AKkemOpZ9m1WJ8UXIHQ,1072
|
45
45
|
vectorvein/workflow/graph/node.py,sha256=WtO4MkeMQr59zNl9N2ZoYiCZcVKxebSp1rKMPONmfqk,5628
|
46
46
|
vectorvein/workflow/graph/port.py,sha256=HcinzQqNP7ysTvBmi3c4iaWne8nV6m-BpFFX0jTrMIE,7122
|
47
|
-
vectorvein/workflow/graph/workflow.py,sha256=
|
47
|
+
vectorvein/workflow/graph/workflow.py,sha256=TfBvuspF1uHxmZl4VThgsXA07xiPvMT_mzd1oUvZ9Ww,14600
|
48
48
|
vectorvein/workflow/nodes/__init__.py,sha256=dWrWtL3q0Vsn-MLgJ7gNgLCrwZ5BrqjrN2QFPNeBMuc,3240
|
49
49
|
vectorvein/workflow/nodes/audio_generation.py,sha256=ZRFZ_ycMTSJ2LKmekctagQdJYTl-3q4TNOIKETpS9AM,5870
|
50
50
|
vectorvein/workflow/nodes/control_flows.py,sha256=fDySWek8Isbfznwn0thmbTwTP4c99w68Up9dlASAtIo,6805
|
@@ -62,6 +62,6 @@ vectorvein/workflow/nodes/vector_db.py,sha256=p9AT_E8ASbcYHZqHYTCIGvqkIqzxaFM4Ux
|
|
62
62
|
vectorvein/workflow/nodes/video_generation.py,sha256=qmdg-t_idpxq1veukd-jv_ChICMOoInKxprV9Z4Vi2w,4118
|
63
63
|
vectorvein/workflow/nodes/web_crawlers.py,sha256=FB0bTimkk___p3Z5UwQx2YarJyQCc45jjnbXbgGA_qw,5640
|
64
64
|
vectorvein/workflow/utils/check.py,sha256=Oj_S5WQf4_Fr_ro3ipjZt9unKFSFcuwZrrSmrS9kVLE,10193
|
65
|
-
vectorvein/workflow/utils/json_to_code.py,sha256=
|
65
|
+
vectorvein/workflow/utils/json_to_code.py,sha256=eeOxtlAUWeEgUyFVawDjee3nIhonnROUUanyf1-l9Ro,6354
|
66
66
|
vectorvein/workflow/utils/layout.py,sha256=j0bRD3uaXu40xCS6U6BGahBI8FrHa5MiF55GbTrZ1LM,4565
|
67
|
-
vectorvein-0.2.
|
67
|
+
vectorvein-0.2.65.dist-info/RECORD,,
|
File without changes
|
File without changes
|