dotflow 0.13.0.dev1__tar.gz → 0.13.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.13.0.dev1 → dotflow-0.13.0.dev2}/PKG-INFO +48 -41
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/README.md +46 -40
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/__init__.py +1 -1
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/action.py +27 -3
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/config.py +7 -6
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/dotflow.py +1 -1
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/execution.py +4 -2
- dotflow-0.13.0.dev2/dotflow/core/serializers/task.py +83 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/task.py +4 -6
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/workflow.py +16 -13
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/providers/notify_telegram.py +10 -8
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/pyproject.toml +7 -3
- dotflow-0.13.0.dev1/dotflow/core/serializers/task.py +0 -47
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/LICENSE +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/abc/__init__.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/abc/file.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/abc/flow.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/abc/http.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/abc/log.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/abc/notify.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/abc/storage.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/abc/tcp.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/cli/__init__.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/cli/command.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/cli/commands/__init__.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/cli/commands/init.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/cli/commands/log.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/cli/commands/start.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/cli/setup.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/cli/validators/__init__.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/cli/validators/start.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/__init__.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/context.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/decorators/__init__.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/decorators/time.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/exception.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/module.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/serializers/__init__.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/serializers/transport.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/serializers/workflow.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/types/__init__.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/types/execution.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/types/status.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/types/storage.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/core/types/worflow.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/logging.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/main.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/notify.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/providers/__init__.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/providers/log_default.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/providers/notify_default.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/providers/storage_default.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/providers/storage_file.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/providers.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/settings.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/storage.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/types.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/utils/__init__.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/utils/basic_functions.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/utils/error_handler.py +0 -0
- {dotflow-0.13.0.dev1 → dotflow-0.13.0.dev2}/dotflow/utils/tools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dotflow
|
|
3
|
-
Version: 0.13.0.
|
|
3
|
+
Version: 0.13.0.dev2
|
|
4
4
|
Summary: 🎲 Dotflow turns an idea into flow!
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -34,6 +34,7 @@ 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
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
37
38
|
Provides-Extra: mongodb
|
|
38
39
|
Requires-Dist: dotflow-mongodb ; extra == "mongodb"
|
|
39
40
|
Requires-Dist: pydantic
|
|
@@ -144,7 +145,7 @@ def my_callback(*args, **kwargs):
|
|
|
144
145
|
def my_task_x():
|
|
145
146
|
print("task")
|
|
146
147
|
|
|
147
|
-
@action
|
|
148
|
+
@action
|
|
148
149
|
def my_task_y():
|
|
149
150
|
print("task")
|
|
150
151
|
|
|
@@ -158,7 +159,7 @@ workflow.start()
|
|
|
158
159
|
|
|
159
160
|
## First Steps
|
|
160
161
|
|
|
161
|
-
#### Import
|
|
162
|
+
#### 1. Import
|
|
162
163
|
|
|
163
164
|
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/))
|
|
164
165
|
|
|
@@ -166,7 +167,7 @@ Start with the basics, which is importing the necessary classes and methods. ([D
|
|
|
166
167
|
from dotflow import DotFlow, action
|
|
167
168
|
```
|
|
168
169
|
|
|
169
|
-
#### Callback function
|
|
170
|
+
#### 2. Callback function
|
|
170
171
|
|
|
171
172
|
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)
|
|
172
173
|
|
|
@@ -175,17 +176,17 @@ def my_callback(*args, **kwargs):
|
|
|
175
176
|
print(args, kwargs)
|
|
176
177
|
```
|
|
177
178
|
|
|
178
|
-
#### Task function
|
|
179
|
+
#### 3. Task function
|
|
179
180
|
|
|
180
|
-
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.
|
|
181
|
+
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.
|
|
181
182
|
|
|
182
183
|
```python
|
|
183
|
-
@action
|
|
184
|
+
@action
|
|
184
185
|
def my_task_x():
|
|
185
186
|
print("task")
|
|
186
187
|
```
|
|
187
188
|
|
|
188
|
-
#### DotFlow Class
|
|
189
|
+
#### 4. DotFlow Class
|
|
189
190
|
|
|
190
191
|
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/).
|
|
191
192
|
|
|
@@ -193,7 +194,7 @@ Instantiate the DotFlow class in a `workflow` variable to be used in the followi
|
|
|
193
194
|
workflow = DotFlow()
|
|
194
195
|
```
|
|
195
196
|
|
|
196
|
-
#### Add Task
|
|
197
|
+
#### 5. Add Task
|
|
197
198
|
|
|
198
199
|
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)
|
|
199
200
|
|
|
@@ -216,7 +217,7 @@ workflow.task.add(step=[my_task_x, my_task_y], callback=my_callback)
|
|
|
216
217
|
workflow.task.add(step="module.task.my_task_x", callback=my_callback)
|
|
217
218
|
```
|
|
218
219
|
|
|
219
|
-
#### Start
|
|
220
|
+
#### 6. Start
|
|
220
221
|
|
|
221
222
|
Finally, just execute the workflow with the following code snippet. [More details](https://dotflow-io.github.io/dotflow/nav/reference/workflow/#dotflow.core.workflow.Manager)
|
|
222
223
|
|
|
@@ -358,37 +359,43 @@ flowchart TD
|
|
|
358
359
|
|
|
359
360
|
## More Examples
|
|
360
361
|
|
|
361
|
-
| Example
|
|
362
|
-
|
|
|
363
|
-
| [cli_with_callback](https://github.com/dotflow-io/examples/blob/master/cli_with_callback.py)
|
|
364
|
-
| [cli_with_initial_context](https://github.com/dotflow-io/examples/blob/master/cli_with_initial_context.py)
|
|
365
|
-
| [cli_with_mode](https://github.com/dotflow-io/examples/blob/master/cli_with_mode.py)
|
|
366
|
-
| [cli_with_output_context](https://github.com/dotflow-io/examples/blob/master/cli_with_output_context.py)
|
|
367
|
-
| [cli_with_path](https://github.com/dotflow-io/examples/blob/master/cli_with_path.py)
|
|
368
|
-
| [
|
|
369
|
-
| [simple_class_workflow](https://github.com/dotflow-io/examples/blob/master/simple_class_workflow.py)
|
|
370
|
-
| [
|
|
371
|
-
| [simple_function_workflow](https://github.com/dotflow-io/examples/blob/master/simple_function_workflow.py)
|
|
372
|
-
| [
|
|
373
|
-
| [
|
|
374
|
-
| [
|
|
375
|
-
| [
|
|
376
|
-
| [
|
|
377
|
-
| [
|
|
378
|
-
| [
|
|
379
|
-
| [
|
|
380
|
-
| [
|
|
381
|
-
| [
|
|
382
|
-
| [
|
|
383
|
-
| [
|
|
384
|
-
| [
|
|
385
|
-
| [
|
|
386
|
-
| [
|
|
387
|
-
| [
|
|
388
|
-
| [workflow_parallel_mode](https://github.com/dotflow-io/examples/blob/master/workflow_parallel_mode.py)
|
|
389
|
-
| [workflow_sequential_group_mode](https://github.com/dotflow-io/examples/blob/master/workflow_sequential_group_mode.py)
|
|
390
|
-
| [workflow_sequential_mode](https://github.com/dotflow-io/examples/blob/master/workflow_sequential_mode.py)
|
|
391
|
-
|
|
362
|
+
| Example | Command |
|
|
363
|
+
| ------- | ------- |
|
|
364
|
+
| [cli_with_callback](https://github.com/dotflow-io/examples/blob/master/cli_with_callback.py) | `dotflow start --step examples.cli_with_callback.simple_step --callback examples.cli_with_callback.callback` |
|
|
365
|
+
| [cli_with_initial_context](https://github.com/dotflow-io/examples/blob/master/cli_with_initial_context.py) | `dotflow start --step examples.cli_with_initial_context.simple_step --initial-context abc` |
|
|
366
|
+
| [cli_with_mode](https://github.com/dotflow-io/examples/blob/master/cli_with_mode.py) | `dotflow start --step examples.cli_with_mode.simple_step --mode sequential` |
|
|
367
|
+
| [cli_with_output_context](https://github.com/dotflow-io/examples/blob/master/cli_with_output_context.py) | `dotflow start --step examples.cli_with_output_context.simple_step --storage file` |
|
|
368
|
+
| [cli_with_path](https://github.com/dotflow-io/examples/blob/master/cli_with_path.py) | `dotflow start --step examples.cli_with_path.simple_step --path .storage --storage file` |
|
|
369
|
+
| [flow](https://github.com/dotflow-io/examples/blob/master/flow.py) | `python examples/flow.py` |
|
|
370
|
+
| [simple_class_workflow](https://github.com/dotflow-io/examples/blob/master/simple_class_workflow.py) | `python examples/simple_class_workflow.py` |
|
|
371
|
+
| [simple_cli](https://github.com/dotflow-io/examples/blob/master/simple_cli.py) | `dotflow start --step examples.simple_cli.simple_step` |
|
|
372
|
+
| [simple_function_workflow](https://github.com/dotflow-io/examples/blob/master/simple_function_workflow.py) | `python examples/simple_function_workflow.py` |
|
|
373
|
+
| [simple_function_workflow_with_error](https://github.com/dotflow-io/examples/blob/master/simple_function_workflow_with_error.py) | `python examples/simple_function_workflow_with_error.py` |
|
|
374
|
+
| [step_class_result_context](https://github.com/dotflow-io/examples/blob/master/step_class_result_context.py) | `python examples/step_class_result_context.py` |
|
|
375
|
+
| [step_class_result_storage](https://github.com/dotflow-io/examples/blob/master/step_class_result_storage.py) | `python examples/step_class_result_storage.py` |
|
|
376
|
+
| [step_class_result_task](https://github.com/dotflow-io/examples/blob/master/step_class_result_task.py) | `python examples/step_class_result_task.py` |
|
|
377
|
+
| [step_function_result_context](https://github.com/dotflow-io/examples/blob/master/step_function_result_context.py) | `python examples/step_function_result_context.py` |
|
|
378
|
+
| [step_function_result_storage](https://github.com/dotflow-io/examples/blob/master/step_function_result_storage.py) | `python examples/step_function_result_storage.py` |
|
|
379
|
+
| [step_function_result_task](https://github.com/dotflow-io/examples/blob/master/step_function_result_task.py) | `python examples/step_function_result_task.py` |
|
|
380
|
+
| [step_with_groups](https://github.com/dotflow-io/examples/blob/master/step_with_groups.py) | `python examples/step_with_groups.py` |
|
|
381
|
+
| [step_with_initial_context](https://github.com/dotflow-io/examples/blob/master/step_with_initial_context.py) | `python examples/step_with_initial_context.py` |
|
|
382
|
+
| [step_with_many_contexts](https://github.com/dotflow-io/examples/blob/master/step_with_many_contexts.py) | `python examples/step_with_many_contexts.py` |
|
|
383
|
+
| [step_with_notify_telegram](https://github.com/dotflow-io/examples/blob/master/step_with_notify_telegram.py) | `python examples/step_with_notify_telegram.py` |
|
|
384
|
+
| [step_with_previous_context](https://github.com/dotflow-io/examples/blob/master/step_with_previous_context.py) | `python examples/step_with_previous_context.py` |
|
|
385
|
+
| [step_with_storage_file](https://github.com/dotflow-io/examples/blob/master/step_with_storage_file.py) | `python examples/step_with_storage_file.py` |
|
|
386
|
+
| [step_with_storage_mongodb](https://github.com/dotflow-io/examples/blob/master/step_with_storage_mongodb.py) | `python examples/step_with_storage_mongodb.py` |
|
|
387
|
+
| [workflow_background_mode](https://github.com/dotflow-io/examples/blob/master/workflow_background_mode.py) | `python examples/workflow_background_mode.py` |
|
|
388
|
+
| [workflow_keep_going_true](https://github.com/dotflow-io/examples/blob/master/workflow_keep_going_true.py) | `python examples/workflow_keep_going_true.py` |
|
|
389
|
+
| [workflow_parallel_mode](https://github.com/dotflow-io/examples/blob/master/workflow_parallel_mode.py) | `python examples/workflow_parallel_mode.py` |
|
|
390
|
+
| [workflow_sequential_group_mode](https://github.com/dotflow-io/examples/blob/master/workflow_sequential_group_mode.py) | `python examples/workflow_sequential_group_mode.py` |
|
|
391
|
+
| [workflow_sequential_mode](https://github.com/dotflow-io/examples/blob/master/workflow_sequential_mode.py) | `python examples/workflow_sequential_mode.py` |
|
|
392
|
+
| [workflow_step_callback](https://github.com/dotflow-io/examples/blob/master/workflow_step_callback.py) | `python examples/workflow_step_callback.py` |
|
|
393
|
+
| [workflow_with_backoff](https://github.com/dotflow-io/examples/blob/master/workflow_with_backoff.py) | `python examples/workflow_with_backoff.py` |
|
|
394
|
+
| [workflow_with_callback_failure](https://github.com/dotflow-io/examples/blob/master/workflow_with_callback_failure.py) | `python examples/workflow_with_callback_failure.py` |
|
|
395
|
+
| [workflow_with_callback_success](https://github.com/dotflow-io/examples/blob/master/workflow_with_callback_success.py) | `python examples/workflow_with_callback_success.py` |
|
|
396
|
+
| [workflow_with_retry](https://github.com/dotflow-io/examples/blob/master/workflow_with_retry.py) | `python examples/workflow_with_retry.py` |
|
|
397
|
+
| [workflow_with_retry_delay](https://github.com/dotflow-io/examples/blob/master/workflow_with_retry_delay.py) | `python examples/workflow_with_retry_delay.py` |
|
|
398
|
+
| [workflow_with_timeout](https://github.com/dotflow-io/examples/blob/master/workflow_with_timeout.py) | `python examples/workflow_with_timeout.py` |
|
|
392
399
|
|
|
393
400
|
## Commit Style
|
|
394
401
|
|
|
@@ -96,7 +96,7 @@ def my_callback(*args, **kwargs):
|
|
|
96
96
|
def my_task_x():
|
|
97
97
|
print("task")
|
|
98
98
|
|
|
99
|
-
@action
|
|
99
|
+
@action
|
|
100
100
|
def my_task_y():
|
|
101
101
|
print("task")
|
|
102
102
|
|
|
@@ -110,7 +110,7 @@ workflow.start()
|
|
|
110
110
|
|
|
111
111
|
## First Steps
|
|
112
112
|
|
|
113
|
-
#### Import
|
|
113
|
+
#### 1. Import
|
|
114
114
|
|
|
115
115
|
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/))
|
|
116
116
|
|
|
@@ -118,7 +118,7 @@ Start with the basics, which is importing the necessary classes and methods. ([D
|
|
|
118
118
|
from dotflow import DotFlow, action
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
-
#### Callback function
|
|
121
|
+
#### 2. Callback function
|
|
122
122
|
|
|
123
123
|
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)
|
|
124
124
|
|
|
@@ -127,17 +127,17 @@ def my_callback(*args, **kwargs):
|
|
|
127
127
|
print(args, kwargs)
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
#### Task function
|
|
130
|
+
#### 3. Task function
|
|
131
131
|
|
|
132
|
-
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.
|
|
132
|
+
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.
|
|
133
133
|
|
|
134
134
|
```python
|
|
135
|
-
@action
|
|
135
|
+
@action
|
|
136
136
|
def my_task_x():
|
|
137
137
|
print("task")
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
#### DotFlow Class
|
|
140
|
+
#### 4. DotFlow Class
|
|
141
141
|
|
|
142
142
|
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/).
|
|
143
143
|
|
|
@@ -145,7 +145,7 @@ Instantiate the DotFlow class in a `workflow` variable to be used in the followi
|
|
|
145
145
|
workflow = DotFlow()
|
|
146
146
|
```
|
|
147
147
|
|
|
148
|
-
#### Add Task
|
|
148
|
+
#### 5. Add Task
|
|
149
149
|
|
|
150
150
|
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)
|
|
151
151
|
|
|
@@ -168,7 +168,7 @@ workflow.task.add(step=[my_task_x, my_task_y], callback=my_callback)
|
|
|
168
168
|
workflow.task.add(step="module.task.my_task_x", callback=my_callback)
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
-
#### Start
|
|
171
|
+
#### 6. Start
|
|
172
172
|
|
|
173
173
|
Finally, just execute the workflow with the following code snippet. [More details](https://dotflow-io.github.io/dotflow/nav/reference/workflow/#dotflow.core.workflow.Manager)
|
|
174
174
|
|
|
@@ -310,37 +310,43 @@ flowchart TD
|
|
|
310
310
|
|
|
311
311
|
## More Examples
|
|
312
312
|
|
|
313
|
-
| Example
|
|
314
|
-
|
|
|
315
|
-
| [cli_with_callback](https://github.com/dotflow-io/examples/blob/master/cli_with_callback.py)
|
|
316
|
-
| [cli_with_initial_context](https://github.com/dotflow-io/examples/blob/master/cli_with_initial_context.py)
|
|
317
|
-
| [cli_with_mode](https://github.com/dotflow-io/examples/blob/master/cli_with_mode.py)
|
|
318
|
-
| [cli_with_output_context](https://github.com/dotflow-io/examples/blob/master/cli_with_output_context.py)
|
|
319
|
-
| [cli_with_path](https://github.com/dotflow-io/examples/blob/master/cli_with_path.py)
|
|
320
|
-
| [
|
|
321
|
-
| [simple_class_workflow](https://github.com/dotflow-io/examples/blob/master/simple_class_workflow.py)
|
|
322
|
-
| [
|
|
323
|
-
| [simple_function_workflow](https://github.com/dotflow-io/examples/blob/master/simple_function_workflow.py)
|
|
324
|
-
| [
|
|
325
|
-
| [
|
|
326
|
-
| [
|
|
327
|
-
| [
|
|
328
|
-
| [
|
|
329
|
-
| [
|
|
330
|
-
| [
|
|
331
|
-
| [
|
|
332
|
-
| [
|
|
333
|
-
| [
|
|
334
|
-
| [
|
|
335
|
-
| [
|
|
336
|
-
| [
|
|
337
|
-
| [
|
|
338
|
-
| [
|
|
339
|
-
| [
|
|
340
|
-
| [workflow_parallel_mode](https://github.com/dotflow-io/examples/blob/master/workflow_parallel_mode.py)
|
|
341
|
-
| [workflow_sequential_group_mode](https://github.com/dotflow-io/examples/blob/master/workflow_sequential_group_mode.py)
|
|
342
|
-
| [workflow_sequential_mode](https://github.com/dotflow-io/examples/blob/master/workflow_sequential_mode.py)
|
|
343
|
-
|
|
313
|
+
| Example | Command |
|
|
314
|
+
| ------- | ------- |
|
|
315
|
+
| [cli_with_callback](https://github.com/dotflow-io/examples/blob/master/cli_with_callback.py) | `dotflow start --step examples.cli_with_callback.simple_step --callback examples.cli_with_callback.callback` |
|
|
316
|
+
| [cli_with_initial_context](https://github.com/dotflow-io/examples/blob/master/cli_with_initial_context.py) | `dotflow start --step examples.cli_with_initial_context.simple_step --initial-context abc` |
|
|
317
|
+
| [cli_with_mode](https://github.com/dotflow-io/examples/blob/master/cli_with_mode.py) | `dotflow start --step examples.cli_with_mode.simple_step --mode sequential` |
|
|
318
|
+
| [cli_with_output_context](https://github.com/dotflow-io/examples/blob/master/cli_with_output_context.py) | `dotflow start --step examples.cli_with_output_context.simple_step --storage file` |
|
|
319
|
+
| [cli_with_path](https://github.com/dotflow-io/examples/blob/master/cli_with_path.py) | `dotflow start --step examples.cli_with_path.simple_step --path .storage --storage file` |
|
|
320
|
+
| [flow](https://github.com/dotflow-io/examples/blob/master/flow.py) | `python examples/flow.py` |
|
|
321
|
+
| [simple_class_workflow](https://github.com/dotflow-io/examples/blob/master/simple_class_workflow.py) | `python examples/simple_class_workflow.py` |
|
|
322
|
+
| [simple_cli](https://github.com/dotflow-io/examples/blob/master/simple_cli.py) | `dotflow start --step examples.simple_cli.simple_step` |
|
|
323
|
+
| [simple_function_workflow](https://github.com/dotflow-io/examples/blob/master/simple_function_workflow.py) | `python examples/simple_function_workflow.py` |
|
|
324
|
+
| [simple_function_workflow_with_error](https://github.com/dotflow-io/examples/blob/master/simple_function_workflow_with_error.py) | `python examples/simple_function_workflow_with_error.py` |
|
|
325
|
+
| [step_class_result_context](https://github.com/dotflow-io/examples/blob/master/step_class_result_context.py) | `python examples/step_class_result_context.py` |
|
|
326
|
+
| [step_class_result_storage](https://github.com/dotflow-io/examples/blob/master/step_class_result_storage.py) | `python examples/step_class_result_storage.py` |
|
|
327
|
+
| [step_class_result_task](https://github.com/dotflow-io/examples/blob/master/step_class_result_task.py) | `python examples/step_class_result_task.py` |
|
|
328
|
+
| [step_function_result_context](https://github.com/dotflow-io/examples/blob/master/step_function_result_context.py) | `python examples/step_function_result_context.py` |
|
|
329
|
+
| [step_function_result_storage](https://github.com/dotflow-io/examples/blob/master/step_function_result_storage.py) | `python examples/step_function_result_storage.py` |
|
|
330
|
+
| [step_function_result_task](https://github.com/dotflow-io/examples/blob/master/step_function_result_task.py) | `python examples/step_function_result_task.py` |
|
|
331
|
+
| [step_with_groups](https://github.com/dotflow-io/examples/blob/master/step_with_groups.py) | `python examples/step_with_groups.py` |
|
|
332
|
+
| [step_with_initial_context](https://github.com/dotflow-io/examples/blob/master/step_with_initial_context.py) | `python examples/step_with_initial_context.py` |
|
|
333
|
+
| [step_with_many_contexts](https://github.com/dotflow-io/examples/blob/master/step_with_many_contexts.py) | `python examples/step_with_many_contexts.py` |
|
|
334
|
+
| [step_with_notify_telegram](https://github.com/dotflow-io/examples/blob/master/step_with_notify_telegram.py) | `python examples/step_with_notify_telegram.py` |
|
|
335
|
+
| [step_with_previous_context](https://github.com/dotflow-io/examples/blob/master/step_with_previous_context.py) | `python examples/step_with_previous_context.py` |
|
|
336
|
+
| [step_with_storage_file](https://github.com/dotflow-io/examples/blob/master/step_with_storage_file.py) | `python examples/step_with_storage_file.py` |
|
|
337
|
+
| [step_with_storage_mongodb](https://github.com/dotflow-io/examples/blob/master/step_with_storage_mongodb.py) | `python examples/step_with_storage_mongodb.py` |
|
|
338
|
+
| [workflow_background_mode](https://github.com/dotflow-io/examples/blob/master/workflow_background_mode.py) | `python examples/workflow_background_mode.py` |
|
|
339
|
+
| [workflow_keep_going_true](https://github.com/dotflow-io/examples/blob/master/workflow_keep_going_true.py) | `python examples/workflow_keep_going_true.py` |
|
|
340
|
+
| [workflow_parallel_mode](https://github.com/dotflow-io/examples/blob/master/workflow_parallel_mode.py) | `python examples/workflow_parallel_mode.py` |
|
|
341
|
+
| [workflow_sequential_group_mode](https://github.com/dotflow-io/examples/blob/master/workflow_sequential_group_mode.py) | `python examples/workflow_sequential_group_mode.py` |
|
|
342
|
+
| [workflow_sequential_mode](https://github.com/dotflow-io/examples/blob/master/workflow_sequential_mode.py) | `python examples/workflow_sequential_mode.py` |
|
|
343
|
+
| [workflow_step_callback](https://github.com/dotflow-io/examples/blob/master/workflow_step_callback.py) | `python examples/workflow_step_callback.py` |
|
|
344
|
+
| [workflow_with_backoff](https://github.com/dotflow-io/examples/blob/master/workflow_with_backoff.py) | `python examples/workflow_with_backoff.py` |
|
|
345
|
+
| [workflow_with_callback_failure](https://github.com/dotflow-io/examples/blob/master/workflow_with_callback_failure.py) | `python examples/workflow_with_callback_failure.py` |
|
|
346
|
+
| [workflow_with_callback_success](https://github.com/dotflow-io/examples/blob/master/workflow_with_callback_success.py) | `python examples/workflow_with_callback_success.py` |
|
|
347
|
+
| [workflow_with_retry](https://github.com/dotflow-io/examples/blob/master/workflow_with_retry.py) | `python examples/workflow_with_retry.py` |
|
|
348
|
+
| [workflow_with_retry_delay](https://github.com/dotflow-io/examples/blob/master/workflow_with_retry_delay.py) | `python examples/workflow_with_retry_delay.py` |
|
|
349
|
+
| [workflow_with_timeout](https://github.com/dotflow-io/examples/blob/master/workflow_with_timeout.py) | `python examples/workflow_with_timeout.py` |
|
|
344
350
|
|
|
345
351
|
## Commit Style
|
|
346
352
|
|
|
@@ -42,14 +42,38 @@ class Action(object):
|
|
|
42
42
|
def my_task():
|
|
43
43
|
print("task")
|
|
44
44
|
|
|
45
|
+
|
|
46
|
+
With Timeout
|
|
47
|
+
|
|
48
|
+
@action(timeout=60)
|
|
49
|
+
def my_task():
|
|
50
|
+
print("task")
|
|
51
|
+
|
|
52
|
+
With Retry delay
|
|
53
|
+
|
|
54
|
+
@action(retry=5, retry_delay=5)
|
|
55
|
+
def my_task():
|
|
56
|
+
print("task")
|
|
57
|
+
|
|
58
|
+
With Backoff
|
|
59
|
+
|
|
60
|
+
@action(retry=5, backoff=True)
|
|
61
|
+
def my_task():
|
|
62
|
+
print("task")
|
|
63
|
+
|
|
45
64
|
Args:
|
|
46
65
|
func (Callable):
|
|
47
66
|
|
|
48
67
|
task (Callable):
|
|
49
68
|
|
|
50
|
-
retry (int):
|
|
51
|
-
|
|
52
|
-
|
|
69
|
+
retry (int): Number of task retries on on_failure.
|
|
70
|
+
|
|
71
|
+
timeout (int): Execution timeout for a task. Duration (in seconds)
|
|
72
|
+
|
|
73
|
+
retry_delay (int): Retry delay on task on_failure. Duration (in seconds)
|
|
74
|
+
|
|
75
|
+
backoff (int): Exponential backoff
|
|
76
|
+
|
|
53
77
|
"""
|
|
54
78
|
|
|
55
79
|
def __init__(
|
|
@@ -17,6 +17,7 @@ class Config:
|
|
|
17
17
|
You can import the **Config** class with:
|
|
18
18
|
|
|
19
19
|
from dotflow import Config
|
|
20
|
+
|
|
20
21
|
from dotflow.providers import (
|
|
21
22
|
StorageDefault,
|
|
22
23
|
NotifyDefault,
|
|
@@ -45,10 +46,10 @@ class Config:
|
|
|
45
46
|
|
|
46
47
|
def __init__(
|
|
47
48
|
self,
|
|
48
|
-
storage: Optional[Storage] =
|
|
49
|
-
notify: Optional[Notify] =
|
|
50
|
-
log: Optional[Log] =
|
|
49
|
+
storage: Optional[Storage] = StorageDefault(),
|
|
50
|
+
notify: Optional[Notify] = NotifyDefault(),
|
|
51
|
+
log: Optional[Log] = LogDefault(),
|
|
51
52
|
) -> None:
|
|
52
|
-
self.storage = storage
|
|
53
|
-
self.notify = notify
|
|
54
|
-
self.log = log
|
|
53
|
+
self.storage = storage
|
|
54
|
+
self.notify = notify
|
|
55
|
+
self.log = log
|
|
@@ -15,7 +15,7 @@ class DotFlow:
|
|
|
15
15
|
You can import the **Dotflow** class directly from dotflow:
|
|
16
16
|
|
|
17
17
|
from dotflow import DotFlow, Config
|
|
18
|
-
from dotflow.
|
|
18
|
+
from dotflow.providers import StorageFile
|
|
19
19
|
|
|
20
20
|
Example:
|
|
21
21
|
`class` dotflow.core.dotflow.Dotflow
|
|
@@ -106,14 +106,15 @@ class Execution:
|
|
|
106
106
|
callable_list=callable_list, class_instance=class_instance
|
|
107
107
|
)
|
|
108
108
|
|
|
109
|
-
for
|
|
110
|
-
new_object = getattr(class_instance, new)
|
|
109
|
+
for index, new in enumerate(ordered_list):
|
|
110
|
+
new_object = getattr(class_instance, new[1])
|
|
111
111
|
try:
|
|
112
112
|
subcontext = new_object(
|
|
113
113
|
initial_context=self.task.initial_context,
|
|
114
114
|
previous_context=previous_context,
|
|
115
115
|
task=self.task,
|
|
116
116
|
)
|
|
117
|
+
subcontext.task_id = index
|
|
117
118
|
new_context.storage.append(subcontext)
|
|
118
119
|
previous_context = subcontext
|
|
119
120
|
|
|
@@ -127,6 +128,7 @@ class Execution:
|
|
|
127
128
|
previous_context=previous_context,
|
|
128
129
|
task=self.task,
|
|
129
130
|
)
|
|
131
|
+
subcontext.task_id = index
|
|
130
132
|
new_context.storage.append(subcontext)
|
|
131
133
|
previous_context = subcontext
|
|
132
134
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Task serializer module"""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
from uuid import UUID
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field, ConfigDict, field_validator
|
|
9
|
+
|
|
10
|
+
from dotflow.core.context import Context
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SerializerTaskError(BaseModel):
|
|
14
|
+
|
|
15
|
+
traceback: str
|
|
16
|
+
message: str
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SerializerTask(BaseModel):
|
|
20
|
+
model_config = ConfigDict(title="task")
|
|
21
|
+
|
|
22
|
+
task_id: int = Field(default=None)
|
|
23
|
+
workflow_id: Optional[UUID] = Field(default=None)
|
|
24
|
+
status: str = Field(default=None, alias="_status")
|
|
25
|
+
error: Optional[SerializerTaskError] = Field(default=None, alias="_error")
|
|
26
|
+
duration: Optional[float] = Field(default=None, alias="_duration")
|
|
27
|
+
initial_context: Any = Field(default=None, alias="_initial_context")
|
|
28
|
+
current_context: Any = Field(default=None, alias="_current_context")
|
|
29
|
+
previous_context: Any = Field(default=None, alias="_previous_context")
|
|
30
|
+
group_name: str = Field(default=None)
|
|
31
|
+
max: Optional[int] = Field(default=None, exclude=True)
|
|
32
|
+
size_message: Optional[str] = Field(default="Context size exceeded", exclude=True)
|
|
33
|
+
|
|
34
|
+
def model_dump_json(self, **kwargs) -> str:
|
|
35
|
+
dump_json = super().model_dump_json(serialize_as_any=True, **kwargs)
|
|
36
|
+
|
|
37
|
+
if self.max and len(dump_json) > self.max:
|
|
38
|
+
self.initial_context = self.size_message
|
|
39
|
+
self.current_context = self.size_message
|
|
40
|
+
self.previous_context = self.size_message
|
|
41
|
+
|
|
42
|
+
dump_json = super().model_dump_json(serialize_as_any=True, **kwargs)
|
|
43
|
+
|
|
44
|
+
return dump_json[0:self.max]
|
|
45
|
+
|
|
46
|
+
return dump_json
|
|
47
|
+
|
|
48
|
+
@field_validator("error", mode="before")
|
|
49
|
+
@classmethod
|
|
50
|
+
def error_validator(cls, value: str) -> str:
|
|
51
|
+
if value:
|
|
52
|
+
return SerializerTaskError(**value.__dict__)
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
@field_validator(
|
|
56
|
+
"initial_context", "current_context", "previous_context", mode="before"
|
|
57
|
+
)
|
|
58
|
+
@classmethod
|
|
59
|
+
def context_validator(cls, value: str) -> str:
|
|
60
|
+
if value and value.storage:
|
|
61
|
+
context = cls.context_loop(value=value)
|
|
62
|
+
return context
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def format_context(cls, value):
|
|
67
|
+
try:
|
|
68
|
+
return json.dumps(value.storage)
|
|
69
|
+
except TypeError:
|
|
70
|
+
return str(value.storage)
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def context_loop(cls, value):
|
|
74
|
+
if isinstance(value.storage, list):
|
|
75
|
+
contexts = {}
|
|
76
|
+
if any(isinstance(context, Context) for context in value.storage):
|
|
77
|
+
for context in value.storage:
|
|
78
|
+
if isinstance(context, Context):
|
|
79
|
+
contexts[context.task_id] = cls.context_loop(context)
|
|
80
|
+
else:
|
|
81
|
+
contexts[context.task_id] = cls.format_context(context)
|
|
82
|
+
return contexts
|
|
83
|
+
return cls.format_context(value=value)
|
|
@@ -228,13 +228,11 @@ class Task(TaskInstance):
|
|
|
228
228
|
def config(self, value: Config):
|
|
229
229
|
self._config = value
|
|
230
230
|
|
|
231
|
-
def schema(self) -> SerializerTask:
|
|
232
|
-
return SerializerTask(
|
|
233
|
-
**self.__dict__
|
|
234
|
-
)
|
|
231
|
+
def schema(self, max: int = None) -> SerializerTask:
|
|
232
|
+
return SerializerTask(**self.__dict__, max=max)
|
|
235
233
|
|
|
236
|
-
def result(self) -> SerializerWorkflow:
|
|
237
|
-
item = self.schema().model_dump_json()
|
|
234
|
+
def result(self, max: int = None) -> SerializerWorkflow:
|
|
235
|
+
item = self.schema(max=max).model_dump_json()
|
|
238
236
|
return json.loads(item)
|
|
239
237
|
|
|
240
238
|
|
|
@@ -47,8 +47,8 @@ class Manager:
|
|
|
47
47
|
|
|
48
48
|
workflow = Manager(
|
|
49
49
|
tasks=[tasks],
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
on_success=basic_callback,
|
|
51
|
+
on_failure=basic_callback,
|
|
52
52
|
keep_going=True
|
|
53
53
|
)
|
|
54
54
|
|
|
@@ -56,11 +56,11 @@ class Manager:
|
|
|
56
56
|
tasks (List[Task]):
|
|
57
57
|
A list containing objects of type Task.
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
on_success (Callable):
|
|
60
60
|
Success function to be executed after the completion of the entire
|
|
61
61
|
workflow. It's essentially a callback for successful scenarios.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
on_failure (Callable):
|
|
64
64
|
Failure function to be executed after the completion of the entire
|
|
65
65
|
workflow. It's essentially a callback for error scenarios
|
|
66
66
|
|
|
@@ -76,27 +76,30 @@ class Manager:
|
|
|
76
76
|
execution of a task. If it is **true**, the execution will continue;
|
|
77
77
|
if it is **False**, the workflow will stop.
|
|
78
78
|
|
|
79
|
-
workflow_id (UUID):
|
|
79
|
+
workflow_id (UUID): Workflow ID.
|
|
80
80
|
|
|
81
81
|
Attributes:
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
on_success (Callable):
|
|
83
|
+
|
|
84
|
+
on_failure (Callable):
|
|
85
|
+
|
|
84
86
|
workflow_id (UUID):
|
|
87
|
+
|
|
85
88
|
started (datetime):
|
|
86
89
|
"""
|
|
87
90
|
|
|
88
91
|
def __init__(
|
|
89
92
|
self,
|
|
90
93
|
tasks: List[Task],
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
on_success: Callable = basic_callback,
|
|
95
|
+
on_failure: Callable = basic_callback,
|
|
93
96
|
mode: TypeExecution = TypeExecution.SEQUENTIAL,
|
|
94
97
|
keep_going: bool = False,
|
|
95
98
|
workflow_id: UUID = None,
|
|
96
99
|
) -> None:
|
|
97
100
|
self.tasks = tasks
|
|
98
|
-
self.
|
|
99
|
-
self.
|
|
101
|
+
self.on_success = on_success
|
|
102
|
+
self.on_failure = on_failure
|
|
100
103
|
self.workflow_id = workflow_id or uuid4()
|
|
101
104
|
self.started = datetime.now()
|
|
102
105
|
|
|
@@ -118,9 +121,9 @@ class Manager:
|
|
|
118
121
|
final_status = [task.status for task in tasks]
|
|
119
122
|
|
|
120
123
|
if TypeStatus.FAILED in final_status:
|
|
121
|
-
self.
|
|
124
|
+
self.on_failure(tasks=tasks)
|
|
122
125
|
else:
|
|
123
|
-
self.
|
|
126
|
+
self.on_success(tasks=tasks)
|
|
124
127
|
|
|
125
128
|
def sequential(self, **kwargs) -> List[Task]:
|
|
126
129
|
if len(kwargs.get("groups", {})) > 1 and not is_darwin():
|
|
@@ -9,21 +9,23 @@ from dotflow.core.types.status import TypeStatus
|
|
|
9
9
|
from dotflow.abc.notify import Notify
|
|
10
10
|
from dotflow.logging import logger
|
|
11
11
|
|
|
12
|
-
MESSAGE = "{symbol} {status}\n```json\n{task}```\n{workflow_id}-{task_id}"
|
|
13
|
-
API_TELEGRAM = "https://api.telegram.org/bot{token}/sendMessage"
|
|
14
|
-
|
|
15
12
|
|
|
16
13
|
class NotifyTelegram(Notify):
|
|
17
14
|
|
|
15
|
+
MESSAGE = "{symbol} {status}\n```json\n{task}```\n{workflow_id}-{task_id}"
|
|
16
|
+
API_TELEGRAM = "https://api.telegram.org/bot{token}/sendMessage"
|
|
17
|
+
|
|
18
18
|
def __init__(
|
|
19
19
|
self,
|
|
20
20
|
token: str,
|
|
21
21
|
chat_id: int,
|
|
22
|
-
notification_type: Optional[TypeStatus] = None
|
|
22
|
+
notification_type: Optional[TypeStatus] = None,
|
|
23
|
+
timeout: int = 1.5
|
|
23
24
|
):
|
|
24
25
|
self.token = token
|
|
25
26
|
self.chat_id = chat_id
|
|
26
27
|
self.notification_type = notification_type
|
|
28
|
+
self.timeout = timeout
|
|
27
29
|
|
|
28
30
|
def send(self, task: Any) -> None:
|
|
29
31
|
if not self.notification_type or self.notification_type == task.status:
|
|
@@ -34,10 +36,10 @@ class NotifyTelegram(Notify):
|
|
|
34
36
|
}
|
|
35
37
|
try:
|
|
36
38
|
response = post(
|
|
37
|
-
url=API_TELEGRAM.format(token=self.token),
|
|
39
|
+
url=self.API_TELEGRAM.format(token=self.token),
|
|
38
40
|
headers={"Content-Type": "application/json"},
|
|
39
41
|
data=dumps(data),
|
|
40
|
-
timeout=
|
|
42
|
+
timeout=self.timeout
|
|
41
43
|
)
|
|
42
44
|
response.raise_for_status()
|
|
43
45
|
except Exception as error:
|
|
@@ -47,10 +49,10 @@ class NotifyTelegram(Notify):
|
|
|
47
49
|
)
|
|
48
50
|
|
|
49
51
|
def _get_text(self, task: Any) -> str:
|
|
50
|
-
return MESSAGE.format(
|
|
52
|
+
return self.MESSAGE.format(
|
|
51
53
|
symbol=TypeStatus.get_symbol(task.status),
|
|
52
54
|
status=task.status,
|
|
53
55
|
workflow_id=task.workflow_id,
|
|
54
56
|
task_id=task.task_id,
|
|
55
|
-
task=task.result(),
|
|
57
|
+
task=task.result(max=4000),
|
|
56
58
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dotflow"
|
|
3
|
-
version = "0.13.0.
|
|
3
|
+
version = "0.13.0.dev2"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name="Fernando Celmer", email="email@fernandocelmer.com" },
|
|
6
6
|
]
|
|
@@ -23,6 +23,7 @@ classifiers = [
|
|
|
23
23
|
"Programming Language :: Python :: 3.10",
|
|
24
24
|
"Programming Language :: Python :: 3.11",
|
|
25
25
|
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
26
27
|
]
|
|
27
28
|
|
|
28
29
|
[project.urls]
|
|
@@ -36,7 +37,7 @@ mongodb = ["dotflow-mongodb"]
|
|
|
36
37
|
|
|
37
38
|
[tool.poetry]
|
|
38
39
|
name = "dotflow"
|
|
39
|
-
version = "0.13.0.
|
|
40
|
+
version = "0.13.0.dev2"
|
|
40
41
|
description = "🎲 Dotflow turns an idea into flow!"
|
|
41
42
|
authors = ["Fernando Celmer <email@fernandocelmer.com>"]
|
|
42
43
|
readme = "README.md"
|
|
@@ -54,6 +55,7 @@ classifiers = [
|
|
|
54
55
|
"Programming Language :: Python :: 3.10",
|
|
55
56
|
"Programming Language :: Python :: 3.11",
|
|
56
57
|
"Programming Language :: Python :: 3.12",
|
|
58
|
+
"Programming Language :: Python :: 3.13",
|
|
57
59
|
]
|
|
58
60
|
|
|
59
61
|
[tool.poetry.scripts]
|
|
@@ -79,9 +81,11 @@ pyzmq = "^26.2.1"
|
|
|
79
81
|
|
|
80
82
|
[tool.poetry.group.docs.dependencies]
|
|
81
83
|
mkdocs = "^1.6.1"
|
|
82
|
-
mkdocs-simple-blog = "^0.1.0"
|
|
83
84
|
mkdocstrings = {extras = ["python"], version = "^0.29.0"}
|
|
84
85
|
griffe-typingdoc = "^0.2.8"
|
|
86
|
+
mike = "^2.1.3"
|
|
87
|
+
mkdocs-simple-blog = "0.2.0"
|
|
88
|
+
mkdocs-material = "^9.6.13"
|
|
85
89
|
|
|
86
90
|
|
|
87
91
|
[[tool.poetry.source]]
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"""Task serializer module"""
|
|
2
|
-
|
|
3
|
-
import json
|
|
4
|
-
|
|
5
|
-
from typing import Any, Optional
|
|
6
|
-
from uuid import UUID
|
|
7
|
-
|
|
8
|
-
from pydantic import BaseModel, Field, ConfigDict, field_validator # type: ignore
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class SerializerTaskError(BaseModel):
|
|
12
|
-
|
|
13
|
-
traceback: str
|
|
14
|
-
message: str
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class SerializerTask(BaseModel):
|
|
18
|
-
model_config = ConfigDict(title="task")
|
|
19
|
-
|
|
20
|
-
task_id: int = Field(default=None)
|
|
21
|
-
workflow_id: Optional[UUID] = Field(default=None)
|
|
22
|
-
status: str = Field(default=None, alias="_status")
|
|
23
|
-
error: Optional[SerializerTaskError] = Field(default=None, alias="_error")
|
|
24
|
-
duration: Optional[float] = Field(default=None, alias="_duration")
|
|
25
|
-
initial_context: Any = Field(default=None, alias="_initial_context")
|
|
26
|
-
current_context: Any = Field(default=None, alias="_current_context")
|
|
27
|
-
previous_context: Any = Field(default=None, alias="_previous_context")
|
|
28
|
-
group_name: str = Field(default=None)
|
|
29
|
-
|
|
30
|
-
@field_validator("error", mode="before")
|
|
31
|
-
@classmethod
|
|
32
|
-
def error_validator(cls, value: str) -> str:
|
|
33
|
-
if value:
|
|
34
|
-
return SerializerTaskError(**value.__dict__)
|
|
35
|
-
return None
|
|
36
|
-
|
|
37
|
-
@field_validator(
|
|
38
|
-
"initial_context", "current_context", "previous_context", mode="before"
|
|
39
|
-
)
|
|
40
|
-
@classmethod
|
|
41
|
-
def context_validator(cls, value: str) -> str:
|
|
42
|
-
if value and value.storage:
|
|
43
|
-
try:
|
|
44
|
-
return json.dumps(value.storage)
|
|
45
|
-
except Exception:
|
|
46
|
-
return str(value)
|
|
47
|
-
return None
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|