Skip to content

Commit d546e5b

Browse files
Merge pull request #40 from dotflow-io/feature/39
πŸ“Œ ISSUE-#39: Bulk task inclusion option
2 parents 31c57d3 + c196099 commit d546e5b

File tree

12 files changed

+279
-84
lines changed

12 files changed

+279
-84
lines changed

β€Ždotflow/core/decorators/time.pyβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ def time(func):
77
def inside(*args, **kwargs):
88
start = datetime.now()
99
task = func(*args, **kwargs)
10-
task._set_duration((datetime.now() - start).total_seconds())
10+
task.duration = (datetime.now() - start).total_seconds()
1111
return task
1212
return inside

β€Ždotflow/core/exception.pyβ€Ž

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"""Exception module"""
22

33
MESSAGE_UNKNOWN_ERROR = "Unknown error, please check logs for more information."
4-
MESSAGE_MISSING_STEP_DECORATOR = "A step function necessarily needs an 'action' decorator to circulate in the workflow. For more implementation details, access the documentation: https://dotflow-io.github.io/dotflow/nav/getting-started/#3-task-function."
4+
MESSAGE_MISSING_STEP_DECORATOR = "A step function necessarily needs an '@action' decorator to circulate in the workflow. For more implementation details, access the documentation: https://dotflow-io.github.io/dotflow/nav/getting-started/#3-task-function."
5+
MESSAGE_NOT_CALLABLE_OBJECT = "Problem validating the '{name}' object type; this is not a callable object"
56
MESSAGE_EXECUTION_NOT_EXIST = "The execution mode does not exist. Allowed parameter is 'sequential' and 'background'."
6-
MESSAGE_MODULE_NOT_FOUND = "Problem importing the python module, it probably doesn't exist or is wrong."
7+
MESSAGE_MODULE_NOT_FOUND = "Problem importing the python module '{module}', it probably doesn't exist or is wrong."
78

89

910
class MissingActionDecorator(Exception):
@@ -24,7 +25,20 @@ def __init__(self):
2425

2526
class ModuleNotFound(Exception):
2627

27-
def __init__(self):
28+
def __init__(self, module: str):
2829
super(ModuleNotFound, self).__init__(
29-
MESSAGE_MODULE_NOT_FOUND
30+
MESSAGE_MODULE_NOT_FOUND.format(
31+
module=module
32+
)
33+
)
34+
35+
36+
class NotCallableObject(Exception):
37+
38+
def __init__(self, name: str):
39+
super(NotCallableObject, self).__init__(
40+
MESSAGE_NOT_CALLABLE_OBJECT.format(
41+
name=name
42+
)
3043
)
44+

β€Ždotflow/core/execution.pyβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ def __init__(
2121
) -> None:
2222
self.task = task
2323
self.task.status = TaskStatus.IN_PROGRESS
24-
self.task._set_workflow_id(workflow_id)
2524
self.task.previous_context = previous_context
25+
self.task.workflow_id = workflow_id
2626

2727
self._excution()
2828

β€Ždotflow/core/module.pyβ€Ž

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ def import_module(cls, value: str):
3030
if hasattr(module, cls._get_name(value)):
3131
return getattr(module, cls._get_name(value))
3232

33-
raise ModuleNotFound()
33+
raise ModuleNotFound(
34+
module=value
35+
)
3436

3537
@classmethod
3638
def _get_name(cls, value: str):

β€Ždotflow/core/task.pyβ€Ž

Lines changed: 100 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from dotflow.core.action import Action
99
from dotflow.core.context import Context
1010
from dotflow.core.module import Module
11-
from dotflow.core.exception import MissingActionDecorator
11+
from dotflow.core.exception import MissingActionDecorator, NotCallableObject
1212
from dotflow.core.types.status import TaskStatus
1313
from dotflow.settings import Settings as settings
1414
from dotflow.utils import basic_callback, traceback_error, message_error, copy_file
@@ -19,11 +19,12 @@ class TaskInstance:
1919
def __init__(self, *args, **kwargs) -> None:
2020
self.task_id = None
2121
self.workflow_id = None
22-
self.step = None
23-
self.callback = None
22+
self._step = None
23+
self._callback = None
24+
self._previous_context = None
2425
self._initial_context = None
2526
self._current_context = None
26-
self._previous_context = None
27+
self._duration = None
2728
self._error = None
2829
self._status = None
2930
self._config = None
@@ -41,44 +42,45 @@ def __init__(
4142
config: Config = None,
4243
) -> None:
4344
super().__init__(task_id, step, callback, initial_context, workflow_id)
44-
self.config = config
4545
self.task_id = task_id
4646
self.workflow_id = workflow_id
4747
self.step = step
4848
self.callback = callback
4949
self.initial_context = initial_context
5050
self.status = TaskStatus.NOT_STARTED
51+
self.config = config
5152

5253
@property
53-
def status(self):
54-
if not self._status:
55-
return TaskStatus.NOT_STARTED
56-
return self._status
54+
def step(self):
55+
return self._step
5756

58-
@status.setter
59-
def status(self, value: TaskStatus) -> None:
60-
self._status = value
57+
@step.setter
58+
def step(self, value: Callable):
59+
new_step = value
60+
61+
if isinstance(value, str):
62+
new_step = Module(value=value)
63+
64+
if new_step.__module__ != Action.__module__:
65+
raise MissingActionDecorator()
6166

62-
logger.info("ID %s - %s - %s", self.workflow_id, self.task_id, value)
67+
self._step = new_step
6368

