Skip to content

Commit

Permalink
Refactor tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
anant-writer authored and FabienArcellier committed Jun 14, 2024
1 parent 979a142 commit 2b3f49c
Show file tree
Hide file tree
Showing 78 changed files with 141 additions and 145 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 Writer Framework?
## What is Framework?

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

Expand Down
10 changes: 5 additions & 5 deletions docs/framework/authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: "Authentication"

The Writer framework authentication module allows you to restrict access to your application.

Writer framework offers either simple password authentication or identity provider authentication (Google, Microsoft, Facebook, Github, Auth0, etc.).
Framework will be able to authenticate a user through an identity provider such as Google, Microsoft, Facebook, Github, Auth0, etc.

<Warning>
Authentication is done before accessing the application. It is not possible to
Expand Down Expand Up @@ -53,7 +53,7 @@ modifying the value of delay_after_failure.
Authentication configuration is done in the `server_setup.py` [module](custom-server.md). The configuration depends on your identity provider.
Here is an example configuration for Google.

![Authentication OIDC Principle](/framework/images/authentication_oidc_principle.png)
![Authentication OIDC Principle](/framework/images/auth.png)

**server_setup.py**

Expand All @@ -80,9 +80,9 @@ Writer framework provides pre-configured OIDC providers. You can use them direct

| Provider | Function | Description |
| -------- | ------------------------ | --------------------------------------------------------------------------------------- |
| Google | `streamsync.auth.Google` | Allow your users to login with their Google Account |
| Github | `streamsync.auth.Github` | Allow your users to login with their Github Account |
| Auth0 | `streamsync.auth.Auth0` | Allow your users to login with different providers or with login password through Auth0 |
| Google | `writer.auth.Google` | Allow your users to login with their Google Account |
| Github | `writer.auth.Github` | Allow your users to login with their Github Account |
| Auth0 | `writer.auth.Auth0` | Allow your users to login with different providers or with login password through Auth0 |

#### Google

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
12 changes: 6 additions & 6 deletions docs/framework/backend-initiated-actions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
title: "Backend-initiated actions"
---

Targeted, backend-initiated actions can be triggered from event handlers, using methods of `state`. Internally, this is achieved using Streamsync's `mail`, ephemeral state that is cleared when it reaches the intended user.
Targeted, backend-initiated actions can be triggered from event handlers, using methods of `state`. Internally, this is achieved using Framework's `mail`, ephemeral state that is cleared when it reaches the intended user.

## Triggering a file download

