-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat:declare optional schema on streamsync state #278
Merged
ramedina86
merged 4 commits into
writer:dev
from
FabienArcellier:277-declare-optional-schema-on-streamsync-state-1
Mar 18, 2024
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
7a335af
feat: declare optional schema on streamsync state
FabienArcellier 723630b
feat: declare optional schema on streamsync state
FabienArcellier 1f7d38c
feat: declare optional schema on streamsync state
FabienArcellier 677be06
feat: declare optional schema on streamsync state
FabienArcellier File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
# State schema | ||
|
||
Schema declaration on the [Application state](./application-state) allows Streamsync to handle complex serialization | ||
scenario and empower your IDE and toolchains to provide autocomplete and type checking. | ||
|
||
## Schema declaration | ||
|
||
```python | ||
import streamsync as ss | ||
|
||
class AppSchema(ss.StreamsyncState): | ||
counter: int | ||
|
||
initial_state = ss.init_state({ | ||
"counter": 0 | ||
}, schema=AppSchema) | ||
|
||
# Event handler | ||
# It receives the session state as an argument and mutates it | ||
def increment(state: AppSchema): | ||
state.counter += 1 | ||
``` | ||
|
||
Access to an attribute by its key is always possible. | ||
|
||
```python | ||
def increment(state: AppSchema): | ||
state['counter'] += 1 | ||
``` | ||
|
||
Attributes missing from the schema remain accessible by their key. | ||
|
||
```python | ||
initial_state = ss.init_state({ | ||
"counter": 0, | ||
"message": None | ||
}, schema=AppSchema) | ||
|
||
def increment(state: AppSchema): | ||
state['message'] = "Hello pigeon" | ||
``` | ||
|
||
## Schema composition | ||
|
||
Schema composition allows you to model a complex Application state. | ||
|
||
```python | ||
class MyappSchema(ss.State): | ||
title: str | ||
|
||
class AppSchema(ss.StreamsyncState): | ||
my_app: MyappSchema | ||
counter: int | ||
|
||
initial_state = ss.init_state({ | ||
"counter": 0, | ||
"my_app": { | ||
"title": "Nested value" | ||
} | ||
}, schema=AppSchema) | ||
``` | ||
|
||
## Multi-level dictionary | ||
|
||
Some components like Vega require specifying a graph in the form of a multi-level dictionary. | ||
|
||
A schema allows you to specify to streamsync that an attribute which contains a dictionary | ||
must be treated as a dictionary and not as a group of state. | ||
|
||
```python | ||
class AppSchema(ss.StreamsyncState): | ||
vegas_graph: dict | ||
|
||
# Without schema, this handler is execute only once | ||
def handle_vega_graph(state: AppSchema): | ||
graph = state.vega_graph | ||
graph['data']['values'][0]['b'] += 1000 | ||
state.vega_graph = graph | ||
|
||
initial_state = ss.init_state({ | ||
"vegas_graph": { | ||
"data": { | ||
"values": [ | ||
{"a": "C", "b": 2}, {"a": "C", "b": 7}, {"a": "C", "b": 4}, | ||
{"a": "D", "b": 1}, {"a": "D", "b": 2}, {"a": "D", "b": 6}, | ||
{"a": "E", "b": 8}, {"a": "E", "b": 4}, {"a": "E", "b": 7} | ||
] | ||
}, | ||
"mark": "bar", | ||
"encoding": { | ||
"x": {"field": "a", "type": "nominal"}, | ||
"y": {"aggregate": "average", "field": "b", "type": "quantitative"} | ||
} | ||
}, | ||
}, schema=AppSchema) | ||
``` | ||
|
||
## Type checking | ||
|
||
A schema allows you to check the integrity of your backend using the type system. | ||
The code below will raise an error with mypy. | ||
|
||
```bash | ||
$ mypy apps/myapp/main.py | ||
apps/myapp/main.py:7: error: "AppSchema" has no attribute "countr"; maybe "counter"? [attr-defined] | ||
``` | ||
|
||
Here is the code, can you spot the error ? | ||
|
||
```python | ||
import streamsync as ss | ||
|
||
class AppSchema(ss.StreamsyncState): | ||
counter: int | ||
|
||
def increment(state: AppSchema): | ||
state.countr += 1 | ||
|
||
initial_state = ss.init_state({ | ||
"counter": 26, | ||
}, schema=AppSchema) | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some minor comments about style, e.g. British spelling, capitalisation of some words, etc, but I'll take care of them. Nice docs though!