dotflow 0.9.0.dev2__tar.gz → 0.10.0.dev1__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.
Files changed (63) hide show
  1. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/PKG-INFO +9 -8
  2. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/README.md +7 -7
  3. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/__init__.py +3 -5
  4. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/abc/file.py +1 -1
  5. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/abc/http.py +1 -1
  6. dotflow-0.10.0.dev1/dotflow/abc/storage.py +25 -0
  7. dotflow-0.10.0.dev1/dotflow/cli/commands/start.py +35 -0
  8. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/cli/setup.py +4 -8
  9. dotflow-0.10.0.dev1/dotflow/core/action.py +129 -0
  10. dotflow-0.10.0.dev1/dotflow/core/config.py +27 -0
  11. dotflow-0.10.0.dev1/dotflow/core/context.py +107 -0
  12. dotflow-0.10.0.dev1/dotflow/core/decorators/__init__.py +8 -0
  13. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/decorators/time.py +1 -0
  14. dotflow-0.10.0.dev1/dotflow/core/dotflow.py +75 -0
  15. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/exception.py +17 -5
  16. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/execution.py +21 -4
  17. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/module.py +2 -2
  18. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/task.py +94 -59
  19. dotflow-0.10.0.dev1/dotflow/core/types/execution.py +17 -0
  20. dotflow-0.10.0.dev1/dotflow/core/types/status.py +19 -0
  21. dotflow-0.10.0.dev1/dotflow/core/types/worflow.py +14 -0
  22. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/workflow.py +55 -4
  23. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/main.py +1 -0
  24. dotflow-0.10.0.dev1/dotflow/providers/__init__.py +9 -0
  25. dotflow-0.10.0.dev1/dotflow/providers/storage_file.py +35 -0
  26. dotflow-0.10.0.dev1/dotflow/providers/storage_init.py +20 -0
  27. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/settings.py +1 -0
  28. dotflow-0.10.0.dev1/dotflow/storage.py +28 -0
  29. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/utils/tools.py +10 -4
  30. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/pyproject.toml +7 -3
  31. dotflow-0.9.0.dev2/dotflow/cli/commands/start.py +0 -31
  32. dotflow-0.9.0.dev2/dotflow/core/action.py +0 -70
  33. dotflow-0.9.0.dev2/dotflow/core/config.py +0 -21
  34. dotflow-0.9.0.dev2/dotflow/core/context.py +0 -15
  35. dotflow-0.9.0.dev2/dotflow/core/decorators/__init__.py +0 -12
  36. dotflow-0.9.0.dev2/dotflow/core/decorators/action.py +0 -17
  37. dotflow-0.9.0.dev2/dotflow/core/decorators/retry.py +0 -29
  38. dotflow-0.9.0.dev2/dotflow/core/dotflow.py +0 -37
  39. dotflow-0.9.0.dev2/dotflow/core/types/execution.py +0 -9
  40. dotflow-0.9.0.dev2/dotflow/core/types/status.py +0 -11
  41. dotflow-0.9.0.dev2/dotflow/core/types/worflow.py +0 -8
  42. dotflow-0.9.0.dev2/dotflow/providers/__init__.py +0 -1
  43. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/LICENSE +0 -0
  44. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/abc/__init__.py +0 -0
  45. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/abc/tcp.py +0 -0
  46. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/cli/__init__.py +0 -0
  47. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/cli/command.py +0 -0
  48. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/cli/commands/__init__.py +0 -0
  49. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/cli/commands/init.py +0 -0
  50. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/cli/commands/log.py +0 -0
  51. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/cli/validators/__init__.py +0 -0
  52. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/cli/validators/start.py +0 -0
  53. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/__init__.py +0 -0
  54. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/serializers/__init__.py +0 -0
  55. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/serializers/task.py +0 -0
  56. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/serializers/transport.py +0 -0
  57. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/serializers/workflow.py +0 -0
  58. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/core/types/__init__.py +0 -0
  59. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/logging.py +0 -0
  60. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/providers/zeromq.py +0 -0
  61. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/utils/__init__.py +0 -0
  62. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/utils/basic_functions.py +0 -0
  63. {dotflow-0.9.0.dev2 → dotflow-0.10.0.dev1}/dotflow/utils/error_handler.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dotflow
