Package to convert a streamlit script and files to an stlite app (https://github.com/whitphx/stlite)
Project description
script2stlite
Note: This project is continuously under development.
A Python package to convert Streamlit applications into single, self-contained HTML files that run entirely in the browser using stlite.
This allows you to easily share or deploy your Streamlit apps as static web pages without needing a Python backend server.
This project was created to easily allow existing streamlit apps to be converted to stlite web apps. Another GREAT way to generate stlite web apps is using https://edit.share.stlite.net/
The creator of stlite and edit.share.stlite.net is Yuichiro Tachibana (whitphx)
Features
- Prepare Project Folders: Initialize a directory with the necessary structure (
pagessubdirectory) and a templatesettings.yamlconfiguration file. - Convert to HTML: Bundle your Streamlit application (main script, pages, requirements, and other assets) into a single HTML file.
- Class-Based Conversion: Offers a
Script2StliteConverterclass for an object-oriented approach to managing the conversion process. - Version Pinning: Allows specifying particular versions of
stliteandPyodideto be used for the conversion. - Automatic Dependency Handling: Reads your Python package requirements from
settings.yamland includes them in thestlitebuild.
Installation
You can install script2stlite using pip:
pip install script2stlite
Example web apps from the /example folder
- Simple first example
- Multi-page app - simple image editor
- Example using requests - Recent daily Bitcoin price
- Simple conversion from existing web app - Streamlit cheat sheet by Daniel Lewis
- More complex app conversion - Streamlit ECharts demo by Fanilo Andrianasolo
- Example with Machine Learning - PixelHue by Juncel Datinggaling
- How to add a config.toml file to control app appearance - Vizzu example by Germán Andrés and Castaño Vásquez
- File Persistence Demo
- IDBFS File Browser
Quick Start with Example_0_simple_app
This quick start guide uses the example application located in the example/Example_0_simple_app directory of this repository.
1. Initialize the Converter and Prepare the Folder
First, you'll use the Script2StliteConverter class. Point it to the directory containing the example application. Then, call prepare_folder() to ensure the necessary settings.yaml file is present (it will be created from a template if it doesn't exist) and a pages subdirectory is available.
from script2stlite import Script2StliteConverter
# Initialize the converter with the path to the example app
# If you have cloned the repository, this path will be relative to the repo root.
converter = Script2StliteConverter(directory="example/Example_0_simple_app")
# Prepare the folder. This creates 'settings.yaml' if it's missing
# and ensures a 'pages' directory exists.
# For this example, 'settings.yaml' is already provided.
converter.prepare_folder()
2. Review settings.yaml
The prepare_folder() step ensures a settings.yaml file is in place. For Example_0_simple_app, the settings.yaml file looks like this:
APP_NAME: "my simple app" #give your app a nice name
APP_REQUIREMENTS: #app requirements separated by a '-' on each new line. Requirements MUST be compatible with pyodide. Suggest specifying versions.
- streamlit
- pandas
- numpy
APP_ENTRYPOINT: home.py #entrypoint to app - main python file
CONFIG: false
APP_FILES: #each file separated by a '-'. Can be .py files or other filetypes that will be converted to binary and embeded in the html.
- functions.py #additional files for the conversion to find and include.
- assets/image.jpg
Key fields in this example:
APP_NAME: "my simple app" - This will be used for the HTML file name and page title.APP_REQUIREMENTS: Listsstreamlit,pandas, andnumpy.APP_ENTRYPOINT:home.py- This is the main script for the Streamlit app.CONFIG:false(or a path like.streamlit/config.toml) - Specifies an optional Streamlit configuration file. If a path is provided, it must point to a TOML file. Set tofalseif no configuration file is used. An example using a TOML config can be found inexample/Example_6_vizzu.APP_FILES: Includesfunctions.py(a supporting Python module) andassets/image.jpg(an image asset).
3. Review the Streamlit Application Code
The main application script for this example is example/Example_0_simple_app/home.py:
import streamlit as st
from functions import random_pandas_dataframe
#say something
st.write("This text is from home.py")
#get a dataframe
st.write("The dataframe below is from functions.py")
df = random_pandas_dataframe()
st.write(df)
#show an image
st.write("The image below in in the assets folder, but is embeded into the html file.")
st.image("assets/image.jpg")
This script imports a function from functions.py (which is listed in APP_FILES), displays some text, shows a Pandas DataFrame, and an image.
4. Convert Your Project to HTML
With the folder prepared and settings reviewed, you can convert the project into a single HTML file using the convert() method:
# Assuming 'converter' is the Script2StliteConverter instance from Step 1.
converter.convert()
# This will read 'settings.yaml' from 'example/Example_0_simple_app',
# bundle all specified files, and generate 'my_simple_app.html'
# inside the 'example/Example_0_simple_app' directory.
After running this, you will find my_simple_app.html in the example/Example_0_simple_app directory. You can open this file in any modern web browser to run the Streamlit application.
You can also view a hosted version of this example here: https://lukeafullard.github.io/script2stlite/example/Example_0_simple_app/my_simple_app.html
Other Examples
For more examples (as they become available), please check the example directory in this repository. Each subfolder there will typically contain a self-contained Streamlit application ready for conversion with script2stlite.
How it Works
script2stlite streamlines the process of packaging your Streamlit application for browser-only execution. Here's a simplified overview:
- Configuration Reading: The tool reads your project's structure and dependencies from the
settings.yamlfile. This includes your main application script (APP_ENTRYPOINT), any additional pages or Python modules (APP_FILES), and Python package requirements (APP_REQUIREMENTS). - File Aggregation: It collects all specified Python scripts, data files, and assets. Python files and text-based data files are read as strings. Binary files (like images) are base64 encoded.
- HTML Generation:
script2stliteuses an HTML template that is pre-configured to usestlite. It injects your application's details into this template:- The content of your main Streamlit script (
APP_ENTRYPOINT) becomes the primary script executed bystlite. - Other Python files and data files from
APP_FILESare embedded into thestlitevirtual filesystem, making them accessible to your application at runtime. - The package
APP_REQUIREMENTSare listed forstliteto install viamicropipfrom Pyodide. - Links to the necessary
stliteCSS and JavaScript bundles, and the specified Pyodide version, are included.
- The content of your main Streamlit script (
- Bundling: The result is a single HTML file. This file contains your entire Streamlit application (code, data, assets) and the
stliteruntime environment. - Browser Execution: When you open this HTML file in a web browser:
stliteinitializes Pyodide, which is a port of Python to WebAssembly.- The specified Python packages are downloaded and installed into the Pyodide environment.
- Your Streamlit application code is executed by the Python interpreter running in the browser.
- Streamlit components are rendered directly in the HTML page, providing the interactive experience.
Essentially, script2stlite automates the setup described in the stlite documentation for self-hosting, packaging everything neatly into one portable HTML file. It leverages stlite's ability to run Streamlit applications without a server by bringing the Python runtime and Streamlit framework into the browser environment.
Limitations
Since script2stlite relies on stlite and Pyodide, it inherits their limitations. Key considerations include:
-
Pyodide Package Compatibility:
- All Python packages listed in
APP_REQUIREMENTSmust be compatible with Pyodide. This generally means they should be pure Python or have pre-compiled WebAssembly wheels available. - Packages with complex binary dependencies that are not specifically ported to the Pyodide environment will not work.
- For more details on Pyodide package support, see:
- All Python packages listed in
-
Inherited
stliteLimitations:st.spinner(): May not display correctly with blocking methods due to the single-threaded browser environment. A workaround is to useawait asyncio.sleep(0.1)before the blocking call.st.bokeh_chart(): Currently does not work as Pyodide uses Bokeh 3.x while Streamlit supports 2.x.time.sleep(): Is a no-op. Useawait asyncio.sleep()instead (requires usingasyncfunctions and top-level await where necessary).st.write_stream(): Should be used with async generator functions for reliable behavior.- DataFrame Serialization: Minor differences in how some data types in DataFrame columns are handled by
st.dataframe(),st.data_editor(),st.table(), and Altair-based charts, becausestliteuses Parquet for serialization instead of Arrow IPC. - Micropip Version Resolution: Package version resolution by
micropip(used by Pyodide) can sometimes fail or lead to unexpected versions, especially with complex dependencies. - For a comprehensive list of
stlitelimitations, refer to the official stlite documentation.
-
File System:
- The default file system (MEMFS) provided by
stlite/Pyodide is ephemeral. Any files written by your application at runtime (e.g., saving a generated file) will be lost when the browser tab is closed or reloaded. stlitesupports persistent storage using IDBFS (IndexedDB File System). However,script2stlitedoes not currently offer a direct configuration option insettings.yamlto set up IDBFS mount points. Implementing persistent storage would require manual modification of the generated HTML to include theidbfsMountpointsoption in thestlite.mount()call, as described in the stlite documentation on file persistence.
- The default file system (MEMFS) provided by
-
HTTP Requests:
- Standard Python networking libraries like
socketdo not work directly in the browser. - For making HTTP requests, use Pyodide-specific mechanisms like
pyodide.http.pyfetch()orpyodide.http.open_url(). - The
requestslibrary and parts ofurllibare patched bypyodide-httpto work in many common cases, but some advanced features might not be available. See the stlite documentation on HTTP requests and pyodide-http for details.
- Standard Python networking libraries like
-
Performance:
- Initial load time can be significant, as the browser needs to download Pyodide,
stlite, and your application's packages. - CPU-intensive Python operations will run slower in the browser (via WebAssembly) compared to a native Python environment.
- Initial load time can be significant, as the browser needs to download Pyodide,
-
Browser Environment:
- Direct access to the local file system (outside the virtual Pyodide FS) or system resources is not possible due to browser security restrictions.
Advanced Usage
Specifying stlite and Pyodide Versions
You can control the versions of stlite (which also dictates the Streamlit version) and Pyodide used in the generated HTML file. This is useful for ensuring compatibility or using specific features from particular releases.
Pass the stlite_version and/or pyodide_version arguments to the convert method of the Script2StliteConverter class.
from script2stlite import Script2StliteConverter
converter = Script2StliteConverter(directory="my_stlite_app")
# Example: Pin stlite to version 0.82.0 and Pyodide to 0.27.4
# Ensure settings.yaml and app files are ready in "my_stlite_app" first.
# converter.prepare_folder() # if needed
converter.convert(
stlite_version="0.82.0", # Check available stlite versions
pyodide_version="0.27.4" # Check available Pyodide versions compatible with stlite
)
script2stlite comes with lists of known compatible versions (see stlite_versions directory in the repository). If you specify a version not listed, it might lead to errors if the CDN links are incorrect or the versions are incompatible. By default, the latest known compatible versions are used.
Overriding Package Versions in Requirements
The Script2StliteConverter.convert() method includes a packages parameter (a dictionary). This parameter is intended for fine-grained control over package versions, potentially overriding what's listed in APP_REQUIREMENTS or how they are formatted for micropip.
Example:
from script2stlite import Script2StliteConverter
converter = Script2StliteConverter(directory="my_stlite_app")
# This is a more advanced use case, typically APP_REQUIREMENTS is sufficient.
# Ensure settings.yaml and app files are ready in "my_stlite_app" first.
# converter.prepare_folder() # if needed
converter.convert(
packages={"pandas": "pandas==1.5.3", "numpy": "numpy>=1.20.0,<1.23.0"}
)
In this example, if APP_REQUIREMENTS in settings.yaml just listed pandas and numpy, the packages argument would provide more specific version constraints for micropip.
However, for most use cases, defining your requirements directly in the APP_REQUIREMENTS list in settings.yaml with appropriate version specifiers (e.g., pandas==1.5.3, matplotlib>=3.5) is the recommended approach. The packages parameter offers an override mechanism primarily for scenarios where the user would like to keepa series of stlite apps on the same package versions. In theory this should reduce loading time for users since a single version of a package is downloaded, rather than multiple versions.
Using SharedWorker Mode
For applications where multiple stlite instances might run on the same page, stlite offers a "SharedWorker mode" to conserve resources by running all apps in a single worker.
To enable this mode, set the SHARED_WORKER key to true in your settings.yaml:
SHARED_WORKER: true
When this is enabled, script2stlite will configure the stlite.mount() call with the sharedWorker: true option.
Key considerations for SharedWorker mode:
- The Python environment and file system are shared across all apps.
- Package installations and module modifications are shared.
- It may not be supported in all browsers (e.g., Chrome on Android), in which case
stlitewill fall back to the default behavior. - For more details, refer to the stlite documentation on SharedWorker mode.
Using a Streamlit Configuration File (config.toml)
You can customize various aspects of your Streamlit application's appearance and behavior by providing a config.toml file. This is particularly useful for setting theme options, configuring server behaviors, or defining custom component settings.
To use a configuration file:
- Create a
config.tomlfile in your project, often placed in a.streamlitsubdirectory (e.g.,.streamlit/config.toml). - Specify the path to this file in your
settings.yamlunder theCONFIGkey. For example:CONFIG: .streamlit/config.toml
If you don't need a configuration file, setCONFIG: false.
script2stlite will embed the content of this config.toml file into the generated HTML, making it available to your stlite application.
Example config.toml:
[theme]
primaryColor="#F63366"
backgroundColor="#FFFFFF"
secondaryBackgroundColor="#F0F2F6"
textColor="#262730"
font="sans serif"
Key Points:
script2stlitesimply includes theconfig.tomlcontent. The interpretation and application of these settings are handled by Streamlit running withinstlite.- Not all options available in a standard Streamlit deployment might be relevant or function identically in the
stliteenvironment due to its browser-based nature. - For a comprehensive list of all available configuration options, please refer to the official Streamlit documentation on configuration.
- The example application in
example/Example_6_vizzudemonstrates the use of aconfig.tomlfile to set a custom theme for the Vizzu charts.
Testing
This repository includes a test suite to ensure the functionality of script2stlite.
To run the tests and generate a datetime-stamped log file, use the provided script:
./run_tests.sh
This will execute the test suite using pytest and save a detailed log in the test_logs directory. The log file will be named with the date and time of the test run (e.g., test_logs/test_run_2025-09-02_18-15-00.log).
Contributing
Contributions are welcome! If you have suggestions for improvements, new features, or bug fixes, please feel free to:
- Open an issue to discuss the change.
- Fork the repository and submit a pull request.
Please ensure that your code adheres to standard Python conventions.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file script2stlite-0.2.0.tar.gz.
File metadata
- Download URL: script2stlite-0.2.0.tar.gz
- Upload date:
- Size: 23.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.7.1 CPython/3.10.6 Linux/4.15.0-142-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9e5ac89939a744d72002ab396c8dae0a192e2dc9d6639b9ac97ba10db49aaff
|
|
| MD5 |
dc6517b8b298ed997abc813dce1ea473
|
|
| BLAKE2b-256 |
cf66a57382e685677953b0ae3eae07306d74013cd89a51c6cfb81a74026384a8
|
File details
Details for the file script2stlite-0.2.0-py3-none-any.whl.
File metadata
- Download URL: script2stlite-0.2.0-py3-none-any.whl
- Upload date:
- Size: 18.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.7.1 CPython/3.10.6 Linux/4.15.0-142-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bdac7d15b4cac117bd8e34c11df05e65f9718541f0d4a3860958e0bf39598cc5
|
|
| MD5 |
f1ab63939742ef0237faf65b5e571c49
|
|
| BLAKE2b-256 |
865240b60fcb86b244cfd70564d4122a650e48e4261c41a1d5f5926baf1559fc
|