Skip to content

Commit

Permalink
Refactoring ss to wf
Browse files Browse the repository at this point in the history
  • Loading branch information
anant-writer committed May 29, 2024
1 parent ca7d67a commit 5b2efdf
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 84 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## What is Streamsync?
## What is Framework?

[![PyPi](https://img.shields.io/pypi/v/streamsync.svg?label=Version)](https://pypi.org/project/streamsync/)
[![CI](https://github.com/streamsync-cloud/streamsync/actions/workflows/ci.yml/badge.svg)](https://github.com/streamsync-cloud/streamsync/actions/workflows/ci.yml)
Expand Down
24 changes: 10 additions & 14 deletions docs/framework/backend-driven-ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@
title: "Backend-driven UI"
---

Streamsync facilitates backend-initiated user interface modifications. These changes are made possible through **Code-Managed Components** (CMCs), distinct from *Builder-Managed Components* (BMCs).
Framework facilitates backend-initiated user interface modifications. These changes are made possible through **Code-Managed Components** (CMCs), distinct from *Builder-Managed Components* (BMCs).

CMCs, unlike BMCs, are dynamically created and modified via backend code, and cannot be edited (but still can be viewed) within the application builder. It's important to also note that CMCs do not persist in your application's `ui.json` file and exist only during the application runtime, supporting dynamic UI adjustments.

<Warning>
Experimental feature! This Streamsync feature is still evolving. You may encounter unexpected behaviour. Your feedback is invaluable — please feel free to [share your experience and suggestions](https://github.com/streamsync-cloud/streamsync/discussions).
</Warning>

<Note>
To summarise:

Expand All @@ -26,16 +22,16 @@ To summarise:

## UI manager

Streamsync provides two independent approaches for managing your application's UI: initializing a base UI and making session-specific updates.
Framework provides two independent approaches for managing your application's UI: initializing a base UI and making session-specific updates.

### Initializing base UI

The `init_ui()` method sets up a UI manager to configure UI components at the application's startup. This creates a component set that is accessible across all sessions:

```python
import streamsync as ss
import writer as wf

with ss.init_ui() as ui:
with wf.init_ui() as ui:
with ui.Page(id="my-page"):
ui.Header({"text": "Hello World!"})
ui.ColumnContainer(id="column-container")
Expand Down Expand Up @@ -179,13 +175,13 @@ In addition to `content`, a set of fields which is specific to the component typ
def increment(state):
state["counter"] += 1

initial_state = ss.init_state({"counter": 0})
initial_state = wf.init_state({"counter": 0})

...

ui.Button(
{"text": "My Counter: @{counter}"},
handlers={"ss-click": increment}
handlers={"wf-click": increment}
)
# You have two options for adding a function
# to the `handlers` dictionary:
Expand All @@ -196,7 +192,7 @@ In addition to `content`, a set of fields which is specific to the component typ
*A component can be linked to multiple event handlers.*
- **`binding: dict[str, str]`**: Links the component to a state variable via [binding](https://www.streamsync.cloud/builder-basics.html#binding). The dictionary key is the bindable event, and the value is the state variable's name:
```python
initial_state = ss.init_state({
initial_state = wf.init_state({
"header_text": "Default Text"
"counter": 0
})
Expand All @@ -205,14 +201,14 @@ In addition to `content`, a set of fields which is specific to the component typ

ui.TextInput(
{"label": "Bound Text"},
binding={"ss-change": "header_text"}
binding={"wf-change": "header_text"}
)
# This input will display "Default Text"
# Changing the text in this input will modify the `header_text` variable

ui.SliderInput(
{"minValue": 0, "maxValue": 300, "stepSize": 1},
binding={"ss-number-change": "counter"}
binding={"wf-number-change": "counter"}
)
# This slider will have 0 as a default value
# Sliding it will modify the `counter` variable
Expand All @@ -221,7 +217,7 @@ In addition to `content`, a set of fields which is specific to the component typ

### Container components

Streamsync provides multiple layout components that can serve as *containers* for other components.
Framework provides multiple layout components that can serve as *containers* for other components.

You can use `with` keyword to define such layouts:
```python
Expand Down
8 changes: 4 additions & 4 deletions docs/framework/deploy-with-docker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
title: "Deploy with Docker"
---

You can use Docker to deploy Streamsync anywhere. If you're an experienced Docker user, you may want to go straight to the provided Dockerfile.
You can use Docker to deploy Framework anywhere. If you're an experienced Docker user, you may want to go straight to the provided Dockerfile.

## Creating a Docker image

### Setting up

- Make sure you have Docker installed.
- Open a terminal and navigate to your app's folder.
- Create a `pyproject.toml` using `poetry init` and install `streamsync` using `poetry add streamsync`
- Create a `pyproject.toml` using `poetry init` and install `writer` using `poetry add writer`

### Creating a Dockerfile

Expand All @@ -27,15 +27,15 @@ WORKDIR /app
RUN pip3 install poetry
RUN poetry config virtualenvs.create false
RUN poetry install --only main
ENTRYPOINT [ "streamsync", "run" ]
ENTRYPOINT [ "writer", "run" ]
EXPOSE 8080
CMD [ ".", "--port", "8080", "--host", "0.0.0.0" ]
```

<Note>
This Dockerfile is just a guideline.
It uses an official Python slim base image with a multistage build to reduce the size of the built image.
If you're a Docker expert, feel free to work on your own `Dockerfile`. Streamsync is, after all, a standard Python package.
If you're a Docker expert, feel free to work on your own `Dockerfile`. Framework is, after all, a standard Python package.
</Note>

### Building the Docker image
Expand Down
18 changes: 9 additions & 9 deletions docs/framework/frontend-scripts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
title: "Frontend scripts"
---

Streamsync can import custom JavaScript/ES6 modules from the frontend. Module functions can be triggered from the backend.
Framework can import custom JavaScript/ES6 modules from the frontend. Module functions can be triggered from the backend.

## Importing an ES6 module

Similarly to [stylesheets](/stylesheets), frontend scripts are imported via Streamsync's `mail` capability. This allows you to trigger an import for all or specific sessions at any time during runtime. When the `import_frontend_module` method is called, this triggers a dynamic [import()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) call in the frontend.
Similarly to [stylesheets](/stylesheets), frontend scripts are imported via Framework's `mail` capability. This allows you to trigger an import for all or specific sessions at any time during runtime. When the `import_frontend_module` method is called, this triggers a dynamic [import()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) call in the frontend.

The `import_frontend_module` method takes the `module_key` and `specifier` arguments. The `module_key` is an identifier used to store the reference to the module, which will be used later to call the module's functions. The `specifier` is the path to the module, such as `/static/mymodule.js`. It needs to be available to the frontend, so storing in the `/static/` folder is recommended.

Expand All @@ -20,7 +20,7 @@ def handle_click(state):
If you want the module to be imported during initialisation, use the initial state.

```py
initial_state = ss.init_state({
initial_state = wf.init_state({
"counter": 1
})

Expand Down Expand Up @@ -61,10 +61,10 @@ def handle_click(state):

## Import a JavaScript script

Streamsync can also import and run JavaScript scripts directly, for their side effects. These are imported via the report's `import_script` method. This method takes two arguments. The first, `script_key` is the identifier used to import the script. The second, `path` is the path to the file. The specified path must be available to the frontend, so storing it in your application's `./static` folder is recommended.
Framework can also import and run JavaScript scripts directly, for their side effects. These are imported via the report's `import_script` method. This method takes two arguments. The first, `script_key` is the identifier used to import the script. The second, `path` is the path to the file. The specified path must be available to the frontend, so storing it in your application's `./static` folder is recommended.

```py
initial_state = ss.init_state({
initial_state = wf.init_state({
"counter": 1
})

Expand All @@ -79,10 +79,10 @@ Importing scripts is useful to import libraries that don't support ES6 modules.

## Importing a script or stylesheet from a URL

Streamsync can also import scripts and stylesheets from URLs. This is useful for importing libraries from CDNs. The `import_script` and `import_stylesheet` methods take a `url` argument, which is the URL to the script or stylesheet.
Framework can also import scripts and stylesheets from URLs. This is useful for importing libraries from CDNs. The `import_script` and `import_stylesheet` methods take a `url` argument, which is the URL to the script or stylesheet.

```python
initial_state = ss.init_state({
initial_state = wf.init_state({
"my_app": {
"title": "My App"
},
Expand All @@ -93,7 +93,7 @@ initial_state.import_script("lodash", "https://cdnjs.cloudflare.com/ajax/libs/lo

## Frontend core

You can access Streamsync's frontend core via `globalThis.core`, unlocking all sorts of functionality. Notably, you can use `getUserState()` to get values from state.
You can access Framework's frontend core via `globalThis.core`, unlocking all sorts of functionality. Notably, you can use `getUserState()` to get values from state.

```js
export function alertHueRotationValue() {
Expand All @@ -105,5 +105,5 @@ export function alertHueRotationValue() {
<Warning>
Here be dragons

Effectively using Streamsync's core can be challenging and will likely entail reading its [source code](https://github.com/streamsync-cloud/streamsync/blob/master/ui/src/core/index.ts). Furthermore, it's considered an internal capability rather than a public API, so it may unexpectedly change between releases.
Effectively using Framework's core can be challenging and will likely entail reading its [source code](https://github.com/streamsync-cloud/streamsync/blob/master/ui/src/core/index.ts). Furthermore, it's considered an internal capability rather than a public API, so it may unexpectedly change between releases.
</Warning>
10 changes: 5 additions & 5 deletions docs/framework/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
title: "Introduction"
---

## What is Streamsync?
## What is Framework?

Streamsync is an open-source framework for creating data apps. Build user interfaces using a visual editor; write the backend code in Python.
Framework is an open-source framework for creating data apps. Build user interfaces using a visual editor; write the backend code in Python.

![Streamsync Builder screenshot](/framework/public/builder.png)
![Framework Builder screenshot](/framework/public/builder.png)

It's an alternative to Plotly Dash, Streamlit and Gradio. Its focused on the creation of web applications for data analytics and machine learning.

Expand All @@ -21,12 +21,12 @@ Event handlers are defined as plain, easily-testable Python functions.
def handle_increment(state):
state["counter"] += 1

ss.init_state({
wf.init_state({
"counter": 0
})
```

The event handler and state are linked to the UI using Streamsync Builder, the framework's visual editor.
The event handler and state are linked to the UI using Framework Builder, the framework's visual editor.

![Counter Increment example](/framework/public/introduction.counter.gif)

Expand Down
6 changes: 3 additions & 3 deletions docs/framework/page-routes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "Page routes"
---

Streamsync apps can have multiple pages, with parametrised routes. Pages can be switched from the frontend or the backend.
Framework apps can have multiple pages, with parametrised routes. Pages can be switched from the frontend or the backend.

## Basic navigation

Expand Down Expand Up @@ -33,7 +33,7 @@ def handle_click(state):

You may want to share a URL that links directly to a specific resource within your app. For example, to a specific location or product.

You can do so by specifying parameters in the URL, known as route vars. Streamsync URLs contain the page key, followed by the route vars and their values. For example, `/#detailPage/product_id=32&country=AR`.
You can do so by specifying parameters in the URL, known as route vars. Framework URLs contain the page key, followed by the route vars and their values. For example, `/#detailPage/product_id=32&country=AR`.

### Adding vars to the URL from the backend

Expand All @@ -50,7 +50,7 @@ def change_route_vars(state):

### Retrieving the values

Streamsync uses the hash portion of the URL to store page and variable data, so even when switching pages or changing variables, the page doesn't reload. To monitor changes to the active URL, set up an event handler for `ss-hashchange` in the _Root_ component.
Framework uses the hash portion of the URL to store page and variable data, so even when switching pages or changing variables, the page doesn't reload. To monitor changes to the active URL, set up an event handler for `wf-hashchange` in the _Root_ component.

```py
# The following event handler reads the product_id route var,
Expand Down
Loading

0 comments on commit 5b2efdf

Please sign in to comment.