Skip to main content

Self-contained Streamlit scripts

· 2 min read
Cody
Product @ Ascend

Reproducible and easy-to-share Streamlit scripts.

As we discussed in our last post on self-contained DuckDB scripts, self-contained Python scripts are increasingly common via uv (making them fast & convenient) -- we use them extensively at Ascend.

Streamlit, a popular open source Python data app framework, makes this a bit difficult. You must always call streamlit to launch Streamlit apps (or uv run streamlit). I strongly prefer to just ./my_script.py so I don't need to remember anything. You can usually achieve with uv & Python like:

#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["typer"]
# ///

My hack to get this working with Streamlit looks like:

#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["streamlit", "plotly", "pandas", "numpy"]
# ///


try:
from streamlit.runtime.scriptrunner import get_script_run_ctx

if get_script_run_ctx() is None:
raise RuntimeError("Not in streamlit context")
except Exception:
import subprocess
import sys

cmd = ["uv", "run", "streamlit", "run", sys.argv[0]]
try:
sys.exit(subprocess.call(cmd))
except KeyboardInterrupt:
sys.exit(130)

import pandas as pd
import plotly.graph_objects as go
import streamlit as st

st.set_page_config(page_title="My dashboard", layout="wide")
st.title("My dashboard")

# The rest of your Streamlit app

This works by checking if the script is being run in a Streamlit context. If it is not, it re-launches itself using uv run streamlit run. Now if we save this file as dashboard.py and chmod +x dashboard.py, we can simply run ./dashboard.py to launch the Streamlit application.