stageflow-framework 0.1.3__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/PKG-INFO +1 -1
  2. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/pyproject.toml +1 -1
  3. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/core/stage.py +20 -4
  4. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow_framework.egg-info/PKG-INFO +1 -1
  5. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow_framework.egg-info/SOURCES.txt +1 -0
  6. stageflow_framework-0.1.4/tests/test_stage_wait_input.py +64 -0
  7. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/README.md +0 -0
  8. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/setup.cfg +0 -0
  9. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/__init__.py +0 -0
  10. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/builtins/__init__.py +0 -0
  11. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/builtins/dicts.py +0 -0
  12. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/builtins/lists.py +0 -0
  13. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/builtins/lists_extra.py +0 -0
  14. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/builtins/logic.py +0 -0
  15. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/builtins/strings.py +0 -0
  16. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/builtins/vars.py +0 -0
  17. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/core/__init__.py +0 -0
  18. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/core/context.py +0 -0
  19. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/core/event.py +0 -0
  20. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/core/jsonlogic.py +0 -0
  21. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/core/node.py +0 -0
  22. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/core/pipeline.py +0 -0
  23. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/core/session.py +0 -0
  24. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/core/utils.py +0 -0
  25. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/docs/__init__.py +0 -0
  26. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/docs/html.py +0 -0
  27. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/docs/schema.py +0 -0
  28. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/docs/schemas/pipeline.json +0 -0
  29. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/py.typed +0 -0
  30. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow/testing.py +0 -0
  31. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow_framework.egg-info/dependency_links.txt +0 -0
  32. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow_framework.egg-info/requires.txt +0 -0
  33. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/stageflow_framework.egg-info/top_level.txt +0 -0
  34. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/tests/test_core_flow.py +0 -0
  35. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/tests/test_docs_schema.py +0 -0
  36. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/tests/test_full_pipeline.py +0 -0
  37. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/tests/test_jsonlogic.py +0 -0
  38. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/tests/test_payload_validation.py +0 -0
  39. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/tests/test_pipeline_tester.py +0 -0
  40. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/tests/test_session_wait_input.py +0 -0
  41. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/tests/test_snapshot.py +0 -0
  42. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/tests/test_std_stages.py +0 -0
  43. {stageflow_framework-0.1.3 → stageflow_framework-0.1.4}/tests/test_subpipeline.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stageflow-framework
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: StageFlow: Pipeline framework for stages
5
5
  Author: lethargy
6
6
  Requires-Python: >=3.10
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "stageflow-framework"
7
- version = "0.1.3"
7
+ version = "0.1.4"
8
8
  description = "StageFlow: Pipeline framework for stages"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  import copy
2
3
  from typing import Any, TYPE_CHECKING
3
4
  import yaml
@@ -121,14 +122,29 @@ class BaseStage:
121
122
  payload=payload or {},
122
123
  ))
123
124
 
124
- async def wait_input(self, type_: str, timeout: float | None = None):
125
+ def _get_allowed_input(self, type_: str) -> InputSpec | None:
125
126
  if self.allowed_inputs:
126
127
  allowed = {spec.type for spec in self.allowed_inputs if spec.type}
127
128
  if allowed and type_ not in allowed:
128
129
  raise ValueError(f"Input type '{type_}' is not allowed for stage '{self.stage_name}'")
129
- matching = next((spec for spec in self.allowed_inputs if spec.type == type_), None)
130
- else:
131
- matching = None
130
+ return next((spec for spec in self.allowed_inputs if spec.type == type_), None)
131
+ return None
132
+
133
+ def start_wait_input(self, type_: str) -> asyncio.Future:
134
+ self._get_allowed_input(type_)
135
+ return self.session.start_wait_input(type_)
136
+
137
+ async def finish_wait_input(self, type_: str, fut: asyncio.Future, timeout: float | None = None):
138
+ matching = self._get_allowed_input(type_)
139
+ result = await self.session.finish_wait_input(type_, fut, timeout=timeout)
140
+ if result is None:
141
+ return None
142
+ if matching and matching.payload_schema is not None:
143
+ validate_schema(result.get("payload", {}), matching.payload_schema, "Input payload")
144
+ return result
145
+
146
+ async def wait_input(self, type_: str, timeout: float | None = None):
147
+ matching = self._get_allowed_input(type_)
132
148
  result = await self.session.wait_input(type_, timeout=timeout)
133
149
  if result is None:
134
150
  return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stageflow-framework
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: StageFlow: Pipeline framework for stages
5
5
  Author: lethargy
6
6
  Requires-Python: >=3.10
@@ -36,5 +36,6 @@ tests/test_payload_validation.py
36
36
  tests/test_pipeline_tester.py
37
37
  tests/test_session_wait_input.py
38
38
  tests/test_snapshot.py
39
+ tests/test_stage_wait_input.py
39
40
  tests/test_std_stages.py
40
41
  tests/test_subpipeline.py
@@ -0,0 +1,64 @@
1
+ import unittest
2
+
3
+ from stageflow.core.context import Context
4
+ from stageflow.core.event import InputSpec
5
+ from stageflow.core.node import TerminalNode
6
+ from stageflow.core.pipeline import Pipeline
7
+ from stageflow.core.session import Session
8
+ from stageflow.core.stage import BaseStage
9
+
10
+
11
+ def _make_pipeline():
12
+ end = TerminalNode(id="end", type="terminal")
13
+ return Pipeline(entry="end", nodes=[end])
14
+
15
+
16
+ class StageWaitInputTests(unittest.IsolatedAsyncioTestCase):
17
+ async def test_start_and_finish_wait_input_success(self):
18
+ session = Session(id="stage1", pipeline=_make_pipeline(), context=Context())
19
+
20
+ class WaitStage(BaseStage):
21
+ allowed_inputs = [InputSpec(type="user", payload_schema={"id": int})]
22
+
23
+ async def run(self):
24
+ return None
25
+
26
+ stage = WaitStage(stage_id="s1", config={}, arguments={}, outputs={}, session=session)
27
+ fut = stage.start_wait_input("user")
28
+ await session.input("user", {"id": 10})
29
+
30
+ result = await stage.finish_wait_input("user", fut, timeout=1)
31
+ self.assertEqual(result["payload"]["id"], 10)
32
+
33
+ async def test_finish_wait_input_validates_payload(self):
34
+ session = Session(id="stage2", pipeline=_make_pipeline(), context=Context())
35
+
36
+ class WaitStage(BaseStage):
37
+ allowed_inputs = [InputSpec(type="user", payload_schema={"id": int})]
38
+
39
+ async def run(self):
40
+ return None
41
+
42
+ stage = WaitStage(stage_id="s1", config={}, arguments={}, outputs={}, session=session)
43
+ fut = stage.start_wait_input("user")
44
+ await session.input("user", {"id": "bad"})
45
+
46
+ with self.assertRaises(ValueError):
47
+ await stage.finish_wait_input("user", fut, timeout=1)
48
+
49
+ async def test_start_wait_input_rejects_disallowed_type(self):
50
+ session = Session(id="stage3", pipeline=_make_pipeline(), context=Context())
51
+
52
+ class LimitedStage(BaseStage):
53
+ allowed_inputs = [InputSpec(type="only")]
54
+
55
+ async def run(self):
56
+ return None
57
+
58
+ stage = LimitedStage(stage_id="s1", config={}, arguments={}, outputs={}, session=session)
59
+ with self.assertRaises(ValueError):
60
+ stage.start_wait_input("other")
61
+
62
+
63
+ if __name__ == "__main__":
64
+ unittest.main()