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.
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