stageflow-framework 0.1.4__tar.gz → 0.1.6__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.
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/PKG-INFO +1 -1
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/pyproject.toml +1 -1
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/core/event.py +17 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/core/stage.py +2 -2
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/core/utils.py +46 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow_framework.egg-info/PKG-INFO +1 -1
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_docs_schema.py +19 -2
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/README.md +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/setup.cfg +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/__init__.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/builtins/__init__.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/builtins/dicts.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/builtins/lists.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/builtins/lists_extra.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/builtins/logic.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/builtins/strings.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/builtins/vars.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/core/__init__.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/core/context.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/core/jsonlogic.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/core/node.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/core/pipeline.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/core/session.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/docs/__init__.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/docs/html.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/docs/schema.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/docs/schemas/pipeline.json +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/py.typed +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/testing.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow_framework.egg-info/SOURCES.txt +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow_framework.egg-info/dependency_links.txt +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow_framework.egg-info/requires.txt +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow_framework.egg-info/top_level.txt +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_core_flow.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_full_pipeline.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_jsonlogic.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_payload_validation.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_pipeline_tester.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_session_wait_input.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_snapshot.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_stage_wait_input.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_std_stages.py +0 -0
- {stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/tests/test_subpipeline.py +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from datetime import datetime, UTC
|
|
3
|
+
from .utils import schema_to_jsonable
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
@dataclass
|
|
@@ -10,6 +11,15 @@ class InputSpec:
|
|
|
10
11
|
default: str | int | float | bool | None = None
|
|
11
12
|
payload_schema: object | None = None
|
|
12
13
|
|
|
14
|
+
def to_dict(self) -> dict:
|
|
15
|
+
return {
|
|
16
|
+
"type": self.type,
|
|
17
|
+
"description": self.description,
|
|
18
|
+
"required": self.required,
|
|
19
|
+
"default": self.default,
|
|
20
|
+
"payload_schema": schema_to_jsonable(self.payload_schema),
|
|
21
|
+
}
|
|
22
|
+
|
|
13
23
|
|
|
14
24
|
@dataclass
|
|
15
25
|
class EventSpec:
|
|
@@ -17,6 +27,13 @@ class EventSpec:
|
|
|
17
27
|
description: str | None = None
|
|
18
28
|
payload_schema: object | None = None
|
|
19
29
|
|
|
30
|
+
def to_dict(self) -> dict:
|
|
31
|
+
return {
|
|
32
|
+
"type": self.type,
|
|
33
|
+
"description": self.description,
|
|
34
|
+
"payload_schema": schema_to_jsonable(self.payload_schema),
|
|
35
|
+
}
|
|
36
|
+
|
|
20
37
|
|
|
21
38
|
class Event:
|
|
22
39
|
type: str
|
|
@@ -158,8 +158,8 @@ class BaseStage:
|
|
|
158
158
|
return {
|
|
159
159
|
"stage_name": cls.stage_name,
|
|
160
160
|
"skipable": cls.skipable,
|
|
161
|
-
"allowed_events": [e.
|
|
162
|
-
"allowed_inputs": [i.
|
|
161
|
+
"allowed_events": [e.to_dict() for e in cls.allowed_events],
|
|
162
|
+
"allowed_inputs": [i.to_dict() for i in cls.allowed_inputs],
|
|
163
163
|
"category": cls.category,
|
|
164
164
|
"description": parsed_description.get("description", "") if isinstance(parsed_description, dict) else "",
|
|
165
165
|
"arguments": _normalize_fields(parsed_description.get("arguments", [])) if isinstance(parsed_description, dict) else [],
|
|
@@ -60,3 +60,49 @@ def validate_schema(value: Any, schema: object, path: str = "payload"):
|
|
|
60
60
|
return
|
|
61
61
|
if not isinstance(value, expected):
|
|
62
62
|
raise ValueError(f"{path} expected {schema}, got {type(value).__name__}")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
_TYPE_NAME_OVERRIDES = {
|
|
66
|
+
str: "str",
|
|
67
|
+
int: "int",
|
|
68
|
+
float: "float",
|
|
69
|
+
bool: "bool",
|
|
70
|
+
dict: "object",
|
|
71
|
+
list: "list",
|
|
72
|
+
type(None): "null",
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def schema_to_jsonable(schema: object) -> object:
|
|
77
|
+
"""Convert payload schema hint into a JSON-serializable structure."""
|
|
78
|
+
origin = get_origin(schema)
|
|
79
|
+
args = get_args(schema)
|
|
80
|
+
|
|
81
|
+
if schema is None:
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
if schema is Any or schema is object:
|
|
85
|
+
return "any"
|
|
86
|
+
|
|
87
|
+
if origin is Union and args:
|
|
88
|
+
return {"anyOf": [schema_to_jsonable(arg) for arg in args]}
|
|
89
|
+
|
|
90
|
+
if origin is list and args:
|
|
91
|
+
return [schema_to_jsonable(args[0])]
|
|
92
|
+
|
|
93
|
+
if origin is dict and args:
|
|
94
|
+
return {"key": schema_to_jsonable(args[0]), "value": schema_to_jsonable(args[1])}
|
|
95
|
+
|
|
96
|
+
if isinstance(schema, dict):
|
|
97
|
+
return {k: schema_to_jsonable(v) for k, v in schema.items()}
|
|
98
|
+
|
|
99
|
+
if isinstance(schema, list):
|
|
100
|
+
return [schema_to_jsonable(v) for v in schema]
|
|
101
|
+
|
|
102
|
+
if isinstance(schema, tuple):
|
|
103
|
+
return [schema_to_jsonable(v) for v in schema]
|
|
104
|
+
|
|
105
|
+
if isinstance(schema, type):
|
|
106
|
+
return _TYPE_NAME_OVERRIDES.get(schema, getattr(schema, "__name__", str(schema)))
|
|
107
|
+
|
|
108
|
+
return str(schema)
|
|
@@ -28,8 +28,20 @@ class DocStage(BaseStage):
|
|
|
28
28
|
type: string
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
-
allowed_events = [
|
|
32
|
-
|
|
31
|
+
allowed_events = [
|
|
32
|
+
EventSpec(
|
|
33
|
+
type="progress",
|
|
34
|
+
description="Progress event",
|
|
35
|
+
payload_schema={"step": int, "tags": list[str]},
|
|
36
|
+
)
|
|
37
|
+
]
|
|
38
|
+
allowed_inputs = [
|
|
39
|
+
InputSpec(
|
|
40
|
+
type="user_input",
|
|
41
|
+
description="User input",
|
|
42
|
+
payload_schema={"answer": str, "meta": {"id": int}, "tags": [str]},
|
|
43
|
+
)
|
|
44
|
+
]
|
|
33
45
|
category = "demo"
|
|
34
46
|
|
|
35
47
|
async def run(self):
|
|
@@ -68,6 +80,11 @@ class DocsSchemaTests(unittest.TestCase):
|
|
|
68
80
|
|
|
69
81
|
self.assertEqual(doc_spec["allowed_events"][0]["type"], "progress")
|
|
70
82
|
self.assertEqual(doc_spec["allowed_inputs"][0]["type"], "user_input")
|
|
83
|
+
self.assertEqual(doc_spec["allowed_events"][0]["payload_schema"], {"step": "int", "tags": ["str"]})
|
|
84
|
+
self.assertEqual(
|
|
85
|
+
doc_spec["allowed_inputs"][0]["payload_schema"],
|
|
86
|
+
{"answer": "str", "meta": {"id": "int"}, "tags": ["str"]},
|
|
87
|
+
)
|
|
71
88
|
self.assertEqual(doc_spec["category"], "demo")
|
|
72
89
|
|
|
73
90
|
def test_generate_yaml_contains_description(self):
|
|
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
|
{stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow/docs/schemas/pipeline.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow_framework.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow_framework.egg-info/requires.txt
RENAMED
|
File without changes
|
{stageflow_framework-0.1.4 → stageflow_framework-0.1.6}/stageflow_framework.egg-info/top_level.txt
RENAMED
|
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
|