Streamlit meets WebAssembly:

stlite

Hi👋

Yuichiro Tachibana

@whitphx

  • Pythonista
  • OSS enthusiast
  • Streamlit Creator
  • Streamlit/Gradio Advocate at Hugging Face

stlite:

WebAssembly port of Streamlit

Background:

Streamlit's pros and cons

What is                        ?

What is Streamlit?

One of the most popular frameworks

Custom components

Rich community, rich ecosystem

...and more and more 👉 https://streamlit.io/components

pip install stmol
pip install streamlit-drawable-canvas

Custom components

Rich community, rich ecosystem

...and more and more 👉 https://streamlit.io/components

pip install stmol
pip install streamlit-drawable-canvas

What is                        ?

streamlit run app.py
import streamlit as st

st.title("Hello World!")
name = st.text_input("What's your name?")
st.write(f"Hello, {name}!")
app.py

Write Python, get a web app!

streamlit run app.py
import streamlit as st

st.title("Hello World!")
name = st.text_input("What's your name?")
st.write(f"Hello, {name}!")
app.py

What happens?

What Streamlit does under the hood

📜

app.py

Web browser

JS runtime

streamlit run app.py

Python runtime

Streamlit

Server

Script runner

🌪️Web server

Static files

JS app

Render

Trigger events

Streamlit's drawbacks

Because it serves web pages from a web server,

and runs Python scripts on the server to process input data,

it lacks...

  • offline capability
  • data privacy

...and for service developers,

  • scalability
  • maintainability

are also sometimes problems.

What is                   ?

stlite is a port of Streamlit to WebAssembly

Client-side execution

stlite is a fork of Streamlit

that runs completely on web browsers.

The power of Pyodide

Pyodide is a Python distribution

for the browser and Node.js

based on WebAssembly.

Streamlit architecture

📜

app.py

Web browser

JS runtime

streamlit run app.py

Python runtime

Streamlit

Server

Script runner

🌪️Web server

Static files

JS app

Render

Trigger events

stlite architecture

📜

app.py

Web browser

JS runtime

Pyodide runtime

(Wasm CPython)

Streamlit

Worker

Script runner

Static files

JS app

Render

Trigger events

What stlite solves

  • Offline capability & data privacy
  • Scalability & maintainability
  • Multi-platform portability

Sample apps!

Basic Streamlit apps

Streamlit Hello

The official demo app bundled with the package

Component Gallery

Showcasing Streamlit's predefined components

Custom Components

Third-party libraries also work on stlite

Computer Vision apps

Real-time image processing

Save the video privacy

Development and Deployment options

Multi-platform capability

WebAssembly is eating the world

Web

Desktop

Mobile

stlite sharing

Web-based editor + sharing platform

Self-hosting

Embed stlite apps on your page

<!DOCTYPE html>
<html>
  <head>
    <title>stlite app</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/@stlite/mountable@0.26.0/build/stlite.css"
    />
  </head>
  <body>
    <div id="root"></div>
    <script src="https://cdn.jsdelivr.net/npm/@stlite/mountable@0.26.0/build/stlite.js"></script>
    <script>
      stlite.mount(
        `
import streamlit as st

name = st.text_input('Your name')
st.write("Hello,", name or "world")
`,
        document.getElementById("root")
      );
    </script>
  </body>
</html>

@stlite/desktop

Package stlite apps with Electron

VSCode extension

Develop stlite apps even on iPad

VSCode extension

Develop stlite apps even on iPad

Use cases

Good for

  • Private data
  • Restrictive network environment
  • Non-tech users
  • Education

Not good for

  • Secret source code
  • Unavailable packages on Pyodide

Summary

Summary

  • Streamlit is a low-code pure-Python WebUI framework.
  • "stlite" is a WebAssembly fork of Streamlit that runs completely on web browsers.
  • You can start with "stlite sharing."
  • Self-hosting web pages and building desktop apps are also options.
  • There are both use cases "stlite" is good for and not good for.

