dotflow 0.9.0.dev2__tar.gz → 0.10.0__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.dev2 → dotflow-0.10.0}/PKG-INFO +100 -18
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/README.md +96 -17
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/__init__.py +3 -11
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/abc/file.py +1 -1
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/abc/http.py +1 -1
- dotflow-0.10.0/dotflow/abc/storage.py +25 -0
- dotflow-0.10.0/dotflow/cli/commands/start.py +35 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/cli/setup.py +4 -8
- dotflow-0.10.0/dotflow/core/action.py +129 -0
- dotflow-0.10.0/dotflow/core/config.py +28 -0
- dotflow-0.10.0/dotflow/core/context.py +105 -0
- dotflow-0.10.0/dotflow/core/decorators/__init__.py +8 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/decorators/time.py +1 -0
- dotflow-0.10.0/dotflow/core/dotflow.py +75 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/exception.py +17 -5
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/execution.py +22 -5
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/module.py +2 -2
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/task.py +94 -59
- dotflow-0.10.0/dotflow/core/types/execution.py +17 -0
- dotflow-0.10.0/dotflow/core/types/status.py +19 -0
- dotflow-0.10.0/dotflow/core/types/worflow.py +14 -0
- dotflow-0.10.0/dotflow/core/workflow.py +123 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/main.py +1 -0
- dotflow-0.10.0/dotflow/providers/__init__.py +6 -0
- dotflow-0.10.0/dotflow/providers/storage_default.py +20 -0
- dotflow-0.10.0/dotflow/providers/storage_file.py +66 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/settings.py +1 -0
- dotflow-0.10.0/dotflow/storage.py +21 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/utils/__init__.py +1 -3
- dotflow-0.10.0/dotflow/utils/tools.py +48 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/pyproject.toml +16 -3
- dotflow-0.9.0.dev2/dotflow/cli/commands/start.py +0 -31
- dotflow-0.9.0.dev2/dotflow/core/action.py +0 -70
- dotflow-0.9.0.dev2/dotflow/core/config.py +0 -21
- dotflow-0.9.0.dev2/dotflow/core/context.py +0 -15
- dotflow-0.9.0.dev2/dotflow/core/decorators/__init__.py +0 -12
- dotflow-0.9.0.dev2/dotflow/core/decorators/action.py +0 -17
- dotflow-0.9.0.dev2/dotflow/core/decorators/retry.py +0 -29
- dotflow-0.9.0.dev2/dotflow/core/dotflow.py +0 -37
- dotflow-0.9.0.dev2/dotflow/core/types/execution.py +0 -9
- dotflow-0.9.0.dev2/dotflow/core/types/status.py +0 -11
- dotflow-0.9.0.dev2/dotflow/core/types/worflow.py +0 -8
- dotflow-0.9.0.dev2/dotflow/core/workflow.py +0 -70
- dotflow-0.9.0.dev2/dotflow/providers/__init__.py +0 -1
- dotflow-0.9.0.dev2/dotflow/providers/zeromq.py +0 -49
- dotflow-0.9.0.dev2/dotflow/utils/tools.py +0 -47
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/LICENSE +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/abc/__init__.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/abc/tcp.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/cli/__init__.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/cli/command.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/cli/commands/__init__.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/cli/commands/init.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/cli/commands/log.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/cli/validators/__init__.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/cli/validators/start.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/__init__.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/serializers/__init__.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/serializers/task.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/serializers/transport.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/serializers/workflow.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/core/types/__init__.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/logging.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/utils/basic_functions.py +0 -0
- {dotflow-0.9.0.dev2 → dotflow-0.10.0}/dotflow/utils/error_handler.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dotflow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
4
4
|
Summary: 🎲 Dotflow turns an idea into flow!
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -34,8 +34,11 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
34
34
|
Classifier: Programming Language :: Python :: 3.10
|
|
35
35
|
Classifier: Programming Language :: Python :: 3.11
|
|
36
36
|
Classifier: Programming Language :: Python :: 3.12
|
|
37
|
+
Provides-Extra: mongodb
|
|
38
|
+
Requires-Dist: dotflow-mongodb ; extra == "mongodb"
|
|
37
39
|
Requires-Dist: pydantic
|
|
38
40
|
Requires-Dist: rich
|
|
41
|
+
Requires-Dist: typing-extensions
|
|
39
42
|
Project-URL: Documentation, https://github.com/dotflow-io/dotflow/blob/master/README.md
|
|
40
43
|
Project-URL: Homepage, https://github.com/dotflow-io/dotflow
|
|
41
44
|
Project-URL: Issues, https://github.com/dotflow-io/dotflow/issues
|
|
@@ -56,6 +59,33 @@ This is a very simple library that is still in the early stages of development.
|
|
|
56
59
|
|
|
57
60
|
Start with the basics [here](https://dotflow-io.github.io/dotflow/nav/getting-started/).
|
|
58
61
|
|
|
62
|
+
## Table of Contents
|
|
63
|
+
|
|
64
|
+
<details>
|
|
65
|
+
<summary>Click to expand</summary>
|
|
66
|
+
|
|
67
|
+
- [Getting Help](#getting-help)
|
|
68
|
+
- [Getting Started](#getting-started)
|
|
69
|
+
- [Install](#install)
|
|
70
|
+
- [A Simple Example](#a-simple-example)
|
|
71
|
+
- [First Steps](#first-steps)
|
|
72
|
+
- [Import](#import)
|
|
73
|
+
- [Callback function](#callback-function)
|
|
74
|
+
- [Task function](#task-function)
|
|
75
|
+
- [DotFlow Class](#dotflow-class)
|
|
76
|
+
- [Add Task](#add-task)
|
|
77
|
+
- [Start](#start)
|
|
78
|
+
- [CLI](#cli)
|
|
79
|
+
- [Simple Start](#simple-start)
|
|
80
|
+
- [With Initial Context](#with-initial-context)
|
|
81
|
+
- [With Callback](#with-callback)
|
|
82
|
+
- [With Mode](#with-mode)
|
|
83
|
+
- [More Examples](#more-examples)
|
|
84
|
+
- [Commit Style](#commit-style)
|
|
85
|
+
- [License](#license)
|
|
86
|
+
|
|
87
|
+
</details>
|
|
88
|
+
|
|
59
89
|
## Getting Help
|
|
60
90
|
|
|
61
91
|
We use GitHub issues for tracking bugs and feature requests and have limited bandwidth to address them. If you need anything, I ask you to please follow our templates for opening issues or discussions.
|
|
@@ -93,68 +123,120 @@ from dotflow import DotFlow, action
|
|
|
93
123
|
def my_callback(*args, **kwargs):
|
|
94
124
|
print(args, kwargs)
|
|
95
125
|
|
|
126
|
+
@action
|
|
127
|
+
def my_task_x():
|
|
128
|
+
print("task")
|
|
129
|
+
|
|
96
130
|
@action(retry=5)
|
|
97
|
-
def
|
|
131
|
+
def my_task_y():
|
|
98
132
|
print("task")
|
|
99
133
|
|
|
100
134
|
workflow = DotFlow()
|
|
101
|
-
|
|
135
|
+
|
|
136
|
+
workflow.task.add(step=my_task_x, callback=my_callback)
|
|
137
|
+
workflow.task.add(step=my_task_y, callback=my_callback)
|
|
138
|
+
|
|
102
139
|
workflow.start()
|
|
103
140
|
```
|
|
104
141
|
|
|
105
142
|
## First Steps
|
|
106
143
|
|
|
107
|
-
####
|
|
144
|
+
#### Import
|
|
108
145
|
|
|
109
|
-
Start with the basics, which is importing the necessary classes and methods. ([DotFlow](https://dotflow-io.github.io/dotflow/nav/reference/dotflow
|
|
146
|
+
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
147
|
|
|
111
148
|
```python
|
|
112
149
|
from dotflow import DotFlow, action
|
|
113
150
|
```
|
|
114
151
|
|
|
115
|
-
####
|
|
152
|
+
#### Callback function
|
|
116
153
|
|
|
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.
|
|
154
|
+
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
155
|
|
|
119
156
|
```python
|
|
120
157
|
def my_callback(*args, **kwargs):
|
|
121
158
|
print(args, kwargs)
|
|
122
159
|
```
|
|
123
160
|
|
|
124
|
-
####
|
|
161
|
+
#### Task function
|
|
125
162
|
|
|
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
|
|
163
|
+
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
164
|
|
|
128
165
|
```python
|
|
129
166
|
@action(retry=5)
|
|
130
|
-
def
|
|
167
|
+
def my_task_x():
|
|
131
168
|
print("task")
|
|
132
169
|
```
|
|
133
170
|
|
|
134
|
-
####
|
|
171
|
+
#### DotFlow Class
|
|
135
172
|
|
|
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
|
|
173
|
+
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
174
|
|
|
138
175
|
```python
|
|
139
176
|
workflow = DotFlow()
|
|
140
177
|
```
|
|
141
178
|
|
|
142
|
-
####
|
|
179
|
+
#### Add Task
|
|
143
180
|
|
|
144
|
-
Now, simply add the `
|
|
181
|
+
Now, simply add the `my_task_x` 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)
|
|
182
|
+
|
|
183
|
+
- Adding one step at a time:
|
|
145
184
|
|
|
146
185
|
```python
|
|
147
|
-
workflow.task.add(step=
|
|
186
|
+
workflow.task.add(step=my_task_x, callback=my_callback)
|
|
187
|
+
workflow.task.add(step=my_task_y, callback=my_callback)
|
|
148
188
|
```
|
|
149
189
|
|
|
150
|
-
|
|
190
|
+
- Adding multiple steps at the same time:
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
workflow.task.add(step=[my_task_x, my_task_y], callback=my_callback)
|
|
194
|
+
```
|
|
151
195
|
|
|
152
|
-
|
|
196
|
+
- Adding a step with the module path:
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
workflow.task.add(step="module.task.my_task_x", callback=my_callback)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### Start
|
|
203
|
+
|
|
204
|
+
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
205
|
|
|
154
206
|
```python
|
|
155
207
|
workflow.start()
|
|
156
208
|
```
|
|
157
209
|
|
|
210
|
+
## CLI
|
|
211
|
+
|
|
212
|
+
#### Simple Start
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
dotflow start --step examples.cli_with_mode.simple_step
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
#### With Initial Context
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
dotflow start --step examples.cli_with_initial_context.simple_step --initial-context abc
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### With Callback
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
dotflow start --step examples.cli_with_callback.simple_step --callback examples.cli_with_callback.callback
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### With Mode
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
dotflow start --step examples.cli_with_mode.simple_step --mode sequential
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
dotflow start --step examples.cli_with_mode.simple_step --mode background
|
|
238
|
+
```
|
|
239
|
+
|
|
158
240
|
## More Examples
|
|
159
241
|
|
|
160
242
|
| | Example |
|
|
@@ -196,7 +278,7 @@ workflow.start()
|
|
|
196
278
|
- ⚠️ SECURITY
|
|
197
279
|
|
|
198
280
|
## License
|
|
199
|
-

|
|
200
282
|
|
|
201
283
|
This project is licensed under the terms of the MIT License.
|
|
202
284
|
|
|
@@ -12,6 +12,33 @@ This is a very simple library that is still in the early stages of development.
|
|
|
12
12
|
|
|
13
13
|
Start with the basics [here](https://dotflow-io.github.io/dotflow/nav/getting-started/).
|
|
14
14
|
|
|
15
|
+
## Table of Contents
|
|
16
|
+
|
|
17
|
+
<details>
|
|
18
|
+
<summary>Click to expand</summary>
|
|
19
|
+
|
|
20
|
+
- [Getting Help](#getting-help)
|
|
21
|
+
- [Getting Started](#getting-started)
|
|
22
|
+
- [Install](#install)
|
|
23
|
+
- [A Simple Example](#a-simple-example)
|
|
24
|
+
- [First Steps](#first-steps)
|
|
25
|
+
- [Import](#import)
|
|
26
|
+
- [Callback function](#callback-function)
|
|
27
|
+
- [Task function](#task-function)
|
|
28
|
+
- [DotFlow Class](#dotflow-class)
|
|
29
|
+
- [Add Task](#add-task)
|
|
30
|
+
- [Start](#start)
|
|
31
|
+
- [CLI](#cli)
|
|
32
|
+
- [Simple Start](#simple-start)
|
|
33
|
+
- [With Initial Context](#with-initial-context)
|
|
34
|
+
- [With Callback](#with-callback)
|
|
35
|
+
- [With Mode](#with-mode)
|
|
36
|
+
- [More Examples](#more-examples)
|
|
37
|
+
- [Commit Style](#commit-style)
|
|
38
|
+
- [License](#license)
|
|
39
|
+
|
|
40
|
+
</details>
|
|
41
|
+
|
|
15
42
|
## Getting Help
|
|
16
43
|
|
|
17
44
|
We use GitHub issues for tracking bugs and feature requests and have limited bandwidth to address them. If you need anything, I ask you to please follow our templates for opening issues or discussions.
|
|
@@ -49,68 +76,120 @@ from dotflow import DotFlow, action
|
|
|
49
76
|
def my_callback(*args, **kwargs):
|
|
50
77
|
print(args, kwargs)
|
|
51
78
|
|
|
79
|
+
@action
|
|
80
|
+
def my_task_x():
|
|
81
|
+
print("task")
|
|
82
|
+
|
|
52
83
|
@action(retry=5)
|
|
53
|
-
def
|
|
84
|
+
def my_task_y():
|
|
54
85
|
print("task")
|
|
55
86
|
|
|
56
87
|
workflow = DotFlow()
|
|
57
|
-
|
|
88
|
+
|
|
89
|
+
workflow.task.add(step=my_task_x, callback=my_callback)
|
|
90
|
+
workflow.task.add(step=my_task_y, callback=my_callback)
|
|
91
|
+
|
|
58
92
|
workflow.start()
|
|
59
93
|
```
|
|
60
94
|
|
|
61
95
|
## First Steps
|
|
62
96
|
|
|
63
|
-
####
|
|
97
|
+
#### Import
|
|
64
98
|
|
|
65
|
-
Start with the basics, which is importing the necessary classes and methods. ([DotFlow](https://dotflow-io.github.io/dotflow/nav/reference/dotflow
|
|
99
|
+
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
100
|
|
|
67
101
|
```python
|
|
68
102
|
from dotflow import DotFlow, action
|
|
69
103
|
```
|
|
70
104
|
|
|
71
|
-
####
|
|
105
|
+
#### Callback function
|
|
72
106
|
|
|
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.
|
|
107
|
+
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
108
|
|
|
75
109
|
```python
|
|
76
110
|
def my_callback(*args, **kwargs):
|
|
77
111
|
print(args, kwargs)
|
|
78
112
|
```
|
|
79
113
|
|
|
80
|
-
####
|
|
114
|
+
#### Task function
|
|
81
115
|
|
|
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
|
|
116
|
+
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
117
|
|
|
84
118
|
```python
|
|
85
119
|
@action(retry=5)
|
|
86
|
-
def
|
|
120
|
+
def my_task_x():
|
|
87
121
|
print("task")
|
|
88
122
|
```
|
|
89
123
|
|
|
90
|
-
####
|
|
124
|
+
#### DotFlow Class
|
|
91
125
|
|
|
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
|
|
126
|
+
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
127
|
|
|
94
128
|
```python
|
|
95
129
|
workflow = DotFlow()
|
|
96
130
|
```
|
|
97
131
|
|
|
98
|
-
####
|
|
132
|
+
#### Add Task
|
|
99
133
|
|
|
100
|
-
Now, simply add the `
|
|
134
|
+
Now, simply add the `my_task_x` 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)
|
|
135
|
+
|
|
136
|
+
- Adding one step at a time:
|
|
101
137
|
|
|
102
138
|
```python
|
|
103
|
-
workflow.task.add(step=
|
|
139
|
+
workflow.task.add(step=my_task_x, callback=my_callback)
|
|
140
|
+
workflow.task.add(step=my_task_y, callback=my_callback)
|
|
104
141
|
```
|
|
105
142
|
|
|
106
|
-
|
|
143
|
+
- Adding multiple steps at the same time:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
workflow.task.add(step=[my_task_x, my_task_y], callback=my_callback)
|
|
147
|
+
```
|
|
107
148
|
|
|
108
|
-
|
|
149
|
+
- Adding a step with the module path:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
workflow.task.add(step="module.task.my_task_x", callback=my_callback)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### Start
|
|
156
|
+
|
|
157
|
+
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
158
|
|
|
110
159
|
```python
|
|
111
160
|
workflow.start()
|
|
112
161
|
```
|
|
113
162
|
|
|
163
|
+
## CLI
|
|
164
|
+
|
|
165
|
+
#### Simple Start
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
dotflow start --step examples.cli_with_mode.simple_step
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### With Initial Context
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
dotflow start --step examples.cli_with_initial_context.simple_step --initial-context abc
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### With Callback
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
dotflow start --step examples.cli_with_callback.simple_step --callback examples.cli_with_callback.callback
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
#### With Mode
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
dotflow start --step examples.cli_with_mode.simple_step --mode sequential
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
dotflow start --step examples.cli_with_mode.simple_step --mode background
|
|
191
|
+
```
|
|
192
|
+
|
|
114
193
|
## More Examples
|
|
115
194
|
|
|
116
195
|
| | Example |
|
|
@@ -152,6 +231,6 @@ workflow.start()
|
|
|
152
231
|
- ⚠️ SECURITY
|
|
153
232
|
|
|
154
233
|
## License
|
|
155
|
-

|
|
156
235
|
|
|
157
236
|
This project is licensed under the terms of the MIT License.
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
"""Dotflow __init__ module."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.
|
|
3
|
+
__version__ = "0.10.0"
|
|
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
|
-
__all__ = [
|
|
15
|
-
"action",
|
|
16
|
-
"retry",
|
|
17
|
-
"DotFlow",
|
|
18
|
-
"Context",
|
|
19
|
-
"Config",
|
|
20
|
-
"Task"
|
|
21
|
-
]
|
|
13
|
+
__all__ = ["action", "Context", "Config", "DotFlow", "Task"]
|
|
@@ -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
|
+
pass
|
|
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 StorageDefault, 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": StorageDefault, "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
|
-
|
|
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
|
|
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,28 @@
|
|
|
1
|
+
"""Config module"""
|
|
2
|
+
|
|
3
|
+
from dotflow.abc.storage import Storage
|
|
4
|
+
from dotflow.providers.storage_default import StorageDefault
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Config:
|
|
8
|
+
"""
|
|
9
|
+
Import:
|
|
10
|
+
You can import the **Config** class with:
|
|
11
|
+
|
|
12
|
+
from dotflow import Config
|
|
13
|
+
from dotflow.storage import StorageDefault
|
|
14
|
+
|
|
15
|
+
Example:
|
|
16
|
+
`class` dotflow.core.config.Config
|
|
17
|
+
|
|
18
|
+
config = Config(storage=StorageDefault)
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
storage (Storage): Type of the storage.
|
|
22
|
+
|
|
23
|
+
Attributes:
|
|
24
|
+
storage (Storage):
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, storage: Storage = StorageDefault()) -> None:
|
|
28
|
+
self.storage = storage
|