6469
@property
65-
def error(self):
66-
if not self._error:
67-
return TaskError()
68-
return self._error
70+
def callback(self):
71+
return self._callback
6972

70-
@error.setter
71-
def error(self, value: Exception) -> None:
72-
task_error = TaskError(value)
73-
self._error = task_error
73+
@callback.setter
74+
def callback(self, value: Callable):
75+
new_callback = value
7476

75-
logger.error(
76-
"ID %s - %s - %s \n %s",
77-
self.workflow_id,
78-
self.task_id,
79-
self.status,
80-
task_error.traceback,
81-
)
77+
if isinstance(value, str):
78+
new_callback = Module(value=value)
79+
80+
if not isinstance(new_callback, Callable):
81+
raise NotCallableObject(name=str(new_callback))
82+
83+
self._callback = new_callback
8284

8385
@property
8486
def previous_context(self):
@@ -90,6 +92,26 @@ def previous_context(self):
9092
def previous_context(self, value: Context):
9193
self._previous_context = Context(value)
9294

95+
@property
96+
def initial_context(self):
97+
if not self._initial_context:
98+
return Context()
99+
return self._initial_context
100+
101+
@initial_context.setter
102+
def initial_context(self, value: Context):
103+
self._initial_context = Context(value)
104+
105+
if self.config.output:
106+
logger.info(
107+
"ID %s - %s - Initial Context -> %s",
108+
self.workflow_id,
109+
self.task_id,
110+
str(value),
111+
)
112+
113+
copy_file(source=settings.LOG_PATH, destination=self.config.log_path)
114+
93115
@property
94116
def current_context(self):
95117
if not self._current_context:
@@ -111,24 +133,47 @@ def current_context(self, value: Context):
111133
copy_file(source=settings.LOG_PATH, destination=self.config.log_path)
112134

113135
@property
114-
def initial_context(self):
115-
if not self._initial_context:
116-
return Context()
117-
return self._initial_context
136+
def duration(self):
137+
return self._duration
118138

119-
@initial_context.setter
120-
def initial_context(self, value: Context):
121-
self._initial_context = Context(value)
139+
@duration.setter
140+
def duration(self, value: float):
141+
self._duration = value
122142

123-
if self.config.output:
124-
logger.info(
125-
"ID %s - %s - Initial Context -> %s",
126-
self.workflow_id,
127-
self.task_id,
128-
str(value),
129-
)
143+
@property
144+
def error(self):
145+
if not self._error:
146+
return TaskError()
147+
return self._error
130148

131-
copy_file(source=settings.LOG_PATH, destination=self.config.log_path)
149+
@error.setter
150+
def error(self, value: Exception) -> None:
151+
task_error = TaskError(value)
152+
self._error = task_error
153+
154+
logger.error(
155+
"ID %s - %s - %s \n %s",
156+
self.workflow_id,
157+
self.task_id,
158+
self.status,
159+
task_error.traceback,
160+
)
161+
162+
@property
163+
def status(self):
164+
if not self._status:
165+
return TaskStatus.NOT_STARTED
166+
return self._status
167+
168+
@status.setter
169+
def status(self, value: TaskStatus) -> None:
170+
self._status = value
171+
logger.info(
172+
"ID %s - %s - %s",
173+
self.workflow_id,
174+
self.task_id,
175+
value
176+
)
132177

133178
@property
134179
def config(self):
@@ -140,12 +185,6 @@ def config(self):
140185
def config(self, value: Config):
141186
self._config = value
142187

143-
def _set_duration(self, value: float) -> None:
144-
self.duration = value
145-
146-
def _set_workflow_id(self, value: UUID) -> None:
147-
self.workflow_id = value
148-
149188

150189
class TaskError:
151190

@@ -158,7 +197,7 @@ def __init__(self, error: Exception = None) -> None:
158197
class TaskBuilder:
159198

160199
def __init__(self, config: Config, workflow_id: UUID = None) -> None:
161-
self.queu: List[Task] = []
200+
self.queu: List[Callable] = []
162201
self.workflow_id = workflow_id
163202
self.config = config
164203

@@ -168,10 +207,14 @@ def add(
168207
callback: Callable = basic_callback,
169208
initial_context: Any = None,
170209
) -> None:
171-
step = Module(value=step)
172-
173-
if step.__module__ != Action.__module__:
174-
raise MissingActionDecorator()
210+
if isinstance(step, list):
211+
for inside_step in step:
212+
self.add(
213+
step=inside_step,
214+
callback=callback,
215+
initial_context=initial_context
216+
)
217+
return self
175218

176219
self.queu.append(
177220
Task(
@@ -191,3 +234,6 @@ def count(self) -> int:
191234

192235
def clear(self) -> None:
193236
self.queu.clear()
237+
238+
def reverse(self) -> None:
239+
self.queu.reverse()

β€Žexamples/simple_cli.pyβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def main():
1616
0000-00-00 00:00:00,000 - INFO [dotflow]: ID 56a908c5-c9f2-4ebf-a00a-895e49bd189b - 0 - In progress
1717
0000-00-00 00:00:00,000 - INFO [dotflow]: ID 56a908c5-c9f2-4ebf-a00a-895e49bd189b - 0 - Completed
1818
"""
19-
system("dotflow start --step examples.cli.simple_step")
19+
system("dotflow start --step examples.simple_cli.simple_step")
2020

2121

2222
if __name__ == "__main__":

0 commit comments

Comments
Β (0)