Thank you!

👈 Please ⭐️

Yuichiro Tachibana

@whitphx

👈 Send feature requests and bug reports!

Notable differences between Streamlit and stlite

Pyodide vs normal Python

Pyodide runs in the web browser environment.

Asyncio, Event loops

import asyncio
import streamlit as st

async def main():
    await asyncio.sleep(1)
    st.title("Hello World!")

asyncio.run(main())

Asyncio, Event loops

In the browser/Node environment,

the async features rely on the JS runtime.

There is only single running event loop.

Top-level await

import asyncio
import streamlit as st

st.title("Hello world!")
await asyncio.sleep(1)
st.title("Goodbye, world!")

Blocking methods

import time
import streamlit as st

st.title("Hello world!")
time.sleep(1)
st.title("Goodbye, world!")
import asyncio
import streamlit as st

st.title("Hello world!")
await asyncio.sleep(1)
st.title("Goodbye, world!")

On Pyodide, time.sleep() is no op.

🚫

Network access methods

On Pyodide, urllib and requests do not work.

> Why can’t I just use urllib or requests?

> We currently can’t use such packages since sockets are not available in Pyodide.

> https://pyodide.org/en/stable/usage/faq.html#how-can-i-load-external-files-in-pyodide

import urllib.request

res = urllib.request.urlopen("...")
import pyodide.http

res = await pyodide.http.pyfetch("...")

🚫

File systems

Browser environment

Pyodide

Virtual File System (Emscripten FIle System)

Streamlit

📜

app.py
open()
  • Pyodide has its virtual file system, and Python scripts access the files on it.
  • stlite provides an API to mount files to the file system.

Mount files to the FS

stlite.mount(
  {
    entrypoint: "👋_Hello.py",
    files: {
      "👋_Hello.py": `
import streamlit as st

st.set_page_config(page_title="Hello")
st.title("Main page")
`,
      "pages/1_⭐️_Page1.py": `
import streamlit as st

st.set_page_config(page_title="Page1")
st.title("Page 1")
`,
      "pages/2_🎈_Page2.py": `
import streamlit as st

st.set_page_config(page_title="Page2")
st.title("Page 2")
`,
    },
  },
  document.getElementById("root")
);

API design principles

We keep the original Streamlit's API as much as possible.

stlite's drawbacks

📜

app.py

Web browser

JS runtime

Pyodide runtime

(Wasm CPython)

Streamlit

Worker

Script runner

Static files

JS app

Render

Trigger events

Source code and data are open

Unavailable packages

but the situation is being improved!

... the package has binary extensions (e.g. C, Fortran or Rust), in which case it needs to be packaged in Pyodide.

https://pyodide.org/en/stable/usage/faq.html#why-can-t-micropip-find-a-pure-python-wheel-for-a-package

34 new packages have been added in Pyodide 0.21 release, including a large number of popular packages, for example bitarray, opencv-python, shapely, and xgboost.

 

Large initial payload

Network access restriction

import pyodide.http

res = await pyodide.http.pyfetch("https://streamlit.io")

Now,

you are ready to use stlite!

Community

Sponsors and supporters

Streamlit (Snowflake)

Databutton

Hal9

Hugging Face

Interlude:

Mass emergence of

Wasm-ported Python frameworks

JupyterLite & Pyodide

Unleashing the Python WebAssembly Revolution

Jeremy Tuloup, "JupyterLite: Jupyter ❤️ WebAssembly ❤️ Python", PyConDE & PyData Berlin 2022.

The Client-side Python Boom

WebAssembly Unleashes a New Era

PyScript

Shinylive

HoloViz Panel

stlite

Wasm has also been desired for Streamlit

Subtitle

Streamlit meets WebAssembly - stlite

By whitphx

Streamlit meets WebAssembly - stlite

  • 1,431