stepflow-py 0.2.1__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.
@@ -0,0 +1,2 @@
1
+ *.pyc
2
+ __pycache__
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,108 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## <a id="0.2.1"></a> [StepFlow Python SDK 0.2.1](https://github.com/riptano/stepflow/releases/tag/stepflow-py-0.2.1) - 2025-07-29
6
+ ### Bug Fixes
7
+
8
+ - Input search path and remove unneeded flow_dir variable ([#74](https://github.com/riptano/stepflow/pull/74))
9
+ - Relax requires-python ([#180](https://github.com/riptano/stepflow/pull/180))
10
+
11
+ ### Documentation
12
+
13
+ - Update contributing with link to conventional commits ([#121](https://github.com/riptano/stepflow/pull/121))
14
+ - Use generated schemas in documentation ([#127](https://github.com/riptano/stepflow/pull/127))
15
+ - Added details on error handling with examples to claude and contrib docs ([#146](https://github.com/riptano/stepflow/pull/146))
16
+ - Updates to paths, routes, and invocations to ensure all examples are working ([#161](https://github.com/riptano/stepflow/pull/161))
17
+
18
+ ### Features
19
+
20
+ - Generate protocol schema from Rust code ([#120](https://github.com/riptano/stepflow/pull/120))
21
+ - Generate and use protocol types ([#122](https://github.com/riptano/stepflow/pull/122))
22
+ - Add FlowBuilder and Value API ([#135](https://github.com/riptano/stepflow/pull/135))
23
+ - Support `.` and `[...]` in paths ([#138](https://github.com/riptano/stepflow/pull/138))
24
+ - Change component names URLs to paths ([#144](https://github.com/riptano/stepflow/pull/144))
25
+ - Switch to path-based routing for components ([#145](https://github.com/riptano/stepflow/pull/145))
26
+ - Implement protocol over HTTP+SSE ([#147](https://github.com/riptano/stepflow/pull/147))
27
+ - Allow substitutions in environment variables ([#148](https://github.com/riptano/stepflow/pull/148))
28
+ - Add eval method and demonstrate loop/map ([#153](https://github.com/riptano/stepflow/pull/153))
29
+ - Change to trie-based routing ([#157](https://github.com/riptano/stepflow/pull/157))
30
+ - Replace HTTP+SSE with Streamable HTTP ([#168](https://github.com/riptano/stepflow/pull/168))
31
+ - Added validate to CLI args. Supports both flow and config ([#175](https://github.com/riptano/stepflow/pull/175))
32
+
33
+ ### Miscellaneous Tasks
34
+
35
+ - Setup release scripts and documentation ([#95](https://github.com/riptano/stepflow/pull/95))
36
+ - Update names of release workflows ([#97](https://github.com/riptano/stepflow/pull/97))
37
+ - Configure license headers ([#115](https://github.com/riptano/stepflow/pull/115))
38
+ - Setup CI for python ([#139](https://github.com/riptano/stepflow/pull/139))
39
+ - Fix python lints & mypy ([#140](https://github.com/riptano/stepflow/pull/140))
40
+ - Add scripts for the CI checks ([#156](https://github.com/riptano/stepflow/pull/156))
41
+ - Update release process for python ([#173](https://github.com/riptano/stepflow/pull/173))
42
+ - Change action label to stepflow-py
43
+ - Use gh token for checkout
44
+ - Set GITHUB_TOUKEN
45
+ - Fix cliff.toml
46
+ - Release stepflow-py v0.2.0 ([#179](https://github.com/riptano/stepflow/pull/179))
47
+
48
+ ### Refactoring
49
+
50
+ - Standardize on `input` naming ([#77](https://github.com/riptano/stepflow/pull/77))
51
+ - Remove unused components and update examples ([#111](https://github.com/riptano/stepflow/pull/111))
52
+ - Use custom exceptions in python SDK ([#114](https://github.com/riptano/stepflow/pull/114))
53
+ - Some doc fixes, load test scripts ([#169](https://github.com/riptano/stepflow/pull/169))
54
+ - Update config to camel case consistently ([#170](https://github.com/riptano/stepflow/pull/170))
55
+ - Rename stepflow-sdk to stepflow-py ([#172](https://github.com/riptano/stepflow/pull/172))
56
+
57
+ ## <a id="0.2.0"></a> [StepFlow Python SDK 0.2.0](https://github.com/riptano/stepflow/releases/tag/stepflow-py-0.2.0) - 2025-07-29
58
+ ### Bug Fixes
59
+
60
+ - Input search path and remove unneeded flow_dir variable ([#74](https://github.com/riptano/stepflow/pull/74))
61
+
62
+ ### Documentation
63
+
64
+ - Update contributing with link to conventional commits ([#121](https://github.com/riptano/stepflow/pull/121))
65
+ - Use generated schemas in documentation ([#127](https://github.com/riptano/stepflow/pull/127))
66
+ - Added details on error handling with examples to claude and contrib docs ([#146](https://github.com/riptano/stepflow/pull/146))
67
+ - Updates to paths, routes, and invocations to ensure all examples are working ([#161](https://github.com/riptano/stepflow/pull/161))
68
+
69
+ ### Features
70
+
71
+ - Generate protocol schema from Rust code ([#120](https://github.com/riptano/stepflow/pull/120))
72
+ - Generate and use protocol types ([#122](https://github.com/riptano/stepflow/pull/122))
73
+ - Add FlowBuilder and Value API ([#135](https://github.com/riptano/stepflow/pull/135))
74
+ - Support `.` and `[...]` in paths ([#138](https://github.com/riptano/stepflow/pull/138))
75
+ - Change component names URLs to paths ([#144](https://github.com/riptano/stepflow/pull/144))
76
+ - Switch to path-based routing for components ([#145](https://github.com/riptano/stepflow/pull/145))
77
+ - Implement protocol over HTTP+SSE ([#147](https://github.com/riptano/stepflow/pull/147))
78
+ - Allow substitutions in environment variables ([#148](https://github.com/riptano/stepflow/pull/148))
79
+ - Add eval method and demonstrate loop/map ([#153](https://github.com/riptano/stepflow/pull/153))
80
+ - Change to trie-based routing ([#157](https://github.com/riptano/stepflow/pull/157))
81
+ - Replace HTTP+SSE with Streamable HTTP ([#168](https://github.com/riptano/stepflow/pull/168))
82
+ - Added validate to CLI args. Supports both flow and config ([#175](https://github.com/riptano/stepflow/pull/175))
83
+
84
+ ### Miscellaneous Tasks
85
+
86
+ - Setup release scripts and documentation ([#95](https://github.com/riptano/stepflow/pull/95))
87
+ - Update names of release workflows ([#97](https://github.com/riptano/stepflow/pull/97))
88
+ - Configure license headers ([#115](https://github.com/riptano/stepflow/pull/115))
89
+ - Setup CI for python ([#139](https://github.com/riptano/stepflow/pull/139))
90
+ - Fix python lints & mypy ([#140](https://github.com/riptano/stepflow/pull/140))
91
+ - Add scripts for the CI checks ([#156](https://github.com/riptano/stepflow/pull/156))
92
+ - Update release process for python ([#173](https://github.com/riptano/stepflow/pull/173))
93
+ - Change action label to stepflow-py
94
+ - Use gh token for checkout
95
+ - Set GITHUB_TOUKEN
96
+ - Fix cliff.toml
97
+
98
+ ### Refactoring
99
+
100
+ - Standardize on `input` naming ([#77](https://github.com/riptano/stepflow/pull/77))
101
+ - Remove unused components and update examples ([#111](https://github.com/riptano/stepflow/pull/111))
102
+ - Use custom exceptions in python SDK ([#114](https://github.com/riptano/stepflow/pull/114))
103
+ - Some doc fixes, load test scripts ([#169](https://github.com/riptano/stepflow/pull/169))
104
+ - Update config to camel case consistently ([#170](https://github.com/riptano/stepflow/pull/170))
105
+ - Rename stepflow-sdk to stepflow-py ([#172](https://github.com/riptano/stepflow/pull/172))
106
+
107
+ ## [Unreleased]
108
+
@@ -0,0 +1,127 @@
1
+ Metadata-Version: 2.4
2
+ Name: stepflow-py
3
+ Version: 0.2.1
4
+ Summary: Python SDK for Stepflow components and workflows.
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: jsonschema>=4.17.0
7
+ Requires-Dist: msgspec>=0.19.0
8
+ Requires-Dist: types-jsonschema>=4.17.0
9
+ Provides-Extra: http
10
+ Requires-Dist: fastapi>=0.104.1; extra == 'http'
11
+ Requires-Dist: sse-starlette>=1.6.5; extra == 'http'
12
+ Requires-Dist: uvicorn>=0.24.0; extra == 'http'
13
+ Description-Content-Type: text/markdown
14
+
15
+ # StepFlow Python SDK
16
+
17
+ Python SDK for building StepFlow components and workflows.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ # Install from source
23
+ uv add stepflow-py
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ### Creating a Component Server
29
+
30
+ ```python
31
+ from stepflow_py import StepflowStdioServer, StepflowContext
32
+ import msgspec
33
+
34
+ # Define input/output types
35
+ class MyInput(msgspec.Struct):
36
+ message: str
37
+ count: int
38
+
39
+ class MyOutput(msgspec.Struct):
40
+ result: str
41
+
42
+ # Create server
43
+ server = StepflowStdioServer()
44
+
45
+ # Register a component
46
+ @server.component
47
+ def my_component(input: MyInput) -> MyOutput:
48
+ return MyOutput(result=f"Processed: {input.message} x{input.count}")
49
+
50
+ # Component with context (for blob operations)
51
+ @server.component
52
+ async def component_with_context(input: MyInput, context: StepflowContext) -> MyOutput:
53
+ # Store data as a blob
54
+ blob_id = await context.put_blob({"processed": input.message})
55
+ return MyOutput(result=f"Stored blob: {blob_id}")
56
+
57
+ # Run the server
58
+ if __name__ == "__main__":
59
+ server.run()
60
+ ```
61
+
62
+ ### Using the Context API
63
+
64
+ The `StepflowContext` provides bidirectional communication with the StepFlow runtime:
65
+
66
+ ```python
67
+ # Store JSON data as a blob
68
+ blob_id = await context.put_blob({"key": "value"})
69
+
70
+ # Retrieve blob data
71
+ data = await context.get_blob(blob_id)
72
+
73
+ # Logging
74
+ context.log("Debug message")
75
+ ```
76
+
77
+ ## Development
78
+
79
+ ### Running Tests
80
+
81
+ ```bash
82
+ uv run pytest
83
+ ```
84
+
85
+ ### Type Checking
86
+
87
+ ```bash
88
+ uv run mypy src/
89
+ ```
90
+
91
+ ### Protocol Generation
92
+
93
+ This SDK uses auto-generated protocol types from the JSON schema. To regenerate the protocol types when the schema changes:
94
+
95
+ ```bash
96
+ uv run python generate.py
97
+ ```
98
+
99
+ The generation script automatically handles the generation and applies necessary fixes for msgspec compatibility.
100
+
101
+ ### Project Structure
102
+
103
+ - `src/stepflow_py/` - Main SDK code
104
+ - `generated_protocol.py` - Auto-generated protocol types from JSON schema
105
+ - `protocol.py` - Hybrid protocol layer with envelope patterns for efficient deserialization
106
+ - `server.py` - Component server implementation
107
+ - `context.py` - Runtime context API
108
+ - `exceptions.py` - SDK-specific exceptions
109
+ - `tests/` - Test suite
110
+
111
+ ### Architecture
112
+
113
+ The SDK uses a hybrid approach for protocol handling:
114
+
115
+ 1. **Generated Types** (`generated_protocol.py`) - Auto-generated from the StepFlow JSON schema using `datamodel-code-generator`
116
+ 2. **Protocol Layer** (`protocol.py`) - Combines generated types with manual envelope patterns for two-stage deserialization using `msgspec.Raw`
117
+ 3. **Server Implementation** - Uses the protocol layer for efficient JSON-RPC message handling
118
+
119
+ This design provides:
120
+ - **Type Safety** - All protocol messages use properly typed structs
121
+ - **Schema Consistency** - Generated types match the Rust protocol exactly
122
+ - **Performance** - Two-stage deserialization with `msgspec.Raw` for optimal speed
123
+ - **Maintainability** - Protocol changes can be regenerated automatically
124
+
125
+ ## License
126
+
127
+ Licensed under the Apache License, Version 2.0.
@@ -0,0 +1,113 @@
1
+ # StepFlow Python SDK
2
+
3
+ Python SDK for building StepFlow components and workflows.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Install from source
9
+ uv add stepflow-py
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ ### Creating a Component Server
15
+
16
+ ```python
17
+ from stepflow_py import StepflowStdioServer, StepflowContext
18
+ import msgspec
19
+
20
+ # Define input/output types
21
+ class MyInput(msgspec.Struct):
22
+ message: str
23
+ count: int
24
+
25
+ class MyOutput(msgspec.Struct):
26
+ result: str
27
+
28
+ # Create server
29
+ server = StepflowStdioServer()
30
+
31
+ # Register a component
32
+ @server.component
33
+ def my_component(input: MyInput) -> MyOutput:
34
+ return MyOutput(result=f"Processed: {input.message} x{input.count}")
35
+
36
+ # Component with context (for blob operations)
37
+ @server.component
38
+ async def component_with_context(input: MyInput, context: StepflowContext) -> MyOutput:
39
+ # Store data as a blob
40
+ blob_id = await context.put_blob({"processed": input.message})
41
+ return MyOutput(result=f"Stored blob: {blob_id}")
42
+
43
+ # Run the server
44
+ if __name__ == "__main__":
45
+ server.run()
46
+ ```
47
+
48
+ ### Using the Context API
49
+
50
+ The `StepflowContext` provides bidirectional communication with the StepFlow runtime:
51
+
52
+ ```python
53
+ # Store JSON data as a blob
54
+ blob_id = await context.put_blob({"key": "value"})
55
+
56
+ # Retrieve blob data
57
+ data = await context.get_blob(blob_id)
58
+
59
+ # Logging
60
+ context.log("Debug message")
61
+ ```
62
+
63
+ ## Development
64
+
65
+ ### Running Tests
66
+
67
+ ```bash
68
+ uv run pytest
69
+ ```
70
+
71
+ ### Type Checking
72
+
73
+ ```bash
74
+ uv run mypy src/
75
+ ```
76
+
77
+ ### Protocol Generation
78
+
79
+ This SDK uses auto-generated protocol types from the JSON schema. To regenerate the protocol types when the schema changes:
80
+
81
+ ```bash
82
+ uv run python generate.py
83
+ ```
84
+
85
+ The generation script automatically handles the generation and applies necessary fixes for msgspec compatibility.
86
+
87
+ ### Project Structure
88
+
89
+ - `src/stepflow_py/` - Main SDK code
90
+ - `generated_protocol.py` - Auto-generated protocol types from JSON schema
91
+ - `protocol.py` - Hybrid protocol layer with envelope patterns for efficient deserialization
92
+ - `server.py` - Component server implementation
93
+ - `context.py` - Runtime context API
94
+ - `exceptions.py` - SDK-specific exceptions
95
+ - `tests/` - Test suite
96
+
97
+ ### Architecture
98
+
99
+ The SDK uses a hybrid approach for protocol handling:
100
+
101
+ 1. **Generated Types** (`generated_protocol.py`) - Auto-generated from the StepFlow JSON schema using `datamodel-code-generator`
102
+ 2. **Protocol Layer** (`protocol.py`) - Combines generated types with manual envelope patterns for two-stage deserialization using `msgspec.Raw`
103
+ 3. **Server Implementation** - Uses the protocol layer for efficient JSON-RPC message handling
104
+
105
+ This design provides:
106
+ - **Type Safety** - All protocol messages use properly typed structs
107
+ - **Schema Consistency** - Generated types match the Rust protocol exactly
108
+ - **Performance** - Two-stage deserialization with `msgspec.Raw` for optimal speed
109
+ - **Maintainability** - Protocol changes can be regenerated automatically
110
+
111
+ ## License
112
+
113
+ Licensed under the Apache License, Version 2.0.
@@ -0,0 +1,86 @@
1
+ # Configuration file for git-cliff for Python SDK package
2
+ # See: https://git-cliff.org/docs/configuration
3
+
4
+ [changelog]
5
+ # Changelog header
6
+ header = """
7
+ # Changelog
8
+
9
+ All notable changes to this project will be documented in this file.
10
+
11
+ """
12
+ # Template for the changelog body
13
+ body = """
14
+ {%- if version -%}
15
+ {%- set clean_version = version | trim_start_matches(pat="stepflow-py-") -%}
16
+ ## <a id="{{ clean_version }}"></a> [StepFlow Python SDK {{ clean_version }}](https://github.com/riptano/stepflow/releases/tag/stepflow-py-{{ clean_version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
17
+ {%- else -%}
18
+ ## unreleased
19
+ {%- endif -%}
20
+ {%- if message %}
21
+ {{ message }}
22
+ {% endif -%}
23
+ {% for group, commits in commits | group_by(attribute="group") %}
24
+ ### {{ group | striptags | trim | upper_first }}
25
+ {% for commit in commits %}
26
+ - {{ commit.message | upper_first }}\
27
+ {%- endfor %}
28
+ {% endfor %}\n
29
+ """
30
+ # Remove the trailing whitespace in the template
31
+ trim = true
32
+ # Changelog footer
33
+ footer = """
34
+ <!-- generated by git-cliff -->
35
+ """
36
+
37
+ [git]
38
+ # Parse the commits based on https://www.conventionalcommits.org
39
+ conventional_commits = true
40
+ # Filter out commits that are not conventional
41
+ filter_unconventional = true
42
+ # Process each line of a commit as an individual commit
43
+ split_commits = false
44
+ # Only include commits that affect the Python SDK directory or root files that affect Python SDK
45
+ filter_commits = true
46
+ # Include commits that modify files in these paths
47
+ include_paths = [
48
+ "sdks/python/**",
49
+ "CLAUDE.md",
50
+ "CONTRIBUTING.md",
51
+ "README.md",
52
+ ".github/workflows/release_python.yml",
53
+ ".github/workflows/release_prepare.yml",
54
+ ".github/workflows/release_dispatch.yml",
55
+ ".github/workflows/ci.yml"
56
+ ]
57
+ # Regex for preprocessing the commit messages
58
+ commit_preprocessors = [
59
+ { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/riptano/stepflow/pull/${2}))"},
60
+ ]
61
+ # Regex for parsing and grouping commits
62
+ commit_parsers = [
63
+ { message = "^feat", group = "Features"},
64
+ { message = "^fix", group = "Bug Fixes"},
65
+ { message = "^doc", group = "Documentation"},
66
+ { message = "^perf", group = "Performance"},
67
+ { message = "^refactor", group = "Refactoring"},
68
+ { message = "^style", group = "Style"},
69
+ { message = "^test", group = "Testing"},
70
+ { message = "^chore\\(release\\):", skip = true},
71
+ { message = "^chore\\(deps\\)", skip = true},
72
+ { message = "^chore|^ci", group = "Miscellaneous Tasks"},
73
+ { body = ".*security", group = "Security"},
74
+ { message = "^revert", group = "Revert"},
75
+ ]
76
+ # Protect breaking changes from being skipped due to matching a skipping commit_parser
77
+ protect_breaking_commits = false
78
+ # Glob pattern for matching git tags
79
+ tag_pattern = "stepflow-py-[0-9.]*"
80
+ # Regex for skipping tags
81
+ # Regex for ignoring tags
82
+ ignore_tags = ""
83
+ # Sort the tags topologically
84
+ topo_order = false
85
+ # Sort the commits inside sections by oldest/newest order
86
+ sort_commits = "oldest"
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ # Licensed to the Apache Software Foundation (ASF) under one or more contributor
3
+ # license agreements. See the NOTICE file distributed with this work for
4
+ # additional information regarding copyright ownership. The ASF licenses this
5
+ # file to you under the Apache License, Version 2.0 (the "License"); you may not
6
+ # use this file except in compliance with the License. You may obtain a copy of
7
+ # the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations under
15
+ # the License.
16
+
17
+ """
18
+ Example demonstrating session_id access in components.
19
+ This shows how HTTP mode components can access their session ID.
20
+ """
21
+
22
+ import msgspec
23
+
24
+ from stepflow_py import StepflowContext, StepflowServer
25
+
26
+ # Create server instance
27
+ server = StepflowServer()
28
+
29
+
30
+ class SessionInput(msgspec.Struct):
31
+ message: str
32
+
33
+
34
+ class SessionOutput(msgspec.Struct):
35
+ processed_message: str
36
+ session_id: str | None
37
+ transport_mode: str
38
+
39
+
40
+ @server.component
41
+ def session_aware_component(
42
+ input: SessionInput, context: StepflowContext
43
+ ) -> SessionOutput:
44
+ """Component that demonstrates session_id access."""
45
+
46
+ # Access the session ID from the context
47
+ session_id = context.session_id
48
+
49
+ # Determine transport mode based on session_id presence
50
+ transport_mode = "HTTP" if session_id is not None else "STDIO"
51
+
52
+ return SessionOutput(
53
+ processed_message=f"Processed: {input.message}",
54
+ session_id=session_id,
55
+ transport_mode=transport_mode,
56
+ )
57
+
58
+
59
+ if __name__ == "__main__":
60
+ # This example can be run in both STDIO and HTTP modes
61
+ print("Session-aware component server started")
62
+ print("In STDIO mode: session_id will be None")
63
+ print("In HTTP mode: session_id will be the actual session ID")
64
+ server.run()