flowweave 3.0.0__tar.gz → 3.0.2__tar.gz
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.
- {flowweave-3.0.0 → flowweave-3.0.2}/PKG-INFO +5 -1
- flowweave-3.0.2/README.md +16 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave/__init__.py +1 -1
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave/base.py +17 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave/flowweave.py +57 -40
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave.egg-info/PKG-INFO +5 -1
- {flowweave-3.0.0 → flowweave-3.0.2}/pyproject.toml +1 -1
- flowweave-3.0.0/README.md +0 -12
- {flowweave-3.0.0 → flowweave-3.0.2}/LICENSE +0 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave/cli.py +0 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave/message.py +0 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave/schema/flow.json +0 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave/schema/op_code.json +0 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave.egg-info/SOURCES.txt +0 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave.egg-info/dependency_links.txt +0 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave.egg-info/entry_points.txt +0 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave.egg-info/requires.txt +0 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/flowweave.egg-info/top_level.txt +0 -0
- {flowweave-3.0.0 → flowweave-3.0.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowweave
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.2
|
|
4
4
|
Summary: YAML-based workflow runner for task orchestration
|
|
5
5
|
Author: syatch
|
|
6
6
|
License: MIT
|
|
@@ -16,6 +16,10 @@ Dynamic: license-file
|
|
|
16
16
|
# FlowWeave
|
|
17
17
|
YAML-based workflow runner for task orchestration
|
|
18
18
|
|
|
19
|
+
Although this version is more stable, it takes a few seconds to start up.
|
|
20
|
+
|
|
21
|
+
Therefore, [Lite version](https://github.com/syatch/flowweave-lite) is recommended.
|
|
22
|
+
|
|
19
23
|
This project is in early development.
|
|
20
24
|
|
|
21
25
|
## Installation
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# FlowWeave
|
|
2
|
+
YAML-based workflow runner for task orchestration
|
|
3
|
+
|
|
4
|
+
Although this version is more stable, it takes a few seconds to start up.
|
|
5
|
+
|
|
6
|
+
Therefore, [Lite version](https://github.com/syatch/flowweave-lite) is recommended.
|
|
7
|
+
|
|
8
|
+
This project is in early development.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
Install FlowWeave using pip:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install flowweave
|
|
16
|
+
```
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# Standard library
|
|
2
2
|
from enum import IntEnum
|
|
3
|
+
import importlib
|
|
3
4
|
from typing import IO, Optional
|
|
4
5
|
|
|
5
6
|
from colorama import Fore
|
|
@@ -10,6 +11,22 @@ class FlowWeaveResult(IntEnum):
|
|
|
10
11
|
IGNORE = 2
|
|
11
12
|
|
|
12
13
|
class TaskData:
|
|
14
|
+
def __getstate__(self):
|
|
15
|
+
state = self.__dict__.copy()
|
|
16
|
+
state["task_class_path"] = (
|
|
17
|
+
self.task_class.__module__,
|
|
18
|
+
self.task_class.__name__,
|
|
19
|
+
)
|
|
20
|
+
del state["task_class"]
|
|
21
|
+
return state
|
|
22
|
+
|
|
23
|
+
def __setstate__(self, state):
|
|
24
|
+
module_name, class_name = state["task_class_path"]
|
|
25
|
+
module = importlib.import_module(module_name)
|
|
26
|
+
state["task_class"] = getattr(module, class_name)
|
|
27
|
+
del state["task_class_path"]
|
|
28
|
+
self.__dict__.update(state)
|
|
29
|
+
|
|
13
30
|
def __init__(self,
|
|
14
31
|
name,
|
|
15
32
|
task_class,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# Standard library
|
|
2
|
-
import copy
|
|
3
2
|
from functools import reduce
|
|
4
3
|
import importlib
|
|
5
4
|
from importlib.resources import files
|
|
@@ -8,6 +7,7 @@ import itertools
|
|
|
8
7
|
import json
|
|
9
8
|
import logging
|
|
10
9
|
from pathlib import Path
|
|
10
|
+
import pickle
|
|
11
11
|
import sys
|
|
12
12
|
|
|
13
13
|
# Third-party
|
|
@@ -43,6 +43,10 @@ class StageData():
|
|
|
43
43
|
class TaskRunner():
|
|
44
44
|
@task
|
|
45
45
|
def start(prev_future, task_data: TaskData):
|
|
46
|
+
if hasattr(prev_future, "result"):
|
|
47
|
+
prev_future = prev_future.result()
|
|
48
|
+
|
|
49
|
+
return_data = None
|
|
46
50
|
try:
|
|
47
51
|
task_instance = task_data.task_class(prev_future)
|
|
48
52
|
except AttributeError:
|
|
@@ -60,7 +64,8 @@ class TaskRunner():
|
|
|
60
64
|
if task_data.show_log:
|
|
61
65
|
FlowWeave._print_log(f"Task option {key} not found: ignore")
|
|
62
66
|
run_task = True
|
|
63
|
-
|
|
67
|
+
|
|
68
|
+
if prev_future is not None:
|
|
64
69
|
if "pre_success" == task_data.do_only:
|
|
65
70
|
run_task = True if (FlowWeaveResult.SUCCESS == prev_future.get("result")) else False
|
|
66
71
|
elif "pre_fail" == task_data.do_only:
|
|
@@ -80,17 +85,23 @@ class TaskRunner():
|
|
|
80
85
|
TaskRunner.message_task_ignore(prev_future, task_data)
|
|
81
86
|
task_result = FlowWeaveResult.IGNORE
|
|
82
87
|
|
|
88
|
+
try:
|
|
89
|
+
if return_data is not None:
|
|
90
|
+
pickle.dumps(return_data)
|
|
91
|
+
except Exception:
|
|
92
|
+
raise TypeError(f"Task '{task_data.name}' return_data is not serializable")
|
|
93
|
+
|
|
83
94
|
return {"name" : task_data.name, "option" : task_data.option, "data" : return_data, "result" : task_result}
|
|
84
95
|
|
|
85
96
|
def message_task_start(prev_future, task_data: TaskData):
|
|
86
|
-
if prev_future:
|
|
97
|
+
if prev_future is not None:
|
|
87
98
|
prev_task_name = prev_future.get("name")
|
|
88
99
|
FlowMessage.task_start_link(prev_task_name, task_data)
|
|
89
100
|
else:
|
|
90
101
|
FlowMessage.task_start(task_data)
|
|
91
102
|
|
|
92
103
|
def message_task_ignore(prev_future, task_data: TaskData):
|
|
93
|
-
if prev_future:
|
|
104
|
+
if prev_future is not None:
|
|
94
105
|
prev_task_name = prev_future.get("name")
|
|
95
106
|
FlowMessage.task_ignore_link(task_data, prev_task_name)
|
|
96
107
|
else:
|
|
@@ -98,7 +109,7 @@ class TaskRunner():
|
|
|
98
109
|
|
|
99
110
|
class FlowWeave():
|
|
100
111
|
@flow
|
|
101
|
-
def run(setting_file: str, parallel: bool = False, show_log: bool = False) -> list[
|
|
112
|
+
def run(setting_file: str, parallel: bool = False, show_log: bool = False) -> list[FlowWeaveResult]:
|
|
102
113
|
if not show_log:
|
|
103
114
|
logging.getLogger("prefect").setLevel(logging.CRITICAL)
|
|
104
115
|
|
|
@@ -177,7 +188,7 @@ class FlowWeave():
|
|
|
177
188
|
op_source = flow_data.get("op_source")
|
|
178
189
|
op_source_list = op_source if isinstance(op_source, list) else [op_source]
|
|
179
190
|
for source in op_source_list:
|
|
180
|
-
source_name = f"task
|
|
191
|
+
source_name = f"task.{source}"
|
|
181
192
|
setting_file = f"{source_name.replace('.', '/')}/op_code.yml"
|
|
182
193
|
return_dic |= FlowWeave._get_op_dic_from_setting_file(setting_file, info=info)
|
|
183
194
|
|
|
@@ -262,7 +273,7 @@ class FlowWeave():
|
|
|
262
273
|
return all_combinations
|
|
263
274
|
|
|
264
275
|
@task
|
|
265
|
-
def run_flow(flow_data: dict, global_cmb: dict, op_dic: dict, part: int, all: int, show_log: bool = False) ->
|
|
276
|
+
def run_flow(flow_data: dict, global_cmb: dict, op_dic: dict, part: int, all: int, show_log: bool = False) -> FlowWeaveResult:
|
|
266
277
|
flow_result = FlowWeaveResult.SUCCESS
|
|
267
278
|
|
|
268
279
|
if show_log:
|
|
@@ -271,7 +282,7 @@ class FlowWeave():
|
|
|
271
282
|
text += "========"
|
|
272
283
|
FlowWeave._print_log(text)
|
|
273
284
|
|
|
274
|
-
default_option = flow_data.get("default_option")
|
|
285
|
+
default_option = flow_data.get("default_option", {})
|
|
275
286
|
|
|
276
287
|
stage_list = flow_data.get("flow")
|
|
277
288
|
for stage in stage_list:
|
|
@@ -288,7 +299,7 @@ class FlowWeave():
|
|
|
288
299
|
if FlowWeaveResult.FAIL == result:
|
|
289
300
|
flow_result = FlowWeaveResult.FAIL
|
|
290
301
|
|
|
291
|
-
FlowMessage.stage_end(stage, part, all,
|
|
302
|
+
FlowMessage.stage_end(stage, part, all, result)
|
|
292
303
|
|
|
293
304
|
return flow_result
|
|
294
305
|
|
|
@@ -328,7 +339,7 @@ class FlowWeave():
|
|
|
328
339
|
return stage_result
|
|
329
340
|
|
|
330
341
|
def _deep_merge(a: dict, b: dict) -> dict:
|
|
331
|
-
result =
|
|
342
|
+
result = copy.deepcopy(a)
|
|
332
343
|
for k, v in b.items():
|
|
333
344
|
if k in result and isinstance(result[k], dict) and isinstance(v, dict):
|
|
334
345
|
result[k] = FlowWeave._deep_merge(result[k], v)
|
|
@@ -346,36 +357,42 @@ class FlowWeave():
|
|
|
346
357
|
raise Exception(f"Cycle detected at task '{task_name}' in {visited}")
|
|
347
358
|
visited.add(task_name)
|
|
348
359
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
360
|
+
try:
|
|
361
|
+
task_dic = stage_data.stage_info.get(task_name)
|
|
362
|
+
if task_dic is None:
|
|
363
|
+
raise KeyError(f"Task '{task_name}' not found in stage '{stage_data.name}'")
|
|
364
|
+
|
|
365
|
+
task_module = stage_data.op_dic.get(task_dic.get('op'))
|
|
366
|
+
if not task_module:
|
|
367
|
+
raise Exception(f"module of op '{task_dic.get('op')}' for '{task_name}' not found")
|
|
368
|
+
|
|
369
|
+
default_option = stage_data.default_option or {}
|
|
370
|
+
global_option = stage_data.global_option or {}
|
|
371
|
+
task_option = FlowWeave._deep_merge_many(default_option, global_option, task_dic.get("option", {}))
|
|
372
|
+
|
|
373
|
+
task_data = TaskData(name=task_name,
|
|
374
|
+
task_class=task_module,
|
|
375
|
+
option=task_option,
|
|
376
|
+
stage_name=stage_data.name,
|
|
377
|
+
flow_part=stage_data.flow_part,
|
|
378
|
+
flow_all=stage_data.flow_all,
|
|
379
|
+
do_only=task_dic.get("do_only"),
|
|
380
|
+
show_log=show_log)
|
|
381
|
+
if prev_future is None:
|
|
382
|
+
future = TaskRunner.start.submit(None, task_data)
|
|
383
|
+
else:
|
|
384
|
+
future = TaskRunner.start.submit(prev_future, task_data)
|
|
371
385
|
|
|
372
|
-
|
|
373
|
-
|
|
386
|
+
links = task_dic.get("chain", {}).get("next", [])
|
|
387
|
+
links = links if isinstance(links, list) else [links]
|
|
374
388
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
389
|
+
futures = [future]
|
|
390
|
+
for link in links:
|
|
391
|
+
futures.extend(
|
|
392
|
+
FlowWeave._run_task(stage_data, link, future, visited.copy(), show_log)
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
return futures
|
|
380
396
|
|
|
381
|
-
|
|
397
|
+
finally:
|
|
398
|
+
visited.remove(task_name)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowweave
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.2
|
|
4
4
|
Summary: YAML-based workflow runner for task orchestration
|
|
5
5
|
Author: syatch
|
|
6
6
|
License: MIT
|
|
@@ -16,6 +16,10 @@ Dynamic: license-file
|
|
|
16
16
|
# FlowWeave
|
|
17
17
|
YAML-based workflow runner for task orchestration
|
|
18
18
|
|
|
19
|
+
Although this version is more stable, it takes a few seconds to start up.
|
|
20
|
+
|
|
21
|
+
Therefore, [Lite version](https://github.com/syatch/flowweave-lite) is recommended.
|
|
22
|
+
|
|
19
23
|
This project is in early development.
|
|
20
24
|
|
|
21
25
|
## Installation
|
flowweave-3.0.0/README.md
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|