stepfunction 0.0.1__tar.gz → 0.0.2__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.
- {stepfunction-0.0.1/src/StepFunction.egg-info → stepfunction-0.0.2}/PKG-INFO +5 -4
- {stepfunction-0.0.1 → stepfunction-0.0.2}/pyproject.toml +3 -3
- {stepfunction-0.0.1 → stepfunction-0.0.2/src/StepFunction.egg-info}/PKG-INFO +5 -4
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/StepFunction.egg-info/SOURCES.txt +2 -1
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/core/step_function/step_function.py +9 -9
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/core/visualizer/visualizer.py +2 -2
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/utils/logger.py +3 -1
- stepfunction-0.0.2/tests/test_car_purchase_workflow.py +103 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/LICENSE +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/README.md +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/setup.cfg +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/StepFunction.egg-info/dependency_links.txt +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/StepFunction.egg-info/requires.txt +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/StepFunction.egg-info/top_level.txt +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/constants/__init__.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/constants/enums.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/constants/visualizer.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/core/step_function/__init__.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/core/visualizer/__init__.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/exceptions/__init__.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/exceptions/step_errors.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/types/__init__.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/types/step_types.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/types/visualizer_types.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/utils/__init__.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/utils/constants.py +0 -0
- {stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/utils/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: stepfunction
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Summary: Step Function Workflow Orchestration Library
|
|
5
5
|
Author: Vineeth Penugonda
|
|
6
6
|
Project-URL: Homepage, https://github.com/vinecodes/stepfunction
|
|
@@ -8,15 +8,16 @@ Project-URL: Issues, https://github.com/vinecodes/stepfunction/issues
|
|
|
8
8
|
Project-URL: Blog_Post, https://blog.vineethp.com/posts/introducingstepfunction/
|
|
9
9
|
Keywords: StepFunction,Workflow,Orchestration,Library
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Classifier: Development Status :: 3 - Alpha
|
|
14
14
|
Classifier: License :: OSI Approved :: MIT License
|
|
15
15
|
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
-
Requires-Python: >=3.
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
Requires-Dist: graphviz===0.20.3
|
|
20
|
+
Dynamic: license-file
|
|
20
21
|
|
|
21
22
|
# StepFunction
|
|
22
23
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "stepfunction"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.2"
|
|
4
4
|
authors = [{ name = "Vineeth Penugonda" }]
|
|
5
5
|
description = "Step Function Workflow Orchestration Library"
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
keywords = ["StepFunction", "Workflow", "Orchestration", "Library"]
|
|
8
|
-
requires-python = ">=3.
|
|
8
|
+
requires-python = ">=3.9"
|
|
9
9
|
dependencies = ["graphviz === 0.20.3"]
|
|
10
10
|
classifiers = [
|
|
11
11
|
"Programming Language :: Python :: 3",
|
|
12
|
-
"Programming Language :: Python :: 3.
|
|
12
|
+
"Programming Language :: Python :: 3.9",
|
|
13
13
|
"Operating System :: OS Independent",
|
|
14
14
|
"Development Status :: 3 - Alpha",
|
|
15
15
|
"License :: OSI Approved :: MIT License",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: stepfunction
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Summary: Step Function Workflow Orchestration Library
|
|
5
5
|
Author: Vineeth Penugonda
|
|
6
6
|
Project-URL: Homepage, https://github.com/vinecodes/stepfunction
|
|
@@ -8,15 +8,16 @@ Project-URL: Issues, https://github.com/vinecodes/stepfunction/issues
|
|
|
8
8
|
Project-URL: Blog_Post, https://blog.vineethp.com/posts/introducingstepfunction/
|
|
9
9
|
Keywords: StepFunction,Workflow,Orchestration,Library
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Classifier: Development Status :: 3 - Alpha
|
|
14
14
|
Classifier: License :: OSI Approved :: MIT License
|
|
15
15
|
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
-
Requires-Python: >=3.
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
Requires-Dist: graphviz===0.20.3
|
|
20
|
+
Dynamic: license-file
|
|
20
21
|
|
|
21
22
|
# StepFunction
|
|
22
23
|
|
{stepfunction-0.0.1 → stepfunction-0.0.2}/src/stepfunction/core/step_function/step_function.py
RENAMED
|
@@ -9,7 +9,6 @@ from inspect import iscoroutinefunction
|
|
|
9
9
|
from typing import Any, Callable, Dict, Optional, Union
|
|
10
10
|
|
|
11
11
|
from stepfunction.constants.enums import StepFunctionStatus
|
|
12
|
-
from stepfunction.core.visualizer import Visualizer
|
|
13
12
|
from stepfunction.exceptions.step_errors import (ParallelStepExecutionError,
|
|
14
13
|
StepExecutionError)
|
|
15
14
|
from stepfunction.types.step_types import StepParams
|
|
@@ -199,8 +198,7 @@ class StepFunction:
|
|
|
199
198
|
self.__context[self.__current_step] = results
|
|
200
199
|
|
|
201
200
|
self.__logger.info(
|
|
202
|
-
f"Parallel step '{
|
|
203
|
-
self.__current_step}' succeeded with results: {results}"
|
|
201
|
+
f"Parallel step '{self.__current_step}' succeeded with results: {results}"
|
|
204
202
|
)
|
|
205
203
|
else:
|
|
206
204
|
result = await self._execute_step(step["func"], self.__last_result)
|
|
@@ -226,8 +224,7 @@ class StepFunction:
|
|
|
226
224
|
|
|
227
225
|
if step["on_failure"]:
|
|
228
226
|
self.__logger.exception(
|
|
229
|
-
f"Executing failure step: {
|
|
230
|
-
step['on_failure']} for '{self.__current_step}'"
|
|
227
|
+
f"Executing failure step: {step['on_failure']} for '{self.__current_step}'"
|
|
231
228
|
)
|
|
232
229
|
|
|
233
230
|
self.__current_step = step["on_failure"]
|
|
@@ -239,8 +236,7 @@ class StepFunction:
|
|
|
239
236
|
f"StepFunction - {self.__name} - Status - {self.__status.value}")
|
|
240
237
|
else:
|
|
241
238
|
self.__logger.exception(
|
|
242
|
-
f"No failure step defined for '{
|
|
243
|
-
self.__current_step}'. Raising Exception."
|
|
239
|
+
f"No failure step defined for '{self.__current_step}'. Raising Exception."
|
|
244
240
|
)
|
|
245
241
|
|
|
246
242
|
self.__status = StepFunctionStatus.FAILED
|
|
@@ -306,6 +302,8 @@ class StepFunction:
|
|
|
306
302
|
|
|
307
303
|
def visualize(self):
|
|
308
304
|
"""Visualize the workflow."""
|
|
305
|
+
from stepfunction.core.visualizer import Visualizer
|
|
306
|
+
|
|
309
307
|
visualizer = Visualizer(self.__name, self.__steps)
|
|
310
308
|
|
|
311
309
|
self.__logger.debug("Visualizing the step function")
|
|
@@ -318,11 +316,13 @@ class StepFunction:
|
|
|
318
316
|
|
|
319
317
|
output_file_name = visualizer.output_file_name
|
|
320
318
|
|
|
321
|
-
self.__logger.debug(
|
|
322
|
-
output_file_name}")
|
|
319
|
+
self.__logger.debug(
|
|
320
|
+
f"Rendered the step function to file: {output_file_name}")
|
|
323
321
|
|
|
324
322
|
def visualize_to_string(self):
|
|
325
323
|
"""Visualize the workflow as a string."""
|
|
324
|
+
from stepfunction.core.visualizer import Visualizer
|
|
325
|
+
|
|
326
326
|
visualizer = Visualizer(self.__name, self.__steps)
|
|
327
327
|
|
|
328
328
|
self.__logger.debug("Visualizing the step function")
|
|
@@ -98,8 +98,8 @@ class Visualizer:
|
|
|
98
98
|
|
|
99
99
|
file_path = kwargs.get(
|
|
100
100
|
'file_path', f"{current_dir}/{DEFAULT_VISUALIZER_FOLDER}")
|
|
101
|
-
file_name = kwargs.get(
|
|
102
|
-
|
|
101
|
+
file_name = kwargs.get(
|
|
102
|
+
'file_name', f"{self.graph_name}.{DEFAULT_VISUALIZER_EXTENSION}")
|
|
103
103
|
|
|
104
104
|
self.__output_file_path = file_path
|
|
105
105
|
self.__output_file_name = file_name
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
import logging.config
|
|
5
5
|
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
6
8
|
from stepfunction.utils.constants import (DEFAULT_LOG_LEVEL,
|
|
7
9
|
DEFAULT_LOGGING_FORMAT,
|
|
8
10
|
ENVIRONMENT_VARIABLE_LOG_LEVEL)
|
|
9
11
|
from stepfunction.utils.utils import get_environment_variable
|
|
10
12
|
|
|
11
13
|
|
|
12
|
-
def setup_logger(name: str
|
|
14
|
+
def setup_logger(name: Optional[str] = None, log_format: str = DEFAULT_LOGGING_FORMAT) -> logging.Logger:
|
|
13
15
|
"""
|
|
14
16
|
Set up and return a logger with the given name.
|
|
15
17
|
If no name is provided, return the root logger.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import sys
|
|
3
|
+
import types
|
|
4
|
+
import unittest
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
ROOT = Path(__file__).resolve().parents[1]
|
|
8
|
+
sys.path.insert(0, str(ROOT / "src"))
|
|
9
|
+
sys.path.insert(0, str(ROOT))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class _FakeSubgraph:
|
|
13
|
+
def __init__(self):
|
|
14
|
+
self.attrs = {}
|
|
15
|
+
|
|
16
|
+
def __enter__(self):
|
|
17
|
+
return self
|
|
18
|
+
|
|
19
|
+
def __exit__(self, exc_type, exc, tb):
|
|
20
|
+
return False
|
|
21
|
+
|
|
22
|
+
def attr(self, **kwargs):
|
|
23
|
+
self.attrs.update(kwargs)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class _FakeDigraph:
|
|
27
|
+
def __init__(self, comment=None):
|
|
28
|
+
self.comment = comment
|
|
29
|
+
self.nodes = []
|
|
30
|
+
self.edges = []
|
|
31
|
+
self.render_calls = []
|
|
32
|
+
|
|
33
|
+
def node(self, *args, **kwargs):
|
|
34
|
+
self.nodes.append((args, kwargs))
|
|
35
|
+
|
|
36
|
+
def edge(self, *args, **kwargs):
|
|
37
|
+
self.edges.append((args, kwargs))
|
|
38
|
+
|
|
39
|
+
def subgraph(self):
|
|
40
|
+
return _FakeSubgraph()
|
|
41
|
+
|
|
42
|
+
def render(self, *args, **kwargs):
|
|
43
|
+
self.render_calls.append((args, kwargs))
|
|
44
|
+
|
|
45
|
+
def pipe(self, format=None, renderer=None):
|
|
46
|
+
return f"digraph {self.comment} ({format}, {renderer})".encode("utf-8")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
fake_graphviz = types.ModuleType("graphviz")
|
|
50
|
+
fake_graphviz.Digraph = _FakeDigraph
|
|
51
|
+
sys.modules.setdefault("graphviz", fake_graphviz)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
from examples.car_purchase_workflow import validate_car_purchase_transaction_workflow
|
|
55
|
+
from stepfunction.constants.enums import StepFunctionStatus
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class CarPurchaseWorkflowTests(unittest.IsolatedAsyncioTestCase):
|
|
59
|
+
async def test_valid_car_purchase_workflow_runs_to_completion(self):
|
|
60
|
+
workflow = await validate_car_purchase_transaction_workflow(
|
|
61
|
+
transaction={
|
|
62
|
+
"transaction_id": "CAR-1001",
|
|
63
|
+
"customer_email": "buyer@example.com",
|
|
64
|
+
"is_valid": True,
|
|
65
|
+
},
|
|
66
|
+
visualize=True,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
self.assertEqual(workflow.status, StepFunctionStatus.COMPLETED)
|
|
70
|
+
self.assertEqual(workflow.last_result["workflow"], "done")
|
|
71
|
+
self.assertEqual(
|
|
72
|
+
workflow.context["Update_Company_DB_Records"]["update_shipping_db_record"],
|
|
73
|
+
"shipping_updated",
|
|
74
|
+
)
|
|
75
|
+
self.assertEqual(
|
|
76
|
+
workflow.context["Update_Car_Purchase_Transaction_Status"]["status"],
|
|
77
|
+
"completed",
|
|
78
|
+
)
|
|
79
|
+
self.assertTrue(
|
|
80
|
+
workflow.context["Send_Notification_To_User_Email"]["notification_sent"])
|
|
81
|
+
|
|
82
|
+
async def test_invalid_car_purchase_skips_parallel_update_steps(self):
|
|
83
|
+
workflow = await validate_car_purchase_transaction_workflow(
|
|
84
|
+
transaction={
|
|
85
|
+
"transaction_id": "CAR-1002",
|
|
86
|
+
"customer_email": "buyer@example.com",
|
|
87
|
+
"is_valid": False,
|
|
88
|
+
},
|
|
89
|
+
visualize=False,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
self.assertEqual(workflow.status, StepFunctionStatus.COMPLETED)
|
|
93
|
+
self.assertEqual(
|
|
94
|
+
workflow.context["Check_If_Car_Purchase_Transaction_Is_Valid"], "invalid")
|
|
95
|
+
self.assertNotIn("Update_Company_DB_Records", workflow.context)
|
|
96
|
+
self.assertEqual(
|
|
97
|
+
workflow.context["Send_Notification_To_User_Email"]["status"],
|
|
98
|
+
"validation_failed",
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
if __name__ == "__main__":
|
|
103
|
+
unittest.main()
|
|
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
|