Streamlit#

  • Maybe the most used freeware dashboard in Python.

  • Enormous choice of elements, widgets and extensions.

  • Can use several interactive graphics packages.

  • Can be run as a local app in a browser or in various other environments.

  • Create a .py file and run using the terminal command below in your favourite Python environment.

    • First time local usage prompts for an email address (press Enter if you do not want to supply it).

    • Code can be updated while the app is running.

    • Any action performed in the app triggers a rerun of the code.

streamlit run /path_to_your_streamlit_folder/appname.py
# Teacher's path to be used below in examples:
path_prefix = "/Users/kristian/Documents/GitHub/IND320/streamlit/"

Examples and documentation#

Basic concepts#

  • Streamlit apps rerun all Python code from top to bottom each time

    • a user interacts with any widget (like buttons, sliders, or text inputs), or

    • when the source code changes.

  • The session state is stored in st.session_state

    • Persistent across interactions.

    • Updated before the code is rerun.

  • Caching of data is important to achieve a responsive app.

  • Progress indicators are useful for large operations.

Static vs dynamic content#

  • Static content in Streamlit means fixed outputs—like Markdown, text, or images that do not change unless the code/script changes.

  • Dynamic content is interactive or data-driven—updates based on user input (widgets, forms), external files, or live data sources.

# static_dynamic.py
import streamlit as st

# Static Example
st.markdown("# Static Dashboard\nThis content won't change until the file is reloaded.")

# Dynamic Example
user_input = st.text_input("Type something:")
if user_input:
    st.write(f"You entered: {user_input}")
file_name = "static_dynamic.py"
# !streamlit run {path_prefix}{file_name}

Magic vs explicit content#

  • Magic: Streamlit automatically displays objects, markdown, and charts on their own line, no function needed (“magic”).

  • Explicit: Using Streamlit functions like st.write, st.markdown, st.dataframe to control display.

# magic_explicit.py
# Magic
"**This shows with magic!**"
import pandas as pd
df = pd.DataFrame({'A': [1,2,3]})
df

# Explicit
st.write("**This shows with explicit command!**")
st.dataframe(df)
file_name = "magic_explicit.py"
# !streamlit run {path_prefix}{file_name}

Session sate and on_click / on_event#

  • st.session_state persists variables across reruns, ideal for storing app state and counters.

    • st.session_state is automatically created, and we can extend and manipulate it.

  • on_click/on_change: Assign callback functions to widgets for event-driven updates.

# session_state.py
import streamlit as st

if 'counter' not in st.session_state:
    st.session_state.counter = 0

def increment():
    st.session_state.counter += 1

st.button("Increment", on_click=increment)
st.write(f"Button clicked {st.session_state.counter} times")
file_name = "session_state.py"
# !streamlit run {path_prefix}{file_name}

Reruns and caching#

  • Every interaction reruns the script top-to-bottom; avoid costly computations on every rerun.

  • Use @st.cache_data to store results of expensive operations.

# caching.py
import streamlit as st

@st.cache_data
def get_data():
    import time; time.sleep(2) # Simulate expensive task
    return [1, 2, 3]

st.write("Data:", get_data())

# Interactive part that costs very little compute time
if 'counter' not in st.session_state:
    st.session_state.counter = 0

def increment():
    st.session_state.counter += 1

st.button("Increment", on_click=increment)
st.write(f"Button clicked {st.session_state.counter} times")
file_name = "caching.py"
# !streamlit run {path_prefix}{file_name}

NB! UNDER CONSTRUCTION#

Plans:

  • basic elements

  • interaction

  • layout

  • secrets.toml