The `file_download` method takes the `data` and `file_name` arguments. The first must contain raw bytes (a `bytes` object) or a packed file. As mentioned in the [Application State](application-state.html#files-and-binary-data) section of the guide, a packed file is obtained using the `ss.pack_file` or `ss.pack_bytes` methods.
The `file_download` method takes the `data` and `file_name` arguments. The first must contain raw bytes (a `bytes` object) or a packed file. As mentioned in the [Application State](application-state.html#files-and-binary-data) section of the guide, a packed file is obtained using the `wf.pack_file` or `wf.pack_bytes` methods.

```py
def handle_file_download(state):
# Pack the file as a FileWrapper object
data = ss.pack_file("assets/story.txt", "text/plain")
data = wf.pack_file("assets/story.txt", "text/plain")
file_name = "thestory.txt"
state.file_download(data, file_name)
```
Expand All @@ -20,7 +20,7 @@ def handle_file_download(state):

![Notifications](./images/backend-initiated-actions.notifications.png)

Streamsync adds notifications when a runtime error takes place. You can add your own notifications using the `add_notification` method, which takes the `type`, `title` and `message` arguments. `type` must be one of `error`, `warning`, `info`, `success`.
Framework adds notifications when a runtime error takes place. You can add your own notifications using the `add_notification` method, which takes the `type`, `title` and `message` arguments. `type` must be one of `error`, `warning`, `info`, `success`.

```py
def notify_of_things_that_happened(state):
Expand All @@ -35,8 +35,8 @@ def notify_of_things_that_happened(state):
Open a URL in a new tab using the `open_url` method, which takes the `url` argument.

```py
def handle_open_streamsync_website(state):
state.open_url("https://streamsync.cloud")
def handle_open_website(state):
state.open_url("https://writer.com")
```

The URL will be safely opened with `noopener` and `noreferrer` options.
Expand Down
18 changes: 9 additions & 9 deletions docs/framework/builder-basics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
title: "Builder basics"
---

Streamsync Builder works as an overlay of the running app; you edit your app while it's running. It gives you an accurate representation of what the app will look like and how it'll behave, without the need to constantly preview it. Changes to the user interface are automatically saved to `ui.json`.
Framework Builder works as an overlay of the running app; you edit your app while it's running. It gives you an accurate representation of what the app will look like and how it'll behave, without the need to constantly preview it. Changes to the user interface are automatically saved to `ui.json`.

## Modes

You can switch modes between _User Interface_, _Code_ and _Preview_ using the buttons on the top bar.

### User Interface

![Streamsync Builder - Mode: User Interface](/framework/images/builder-basics.ui.png)
![Framework Builder - Mode: User Interface](/framework/images/builder-basics.ui.png)

The default mode. Allows you to focus on building the interface.

### Code

![Streamsync Builder - Mode: Code](/framework/images/builder-basics.code.png)
![Framework Builder - Mode: Code](/framework/images/builder-basics.code.png)

This mode displays the code editor and the application log, while still allowing you to access the _Component Tree_ and _Settings_.

Expand All @@ -30,7 +30,7 @@ If you need a more powerful editor or if your codebase is distributed across sev

Code changes are automatically detected

The application will reload whenever a change to a `.py` file inside the app folder is detected. This feature only works in Streamsync Builder i.e. `edit` mode, not when running the app in `run` mode.
The application will reload whenever a change to a `.py` file inside the app folder is detected. This feature only works in Framework Builder i.e. `edit` mode, not when running the app in `run` mode.

</Note>

Expand All @@ -40,7 +40,7 @@ Exceptions raised by your application are shown here, as log entries. Standard o

### Preview

![Streamsync Builder - Mode: Preview](/framework/images/builder-basics.preview.png)
![Framework Builder - Mode: Preview](/framework/images/builder-basics.preview.png)

The _Preview_ mode shows the application exactly like the user will see it. It allocates the whole width of the viewport to the app.

Expand All @@ -51,7 +51,7 @@ The _Preview_ mode shows the application exactly like the user will see it. It a
- Certain components have restrictions. For example, a _Column_ can only be added to a _Column Container_. A _Sidebar_ can only be added to a _Page_.
- By default, components are added in the last position. To add components in a specific position, drag over the desired parent until the insertion lines are shown.

![Streamsync Builder - Insertion position](./images/builder-basics.insertion.gif)
![Framework Builder - Insertion position](/framework/images/builder-basics.insertion.gif)

- You can drag and drop existing components within the app, from one parent to another, or within the same parent to reposition them.
- Alternatively, you can use the _Component Tree_ either as source or destination for drag and drop.
Expand All @@ -67,7 +67,7 @@ The _Preview_ mode shows the application exactly like the user will see it. It a

Settings are divided into the following sections. Changes to settings can be undone and redone using the buttons on the top bar.

![Streamsync Builder - Component settings](./images/builder-basics.component-settings.png)
![Framework Builder - Component settings](/framework/images/builder-basics.component-settings.png)

### Properties

Expand All @@ -83,7 +83,7 @@ Properties are of different types, such as _Text_, _Color_ and _Number_. All pro

### Binding

![Streamsync Builder - Binding](./images/builder-basics.binding.png)
![Framework Builder - Binding](/framework/images/builder-basics.binding.png)

Input components can be bound, in a two-way fashion, to a state element.

Expand All @@ -107,7 +107,7 @@ Whether the component should be displayed. There are three visibility options:

Perform a variety of operations on existing components. Options will be grayed out when they're not applicable to the relevant component. Most shortcuts can be triggered using the keyboard; hover on them to show the appropriate combination.

![Streamsync Builder - Component shortcuts](./images/builder-basics.component-shortcuts.png)
![Framework Builder - Component shortcuts](/framework/images/builder-basics.component-shortcuts.png)

- _Add_. Adds a child of a given type to this component.
- _Move up_. Decrements the position index of the component, used to sort children in the parent container.
Expand Down
24 changes: 12 additions & 12 deletions docs/framework/custom-components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "Custom components"
---

It's possible to extend Streamsync with custom component templates.
It's possible to extend Framework with custom component templates.

They're developed using Vue 3 and TypeScript. Once transpiled, they can be used by copying them to the `extensions/` folder of any project.

Expand All @@ -13,7 +13,7 @@ They are just as performant, can contain other components, and offer the same Bu

## Architecture

Streamsync frontend compiles to a collection of static assets that is distributed in the Python package. These static assets are then served via FastAPI.
Framework frontend compiles to a collection of static assets that is distributed in the Python package. These static assets are then served via FastAPI.

During initialisation time, the server scans the `extensions/` folder in the project folder and looks for `.css` and `.js` files. This folder is also served, similarly to `static/`. If it finds any valid files in `extensions/`, it shares the list with clients and tells them to dynamically import these files during runtime.

Expand All @@ -31,7 +31,7 @@ Dependencies are [_provided_](https://vuejs.org/api/composition-api-dependency-i

A template defines how a certain component is rendered. For example, `corebutton` defines how _Button_ components are rendered.

Streamsync component templates are purely frontend-based. **They are Vue 3 templates that extend the Vue specification** via a [custom option](https://vuejs.org/api/utility-types.html#componentcustomoptions), `streamsync`. This _custom option_ defines all the Streamsync-specific behaviour of the component. For example, its `fields` property establishes which fields will be editable via Builder.
Framework component templates are purely frontend-based. **They are Vue 3 templates that extend the Vue specification** via a [custom option](https://vuejs.org/api/utility-types.html#componentcustomoptions), `writer`. This _custom option_ defines all the Framework-specific behaviour of the component. For example, its `fields` property establishes which fields will be editable via Builder.

### Simple example

Expand All @@ -52,12 +52,12 @@ This example shows a template for _Bubble Message_, a simple demo component with
<script lang="ts">
export default {
streamsync: {
writer: {
name: "Bubble Message",
description: "Shows a message in the shape of a speech bubble.",
category: "Content",
// Fields will be editable via Streamsync Builder
// Fields will be editable via Framework Builder
fields: {
text: {
Expand Down Expand Up @@ -98,11 +98,11 @@ The code above will make _Bubble Message_ available in Builder.

### Run a local server

To get started, clone the [Streamsync repository](https://github.com/streamsync-cloud/streamsync) from GitHub.
To get started, clone the [Framework repository](https://github.com/streamsync-cloud/streamsync) from GitHub.

To develop custom templates, at least in a developer-friendly way, you'll need a frontend development server with instant reloads.

The frontend code for Streamsync can be found in the folder `ui`. With Node and npm in your system, run `npm install` to install dependencies, and start the server with support for custom component templates using `npm run custom.dev`.
The frontend code for Framework can be found in the folder `ui`. With Node and npm in your system, run `npm install` to install dependencies, and start the server with support for custom component templates using `npm run custom.dev`.

```sh
cd ui
Expand All @@ -116,14 +116,14 @@ npm run custom.dev

The command above will start a frontend server, but won't be of much use by itself —a backend is needed. The frontend development server proxies backend requests to port 5000.

Start Streamsync via command line, specifying the option `--port 5000`, to provide a backend in that port. It's recommended to create a new app for testing the template you're developing.
Start Framework via command line, specifying the option `--port 5000`, to provide a backend in that port. It's recommended to create a new app for testing the template you're developing.

```sh
streamsync create customtester
streamsync edit customtester --port 5000
writer create customtester
writer edit customtester --port 5000
```

You should now be able to access Streamsync via the URL provided by Vite, e.g. `http://localhost:5174`. In Builder's _Toolkit_, you should see the sample component, _Balloon Message_. Add it to your tester application.
You should now be able to access Framework via the URL provided by Vite, e.g. `http://localhost:5174`. In Builder's _Toolkit_, you should see the sample component, _Balloon Message_. Add it to your tester application.

### Create a new component

Expand Down Expand Up @@ -175,4 +175,4 @@ Collect the files from `ui/custom_components_dist` and pack them in a folder suc

### Try them

The folder containing the generated files, e.g. `my_custom_bubbles`, can now be placed in the `extensions/` folder of any Streamsync project. It'll be automatically detected during server startup.
The folder containing the generated files, e.g. `my_custom_bubbles`, can now be placed in the `extensions/` folder of any Framework project. It'll be automatically detected during server startup.
Loading

0 comments on commit 2b3f49c

Please sign in to comment.