3
- Version: 0.9.0.dev2
3
+ Version: 0.10.0.dev1
4
4
  Summary: 🎲 Dotflow turns an idea into flow!
5
5
  License: MIT License
6
6
 
@@ -36,6 +36,7 @@ Classifier: Programming Language :: Python :: 3.11
36
36
  Classifier: Programming Language :: Python :: 3.12
37
37
  Requires-Dist: pydantic
38
38
  Requires-Dist: rich
39
+ Requires-Dist: typing-extensions
39
40
  Project-URL: Documentation, https://github.com/dotflow-io/dotflow/blob/master/README.md
40
41
  Project-URL: Homepage, https://github.com/dotflow-io/dotflow
41
42
  Project-URL: Issues, https://github.com/dotflow-io/dotflow/issues
@@ -106,7 +107,7 @@ workflow.start()
106
107
 
107
108
  #### 1 - Import
108
109
 
109
- Start with the basics, which is importing the necessary classes and methods. ([DotFlow](https://dotflow-io.github.io/dotflow/nav/reference/dotflow-class/), [action](https://dotflow-io.github.io/dotflow/nav/reference/action-decorator/))
110
+ Start with the basics, which is importing the necessary classes and methods. ([DotFlow](https://dotflow-io.github.io/dotflow/nav/reference/dotflow/), [action](https://dotflow-io.github.io/dotflow/nav/reference/action/))
110
111
 
111
112
  ```python
112
113
  from dotflow import DotFlow, action
@@ -114,7 +115,7 @@ from dotflow import DotFlow, action
114
115
 
115
116
  #### 2 - Callback function
116
117
 
117
- Create a `my_callback` function to receive execution information of a task. `It is not necessary` to include this function, as you will still have a report at the end of the execution in the instantiated object of the `DotFlow` class. This `my_callback` function is only needed if you need to do something after the execution of the task, for example: sending a message to someone, making a phone call, or sending a letter.
118
+ Create a `my_callback` function to receive execution information of a task. `It is not necessary` to include this function, as you will still have a report at the end of the execution in the instantiated object of the `DotFlow` class. This `my_callback` function is only needed if you need to do something after the execution of the task, for example: sending a message to someone, making a phone call, or sending a letter. [More details](https://dotflow-io.github.io/dotflow/nav/reference/utils/#dotflow.utils.basic_functions.basic_callback)
118
119
 
119
120
  ```python
120
121
  def my_callback(*args, **kwargs):
@@ -123,7 +124,7 @@ def my_callback(*args, **kwargs):
123
124
 
124
125
  #### 3 - Task function
125
126
 
126
- Now, create the function responsible for executing your task. It's very simple; just use the [action](https://dotflow-io.github.io/dotflow/nav/reference/action-decorator/) decorator above the function, and that's it—you've created a task. If necessary, you can also add the parameter called `retry` to set the maximum number of execution attempts if the function fails.
127
+ Now, create the function responsible for executing your task. It's very simple; just use the [action](https://dotflow-io.github.io/dotflow/nav/reference/action/) decorator above the function, and that's it—you've created a task. If necessary, you can also add the parameter called `retry` to set the maximum number of execution attempts if the function fails. [More details](https://dotflow-io.github.io/dotflow/nav/reference/utils/#dotflow.utils.basic_functions.basic_function)
127
128
 
128
129
  ```python
129
130
  @action(retry=5)
@@ -133,7 +134,7 @@ def my_task():
133
134
 
134
135
  #### 4 - DotFlow Class
135
136
 
136
- Instantiate the DotFlow class in a `workflow` variable to be used in the following steps. [More details](https://dotflow-io.github.io/dotflow/nav/reference/dotflow-class/).
137
+ Instantiate the DotFlow class in a `workflow` variable to be used in the following steps. [More details](https://dotflow-io.github.io/dotflow/nav/reference/dotflow/).
137
138
 
138
139
  ```python
139
140
  workflow = DotFlow()
@@ -141,7 +142,7 @@ workflow = DotFlow()
141
142
 
142
143
  #### 5 - Add Task
143
144
 
144
- Now, simply add the `my_task` and `my_callback` functions you created earlier to the workflow using the code below. This process is necessary to define which tasks will be executed and the order in which they will run. The execution order follows the sequence in which they were added to the workflow.
145
+ Now, simply add the `my_task` and `my_callback` functions you created earlier to the workflow using the code below. This process is necessary to define which tasks will be executed and the order in which they will run. The execution order follows the sequence in which they were added to the workflow. [More details](https://dotflow-io.github.io/dotflow/nav/reference/task-builder/#dotflow.core.task.TaskBuilder.add)
145
146
 
146
147
  ```python
147
148
  workflow.task.add(step=my_task, callback=my_callback)
@@ -149,7 +150,7 @@ workflow.task.add(step=my_task, callback=my_callback)
149
150
 
150
151
  #### 6 - Start
151
152
 
152
- Finally, just execute the workflow with the following code snippet.
153
+ Finally, just execute the workflow with the following code snippet. [More details](https://dotflow-io.github.io/dotflow/nav/reference/workflow/#dotflow.core.workflow.Workflow)
153
154
 
154
155
  ```python
155
156
  workflow.start()
@@ -196,7 +197,7 @@ workflow.start()
196
197
  - ⚠️ SECURITY
197
198
 
198
199
  ## License
199
- ![GitHub License](https://img.shields.io/github/license/FernandoCelmer/dotflow)
200
+ ![GitHub License](https://img.shields.io/github/license/dotflow-io/dotflow)
200
201
 
201
202
  This project is licensed under the terms of the MIT License.
202
203
 
@@ -62,7 +62,7 @@ workflow.start()
62
62
 
63
63
  #### 1 - Import
64
64
 
65
- Start with the basics, which is importing the necessary classes and methods. ([DotFlow](https://dotflow-io.github.io/dotflow/nav/reference/dotflow-class/), [action](https://dotflow-io.github.io/dotflow/nav/reference/action-decorator/))
65
+ Start with the basics, which is importing the necessary classes and methods. ([DotFlow](https://dotflow-io.github.io/dotflow/nav/reference/dotflow/), [action](https://dotflow-io.github.io/dotflow/nav/reference/action/))
66
66
 
67
67
  ```python
68
68
  from dotflow import DotFlow, action
@@ -70,7 +70,7 @@ from dotflow import DotFlow, action
70
70
 
71
71
  #### 2 - Callback function
72
72
 
73
- Create a `my_callback` function to receive execution information of a task. `It is not necessary` to include this function, as you will still have a report at the end of the execution in the instantiated object of the `DotFlow` class. This `my_callback` function is only needed if you need to do something after the execution of the task, for example: sending a message to someone, making a phone call, or sending a letter.
73
+ Create a `my_callback` function to receive execution information of a task. `It is not necessary` to include this function, as you will still have a report at the end of the execution in the instantiated object of the `DotFlow` class. This `my_callback` function is only needed if you need to do something after the execution of the task, for example: sending a message to someone, making a phone call, or sending a letter. [More details](https://dotflow-io.github.io/dotflow/nav/reference/utils/#dotflow.utils.basic_functions.basic_callback)
74
74
 
75
75
  ```python
76
76
  def my_callback(*args, **kwargs):
@@ -79,7 +79,7 @@ def my_callback(*args, **kwargs):
79
79
 
80
80
  #### 3 - Task function
81
81
 
82
- Now, create the function responsible for executing your task. It's very simple; just use the [action](https://dotflow-io.github.io/dotflow/nav/reference/action-decorator/) decorator above the function, and that's it—you've created a task. If necessary, you can also add the parameter called `retry` to set the maximum number of execution attempts if the function fails.
82
+ Now, create the function responsible for executing your task. It's very simple; just use the [action](https://dotflow-io.github.io/dotflow/nav/reference/action/) decorator above the function, and that's it—you've created a task. If necessary, you can also add the parameter called `retry` to set the maximum number of execution attempts if the function fails. [More details](https://dotflow-io.github.io/dotflow/nav/reference/utils/#dotflow.utils.basic_functions.basic_function)
83
83
 
84
84
  ```python
85
85
  @action(retry=5)
@@ -89,7 +89,7 @@ def my_task():
89
89
 
90
90
  #### 4 - DotFlow Class
91
91
 
92
- Instantiate the DotFlow class in a `workflow` variable to be used in the following steps. [More details](https://dotflow-io.github.io/dotflow/nav/reference/dotflow-class/).
92
+ Instantiate the DotFlow class in a `workflow` variable to be used in the following steps. [More details](https://dotflow-io.github.io/dotflow/nav/reference/dotflow/).
93
93
 
94
94
  ```python
95
95
  workflow = DotFlow()
@@ -97,7 +97,7 @@ workflow = DotFlow()
97
97
 
98
98
  #### 5 - Add Task
99
99
 
100
- Now, simply add the `my_task` and `my_callback` functions you created earlier to the workflow using the code below. This process is necessary to define which tasks will be executed and the order in which they will run. The execution order follows the sequence in which they were added to the workflow.
100
+ Now, simply add the `my_task` and `my_callback` functions you created earlier to the workflow using the code below. This process is necessary to define which tasks will be executed and the order in which they will run. The execution order follows the sequence in which they were added to the workflow. [More details](https://dotflow-io.github.io/dotflow/nav/reference/task-builder/#dotflow.core.task.TaskBuilder.add)
101
101
 
102
102
  ```python
103
103
  workflow.task.add(step=my_task, callback=my_callback)
@@ -105,7 +105,7 @@ workflow.task.add(step=my_task, callback=my_callback)
105
105
 
106
106
  #### 6 - Start
107
107
 
108
- Finally, just execute the workflow with the following code snippet.
108
+ Finally, just execute the workflow with the following code snippet. [More details](https://dotflow-io.github.io/dotflow/nav/reference/workflow/#dotflow.core.workflow.Workflow)
109
109
 
110
110
  ```python
111
111
  workflow.start()
@@ -152,6 +152,6 @@ workflow.start()
152
152
  - ⚠️ SECURITY
153
153
 
154
154
  ## License
155
- ![GitHub License](https://img.shields.io/github/license/FernandoCelmer/dotflow)
155
+ ![GitHub License](https://img.shields.io/github/license/dotflow-io/dotflow)
156
156
 
157
157
  This project is licensed under the terms of the MIT License.
@@ -1,21 +1,19 @@
1
1
  """Dotflow __init__ module."""
2
2
 
3
- __version__ = "0.9.0.dev2"
3
+ __version__ = "0.10.0.dev1"
4
4
  __description__ = "🎲 Dotflow turns an idea into flow!"
5
5
 
6
- from .core.config import Config
7
6
  from .core.action import Action as action
7
+ from .core.config import Config
8
8
  from .core.context import Context
9
9
  from .core.dotflow import DotFlow
10
10
  from .core.task import Task
11
- from .core.decorators import retry # deprecated
12
11
 
13
12
 
14
13
  __all__ = [
15
14
  "action",
16
- "retry",
17
- "DotFlow",
18
15
  "Context",
19
16
  "Config",
17
+ "DotFlow",
20
18
  "Task"
21
19
  ]
@@ -1,4 +1,4 @@
1
- """File module"""
1
+ """File ABC"""
2
2
 
3
3
  from abc import ABC, abstractmethod
4
4
 
@@ -1,4 +1,4 @@
1
- """HTTP module"""
1
+ """HTTP ABC"""
2
2
 
3
3
  from abc import ABC, abstractmethod
4
4
  from typing import Callable
@@ -0,0 +1,25 @@
1
+ """Storage ABC"""
2
+
3
+ from typing import Callable
4
+ from abc import ABC, abstractmethod
5
+
6
+ from dotflow.core.context import Context
7
+
8
+
9
+ class Storage(ABC):
10
+ """Storage"""
11
+
12
+ def __init__(self, *args, **kwargs):
13
+ super().__init__()
14
+
15
+ @abstractmethod
16
+ def post(self, key: str, context: Context) -> None:
17
+ """Post context somewhere"""
18
+
19
+ @abstractmethod
20
+ def get(self, key: str) -> Context:
21
+ """Get context somewhere"""
22
+
23
+ @abstractmethod
24
+ def key(self, task: Callable):
25
+ """Function that returns a key to get and post storage"""
@@ -0,0 +1,35 @@
1
+ """Command start module"""
2
+
3
+ from os import system
4
+
5
+ from dotflow import DotFlow, Config
6
+ from dotflow.providers import StorageInit, StorageFile
7
+ from dotflow.core.types.execution import TypeExecution
8
+ from dotflow.cli.command import Command
9
+
10
+
11
+ class StartCommand(Command):
12
+
13
+ def setup(self):
14
+ workflow = DotFlow()
15
+
16
+ if self.params.storage:
17
+ storage = {"default": StorageInit, "file": StorageFile}
18
+
19
+ config = Config(
20
+ storage=storage.get(self.params.storage)(
21
+ path=self.params.path,
22
+ )
23
+ )
24
+ workflow = DotFlow(config=config)
25
+
26
+ workflow.task.add(
27
+ step=self.params.step,
28
+ callback=self.params.callback,
29
+ initial_context=self.params.initial_context,
30
+ )
31
+
32
+ workflow.start(mode=self.params.mode)
33
+
34
+ if self.params.mode == TypeExecution.BACKGROUND:
35
+ system("/bin/bash")
@@ -10,7 +10,7 @@ from dotflow.core.types.execution import TypeExecution
10
10
  from dotflow.core.exception import (
11
11
  MissingActionDecorator,
12
12
  ExecutionModeNotExist,
13
- ModuleNotFound,
13
+ ImportModuleError,
14
14
  MESSAGE_UNKNOWN_ERROR,
15
15
  )
16
16
  from dotflow.cli.commands import (
@@ -56,9 +56,7 @@ class Command:
56
56
  self.cmd_start.add_argument("-s", "--step", required=True)
57
57
  self.cmd_start.add_argument("-c", "--callback", default=basic_callback)
58
58
  self.cmd_start.add_argument("-i", "--initial-context")
59
- self.cmd_start.add_argument(
60
- "-o", "--output-context", default=False, action="store_true"
61
- )
59
+ self.cmd_start.add_argument("-o", "--storage", choices=["default", "file"])
62
60
  self.cmd_start.add_argument("-p", "--path", default=settings.START_PATH)
63
61
  self.cmd_start.add_argument(
64
62
  "-m",
@@ -71,9 +69,7 @@ class Command:
71
69
 
72
70
  def setup_logs(self):
73
71
  self.cmd_logs = self.subparsers.add_parser("logs", help="Logs")
74
- self.cmd_logs = self.cmd_logs.add_argument_group(
75
- "Usage: dotflow log [OPTIONS]"
76
- )
72
+ self.cmd_logs = self.cmd_logs.add_argument_group("Usage: dotflow log [OPTIONS]")
77
73
  self.cmd_logs.set_defaults(exec=LogCommand)
78
74
 
79
75
  def command(self):
@@ -89,7 +85,7 @@ class Command:
89
85
  except ExecutionModeNotExist as err:
90
86
  print(settings.WARNING_ALERT, err)
91
87
 
92
- except ModuleNotFound as err:
88
+ except ImportModuleError as err:
93
89
  print(settings.WARNING_ALERT, err)
94
90
 
95
91
  except Exception as err:
@@ -0,0 +1,129 @@
1
+ """Action module"""
2
+
3
+ from typing import Callable, Dict
4
+ from types import FunctionType
5
+
6
+ from dotflow.core.context import Context
7
+
8
+
9
+ class Action(object):
10
+ """
11
+ Import:
12
+ You can import the **action** decorator directly from dotflow:
13
+
14
+ from dotflow import action
15
+
16
+ Example:
17
+ `class` dotflow.core.action.Action
18
+
19
+ Standard
20
+
21
+ @action
22
+ def my_task():
23
+ print("task")
24
+
25
+ With Retry
26
+
27
+ @action(retry=5)
28
+ def my_task():
29
+ print("task")
30
+
31
+ Args:
32
+ func (Callable):
33
+
34
+ task (Callable):
35
+
36
+ retry (int):
37
+ Integer-type argument referring to the number of retry attempts
38
+ the function will execute in case of failure.
39
+ """
40
+
41
+ def __init__(
42
+ self,
43
+ func: Callable = None,
44
+ task: Callable = None,
45
+ retry: int = 1
46
+ ) -> None:
47
+ self.func = func
48
+ self.task = task
49
+ self.retry = retry
50
+ self.params = []
51
+
52
+ def __call__(self, *args, **kwargs):
53
+ # With parameters
54
+ if self.func:
55
+ self._set_params()
56
+
57
+ task = self._get_task(kwargs=kwargs)
58
+ contexts = self._get_context(kwargs=kwargs)
59
+
60
+ if contexts:
61
+ return Context(
62
+ storage=self._retry(*args, **contexts),
63
+ task_id=task.task_id,
64
+ workflow_id=task.workflow_id
65
+ )
66
+
67
+ return Context(
68
+ storage=self._retry(*args),
69
+ task_id=task.task_id,
70
+ workflow_id=task.workflow_id
71
+ )
72
+
73
+ # No parameters
74
+ def action(*_args, **_kwargs):
75
+ self.func = args[0]
76
+ self._set_params()
77
+
78
+ task = self._get_task(kwargs=_kwargs)
79
+ contexts = self._get_context(kwargs=_kwargs)
80
+
81
+ if contexts:
82
+ return Context(
83
+ storage=self._retry(*_args, **contexts),
84
+ task_id=task.task_id,
85
+ workflow_id=task.workflow_id
86
+ )
87
+
88
+ return Context(
89
+ storage=self._retry(*_args),
90
+ task_id=task.task_id,
91
+ workflow_id=task.workflow_id
92
+ )
93
+
94
+ return action
95
+
96
+ def _retry(self, *args, **kwargs):
97
+ attempt = 0
98
+ exception = Exception()
99
+
100
+ while self.retry > attempt:
101
+ try:
102
+ return self.func(*args, **kwargs)
103
+ except Exception as error:
104
+ exception = error
105
+ attempt += 1
106
+
107
+ raise exception
108
+
109
+ def _set_params(self):
110
+ if isinstance(self.func, FunctionType):
111
+ self.params = [param for param in self.func.__code__.co_varnames]
112
+
113
+ if type(self.func) is type:
114
+ if hasattr(self.func, "__init__"):
115
+ if hasattr(self.func.__init__, "__code__"):
116
+ self.params = [param for param in self.func.__init__.__code__.co_varnames]
117
+
118
+ def _get_context(self, kwargs: Dict):
119
+ context = {}
120
+ if "initial_context" in self.params:
121
+ context["initial_context"] = Context(kwargs.get("initial_context"))
122
+
123
+ if "previous_context" in self.params:
124
+ context["previous_context"] = Context(kwargs.get("previous_context"))
125
+
126
+ return context
127
+
128
+ def _get_task(self, kwargs: Dict):
129
+ return kwargs.get("task")
@@ -0,0 +1,27 @@
1
+ """Config module"""
2
+
3
+ from dotflow.abc.storage import Storage
4
+ from dotflow.providers.storage_init import StorageInit
5
+
6
+
7
+ class Config:
8
+ """
9
+ Import:
10
+ You can import the **Config** class with:
11
+
12
+ from dotflow import Config, StorageInit
13
+
14
+ Example:
15
+ `class` dotflow.core.config.Config
16
+
17
+ config = Config(storage=StorageInit)
18
+
19
+ Args:
20
+ storage (Storage): Type of the storage.
21
+
22
+ Attributes:
23
+ storage (Storage):
24
+ """
25
+
26
+ def __init__(self, storage: Storage = StorageInit()) -> None:
27
+ self.storage = storage
@@ -0,0 +1,107 @@
1
+ """Context module"""
2
+
3
+ from uuid import UUID
4
+
5
+ from typing import Any
6
+ from datetime import datetime
7
+
8
+
9
+ class ContextInstance:
10
+ """
11
+ Import:
12
+ You can import the **ContextInstance** class with:
13
+
14
+ from dotflow.core.context import ContextInstance
15
+ """
16
+
17
+ def __init__(self, *args, **kwargs):
18
+ self._time = None
19
+ self._task_id = None
20
+ self._workflow_id = None
21
+ self._storage = None
22
+ self._current_key = None
23
+ self._previous_key = None
24
+
25
+
26
+ class Context(ContextInstance):
27
+ """
28
+ Import:
29
+ You can import the Context class directly from dotflow:
30
+
31
+ from dotflow import Context
32
+
33
+ Example:
34
+ `class` dotflow.core.context.Context
35
+
36
+ Context(
37
+ storage={"data": [0, 1, 2, 3]}
38
+ )
39
+
40
+ Args:
41
+ storage (Any): Attribute where any type of Python object can be stored.
42
+
43
+ task_id (int): Task ID.
44
+
45
+ workflow_id (UUID): Workflow ID.
46
+ """
47
+
48
+ def __init__(
49
+ self,
50
+ storage: Any = None,
51
+ task_id: int = None,
52
+ workflow_id: UUID = None,
53
+ ) -> None:
54
+ super().__init__(
55
+ task_id,
56
+ storage,
57
+ task_id,
58
+ workflow_id
59
+ )
60
+ self.time = datetime.now()
61
+ self.task_id = task_id
62
+ self.workflow_id = workflow_id
63
+ self.storage = storage
64
+
65
+ @property
66
+ def time(self):
67
+ return self._time
68
+
69
+ @time.setter
70
+ def time(self, value: datetime):
71
+ self._time = value
72
+
73
+ @property
74
+ def task_id(self):
75
+ return self._task_id
76
+
77
+ @task_id.setter
78
+ def task_id(self, value: int):
79
+ if isinstance(value, int):
80
+ self._task_id = value
81
+
82
+ if not self.task_id:
83
+ self._task_id = value
84
+
85
+ @property
86
+ def workflow_id(self):
87
+ return self._workflow_id
88
+
89
+ @workflow_id.setter
90
+ def workflow_id(self, value: UUID):
91
+ if isinstance(value, UUID):
92
+ self._workflow_id = value
93
+
94
+ @property
95
+ def storage(self):
96
+ return self._storage
97
+
98
+ @storage.setter
99
+ def storage(self, value: Any):
100
+ if isinstance(value, Context):
101
+ self._storage = value.storage
102
+
103
+ self.time = value.time
104
+ self.task_id = value.task_id
105
+ self.workflow_id = value.workflow_id
106
+ else:
107
+ self._storage = value
@@ -0,0 +1,8 @@
1
+ """Decorators __init__ module."""
2
+
3
+ from dotflow.core.decorators.time import time
4
+
5
+
6
+ __all__ = [
7
+ "time"
8
+ ]
@@ -4,6 +4,7 @@ from datetime import datetime
4
4
 
5
5
 
6
6
  def time(func):
7
+ """"Time Decorator"""
7
8
  def inside(*args, **kwargs):
8
9
  start = datetime.now()
9
10
  task = func(*args, **kwargs)
@@ -0,0 +1,75 @@
1
+ """DotFlow"""
2
+
3
+ from uuid import uuid4
4
+ from functools import partial
5
+
6
+ from dotflow.core.config import Config
7
+ from dotflow.core.workflow import Workflow
8
+ from dotflow.core.task import TaskBuilder
9
+
10
+
11
+ class DotFlow:
12
+ """
13
+ Import:
14
+ You can import the **Dotflow** class directly from dotflow:
15
+
16
+ from dotflow import DotFlow, Config
17
+ from dotflow.storage import StorageFile
18
+
19
+ Example:
20
+ `class` dotflow.core.dotflow.Dotflow
21
+
22
+ config = Config(
23
+ storage=StorageFile()
24
+ )
25
+
26
+ workflow = DotFlow(config=config)
27
+
28
+ Args:
29
+ config (Config): Configuration class.
30
+
31
+ Attributes:
32
+ workflow_id (UUID):
33
+
34
+ task (List[Task]):
35
+
36
+ start (Workflow):
37
+ """
38
+
39
+ def __init__(
40
+ self,
41
+ config: Config = Config()
42
+ ) -> None:
43
+ self.workflow_id = uuid4()
44
+
45
+ self.task = TaskBuilder(
46
+ config=config,
47
+ workflow_id=self.workflow_id
48
+ )
49
+
50
+ self.start = partial(
51
+ Workflow,
52
+ tasks=self.task.queu,
53
+ id=self.workflow_id
54
+ )
55
+
56
+ def result_task(self):
57
+ """
58
+ Returns:
59
+ list (List[Task]): Returns a list of Task class.
60
+ """
61
+ return self.task.queu
62
+
63
+ def result_context(self):
64
+ """
65
+ Returns:
66
+ list (List[Context]): Returns a list of Context class.
67
+ """
68
+ return [task.current_context for task in self.task.queu]
69
+
70
+ def result_storage(self):
71
+ """
72
+ Returns:
73
+ list (List[Any]): Returns a list of assorted objects.
74
+ """
75
+ return [task.current_context.storage for task in self.task.queu]
@@ -4,8 +4,9 @@ MESSAGE_UNKNOWN_ERROR = "Unknown error, please check logs for more information."
4
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
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
- MESSAGE_MODULE_NOT_FOUND = "Problem importing the python module '{module}'."
7
+ MESSAGE_IMPORT_MODULE_ERROR = "Error importing Python module '{module}'."
8
8
  MESSAGE_PROBLEM_ORDERING = "Problem with correctly ordering functions of the '{name}' class."
9
+ MESSAGE_MODULE_NOT_FOUND = "Module '{module}' not found. Please install with 'pip install {library}'"
9
10
 
10
11
  class MissingActionDecorator(Exception):
11
12
 
@@ -23,11 +24,11 @@ class ExecutionModeNotExist(Exception):
23
24
  )
24
25
 
25
26
 
26
- class ModuleNotFound(Exception):
27
+ class ImportModuleError(Exception):
27
28
 
28
29
  def __init__(self, module: str):
29
- super(ModuleNotFound, self).__init__(
30
- MESSAGE_MODULE_NOT_FOUND.format(
30
+ super(ImportModuleError, self).__init__(
31
+ MESSAGE_IMPORT_MODULE_ERROR.format(
31
32
  module=module
32
33
  )
33
34
  )
@@ -50,4 +51,15 @@ class ProblemOrdering(Exception):
50
51
  MESSAGE_PROBLEM_ORDERING.format(
51
52
  name=name
52
53
  )
53
- )
54
+ )
55
+
56
+
57
+ class ModuleNotFound(Exception):
58
+
59
+ def __init__(self, module: str, library: str):
60
+ super(ModuleNotFound, self).__init__(
61
+ MESSAGE_MODULE_NOT_FOUND.format(
62
+ module=module,
63
+ library=library
64
+ )
65
+ )