dotflow 0.9.0.dev1__tar.gz → 0.9.0.dev2__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.
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/PKG-INFO +1 -1
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/__init__.py +1 -1
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/cli/setup.py +1 -1
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/exception.py +10 -1
- dotflow-0.9.0.dev2/dotflow/core/execution.py +138 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/pyproject.toml +2 -2
- dotflow-0.9.0.dev1/dotflow/core/execution.py +0 -86
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/LICENSE +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/README.md +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/abc/__init__.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/abc/file.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/abc/http.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/abc/tcp.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/cli/__init__.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/cli/command.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/cli/commands/__init__.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/cli/commands/init.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/cli/commands/log.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/cli/commands/start.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/cli/validators/__init__.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/cli/validators/start.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/__init__.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/action.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/config.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/context.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/decorators/__init__.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/decorators/action.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/decorators/retry.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/decorators/time.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/dotflow.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/module.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/serializers/__init__.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/serializers/task.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/serializers/transport.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/serializers/workflow.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/task.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/types/__init__.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/types/execution.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/types/status.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/types/worflow.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/core/workflow.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/logging.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/main.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/providers/__init__.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/providers/zeromq.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/settings.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/utils/__init__.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/utils/basic_functions.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/utils/error_handler.py +0 -0
- {dotflow-0.9.0.dev1 → dotflow-0.9.0.dev2}/dotflow/utils/tools.py +0 -0
|
@@ -5,7 +5,7 @@ MESSAGE_MISSING_STEP_DECORATOR = "A step function necessarily needs an '@action'
|
|
|
5
5
|
MESSAGE_NOT_CALLABLE_OBJECT = "Problem validating the '{name}' object type; this is not a callable object"
|
|
6
6
|
MESSAGE_EXECUTION_NOT_EXIST = "The execution mode does not exist. Allowed parameter is 'sequential' and 'background'."
|
|
7
7
|
MESSAGE_MODULE_NOT_FOUND = "Problem importing the python module '{module}'."
|
|
8
|
-
|
|
8
|
+
MESSAGE_PROBLEM_ORDERING = "Problem with correctly ordering functions of the '{name}' class."
|
|
9
9
|
|
|
10
10
|
class MissingActionDecorator(Exception):
|
|
11
11
|
|
|
@@ -42,3 +42,12 @@ class NotCallableObject(Exception):
|
|
|
42
42
|
)
|
|
43
43
|
)
|
|
44
44
|
|
|
45
|
+
|
|
46
|
+
class ProblemOrdering(Exception):
|
|
47
|
+
|
|
48
|
+
def __init__(self, name: str):
|
|
49
|
+
super(ProblemOrdering, self).__init__(
|
|
50
|
+
MESSAGE_PROBLEM_ORDERING.format(
|
|
51
|
+
name=name
|
|
52
|
+
)
|
|
53
|
+
)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Execution module"""
|
|
2
|
+
|
|
3
|
+
from uuid import UUID
|
|
4
|
+
from typing import Callable, List, Tuple
|
|
5
|
+
from inspect import getsourcelines
|
|
6
|
+
from types import FunctionType, NoneType
|
|
7
|
+
|
|
8
|
+
from dotflow.logging import logger
|
|
9
|
+
from dotflow.core.action import Action
|
|
10
|
+
from dotflow.core.context import Context
|
|
11
|
+
from dotflow.core.task import Task
|
|
12
|
+
from dotflow.core.types import TaskStatus
|
|
13
|
+
|
|
14
|
+
from dotflow.core.decorators import time
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Execution:
|
|
18
|
+
|
|
19
|
+
VALID_OBJECTS = [
|
|
20
|
+
str,
|
|
21
|
+
int,
|
|
22
|
+
float,
|
|
23
|
+
dict,
|
|
24
|
+
list,
|
|
25
|
+
tuple,
|
|
26
|
+
set,
|
|
27
|
+
bool,
|
|
28
|
+
FunctionType,
|
|
29
|
+
NoneType
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
task: Task,
|
|
35
|
+
workflow_id: UUID,
|
|
36
|
+
previous_context: Context
|
|
37
|
+
) -> None:
|
|
38
|
+
self.task = task
|
|
39
|
+
self.task.status = TaskStatus.IN_PROGRESS
|
|
40
|
+
self.task.previous_context = previous_context
|
|
41
|
+
self.task.workflow_id = workflow_id
|
|
42
|
+
|
|
43
|
+
self._excution()
|
|
44
|
+
|
|
45
|
+
def _is_action(self, class_instance: Callable, func: Callable):
|
|
46
|
+
return (
|
|
47
|
+
callable(getattr(class_instance, func))
|
|
48
|
+
and not func.startswith("__")
|
|
49
|
+
and getattr(class_instance, func).__module__ is Action.__module__
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def _execution_orderer(
|
|
53
|
+
self,
|
|
54
|
+
callable_list: List[str],
|
|
55
|
+
class_instance: Callable
|
|
56
|
+
) -> Tuple[int, Callable]:
|
|
57
|
+
ordered_list = []
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
inside_code = getsourcelines(class_instance.__class__)[0]
|
|
61
|
+
|
|
62
|
+
for callable_name in callable_list:
|
|
63
|
+
for index, code in enumerate(inside_code):
|
|
64
|
+
if code.find(f"def {callable_name}") != -1:
|
|
65
|
+
ordered_list.append((index, callable_name))
|
|
66
|
+
|
|
67
|
+
ordered_list.sort()
|
|
68
|
+
return ordered_list
|
|
69
|
+
|
|
70
|
+
except TypeError as err:
|
|
71
|
+
logger.error(f"Internal problem: {str(err)}")
|
|
72
|
+
|
|
73
|
+
for index, callable_name in enumerate(callable_list):
|
|
74
|
+
ordered_list.append((index, callable_name))
|
|
75
|
+
|
|
76
|
+
return ordered_list
|
|
77
|
+
|
|
78
|
+
def _execution_with_class(self, class_instance: Callable):
|
|
79
|
+
new_context = Context(storage=[])
|
|
80
|
+
previous_context = self.task.previous_context
|
|
81
|
+
callable_list = [
|
|
82
|
+
func
|
|
83
|
+
for func in dir(class_instance)
|
|
84
|
+
if self._is_action(class_instance, func)
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
ordered_list = self._execution_orderer(
|
|
88
|
+
callable_list=callable_list, class_instance=class_instance
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
for _, new in ordered_list:
|
|
92
|
+
new_object = getattr(class_instance, new)
|
|
93
|
+
try:
|
|
94
|
+
subcontext = new_object(
|
|
95
|
+
initial_context=self.task.initial_context,
|
|
96
|
+
previous_context=previous_context,
|
|
97
|
+
)
|
|
98
|
+
new_context.storage.append(subcontext)
|
|
99
|
+
previous_context = subcontext
|
|
100
|
+
|
|
101
|
+
except Exception:
|
|
102
|
+
subcontext = new_object(
|
|
103
|
+
class_instance,
|
|
104
|
+
initial_context=self.task.initial_context,
|
|
105
|
+
previous_context=previous_context,
|
|
106
|
+
)
|
|
107
|
+
new_context.storage.append(subcontext)
|
|
108
|
+
previous_context = subcontext
|
|
109
|
+
|
|
110
|
+
if not new_context.storage:
|
|
111
|
+
return Context(storage=class_instance)
|
|
112
|
+
|
|
113
|
+
return new_context
|
|
114
|
+
|
|
115
|
+
@time
|
|
116
|
+
def _excution(self):
|
|
117
|
+
try:
|
|
118
|
+
current_context = self.task.step(
|
|
119
|
+
initial_context=self.task.initial_context,
|
|
120
|
+
previous_context=self.task.previous_context,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
if type(current_context.storage) not in self.VALID_OBJECTS:
|
|
124
|
+
current_context = self._execution_with_class(
|
|
125
|
+
class_instance=current_context.storage
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
self.task.status = TaskStatus.COMPLETED
|
|
129
|
+
self.task.current_context = current_context
|
|
130
|
+
|
|
131
|
+
except Exception as err:
|
|
132
|
+
self.task.status = TaskStatus.FAILED
|
|
133
|
+
self.task.error = err
|
|
134
|
+
|
|
135
|
+
finally:
|
|
136
|
+
self.task.callback(content=self.task)
|
|
137
|
+
|
|
138
|
+
return self.task
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dotflow"
|
|
3
|
-
version = "0.9.0.
|
|
3
|
+
version = "0.9.0.dev2"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name="Fernando Celmer", email="email@fernandocelmer.com" },
|
|
6
6
|
]
|
|
@@ -31,7 +31,7 @@ Documentation = "https://github.com/dotflow-io/dotflow/blob/master/README.md"
|
|
|
31
31
|
|
|
32
32
|
[tool.poetry]
|
|
33
33
|
name = "dotflow"
|
|
34
|
-
version = "0.9.0.
|
|
34
|
+
version = "0.9.0.dev2"
|
|
35
35
|
description = "🎲 Dotflow turns an idea into flow!"
|
|
36
36
|
authors = ["Fernando Celmer <email@fernandocelmer.com>"]
|
|
37
37
|
readme = "README.md"
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
"""Execution module"""
|
|
2
|
-
|
|
3
|
-
from uuid import UUID
|
|
4
|
-
from typing import Callable
|
|
5
|
-
|
|
6
|
-
from dotflow.core.action import Action
|
|
7
|
-
from dotflow.core.context import Context
|
|
8
|
-
from dotflow.core.task import Task
|
|
9
|
-
from dotflow.core.types import TaskStatus
|
|
10
|
-
|
|
11
|
-
from dotflow.core.decorators import time
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class Execution:
|
|
15
|
-
|
|
16
|
-
def __init__(
|
|
17
|
-
self,
|
|
18
|
-
task: Task,
|
|
19
|
-
workflow_id: UUID,
|
|
20
|
-
previous_context: Context
|
|
21
|
-
) -> None:
|
|
22
|
-
self.task = task
|
|
23
|
-
self.task.status = TaskStatus.IN_PROGRESS
|
|
24
|
-
self.task.previous_context = previous_context
|
|
25
|
-
self.task.workflow_id = workflow_id
|
|
26
|
-
|
|
27
|
-
self._excution()
|
|
28
|
-
|
|
29
|
-
def _execution_with_class(self, class_instance: Callable):
|
|
30
|
-
context = Context(storage=[])
|
|
31
|
-
previous_context = self.task.previous_context
|
|
32
|
-
|
|
33
|
-
for func_name in dir(class_instance):
|
|
34
|
-
additional_function = getattr(class_instance, func_name)
|
|
35
|
-
|
|
36
|
-
if isinstance(additional_function, Action):
|
|
37
|
-
try:
|
|
38
|
-
current_context = additional_function(
|
|
39
|
-
initial_context=self.task.initial_context,
|
|
40
|
-
previous_context=previous_context,
|
|
41
|
-
)
|
|
42
|
-
context.storage.append(current_context)
|
|
43
|
-
previous_context = current_context
|
|
44
|
-
except TypeError:
|
|
45
|
-
current_context = additional_function(
|
|
46
|
-
class_instance,
|
|
47
|
-
initial_context=self.task.initial_context,
|
|
48
|
-
previous_context=previous_context,
|
|
49
|
-
)
|
|
50
|
-
context.storage.append(current_context)
|
|
51
|
-
previous_context = current_context
|
|
52
|
-
|
|
53
|
-
if not context.storage:
|
|
54
|
-
return Context(storage=class_instance)
|
|
55
|
-
|
|
56
|
-
return context
|
|
57
|
-
|
|
58
|
-
@time
|
|
59
|
-
def _excution(self):
|
|
60
|
-
try:
|
|
61
|
-
current_context = self.task.step(
|
|
62
|
-
initial_context=self.task.initial_context,
|
|
63
|
-
previous_context=self.task.previous_context,
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
object_attributes = [
|
|
67
|
-
type(getattr(current_context.storage, param)) is Action
|
|
68
|
-
for param in dir(current_context.storage)
|
|
69
|
-
]
|
|
70
|
-
|
|
71
|
-
if True in object_attributes:
|
|
72
|
-
current_context = self._execution_with_class(
|
|
73
|
-
class_instance=current_context.storage
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
self.task.status = TaskStatus.COMPLETED
|
|
77
|
-
self.task.current_context = current_context
|
|
78
|
-
|
|
79
|
-
except Exception as err:
|
|
80
|
-
self.task.status = TaskStatus.FAILED
|
|
81
|
-
self.task.error = err
|
|
82
|
-
|
|
83
|
-
finally:
|
|
84
|
-
self.task.callback(content=self.task)
|
|
85
|
-
|
|
86
|
-
return self.task
|
|
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
|
|
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
|
|
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
|
|
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
|