Input widgets

Streamlit · Essentials · 12 min

Widgets are how users drive an app, and their return values feed the rest of the script.

Each widget call draws a control and returns its current value:

  • st.button("Run") returns True only during the rerun triggered by the click, then False again.
  • st.checkbox, st.toggle return booleans.
  • st.slider("Age", 0, 100, 25) returns a number, or a tuple for a range with value=(20, 40).
  • st.number_input, st.text_input, st.text_area, st.date_input, st.time_input.
  • st.selectbox, st.radio, st.segmented_control return one option; st.multiselect and st.pills (with selection_mode="multi") return lists.
  • st.file_uploader returns an uploaded file object (or None), readable with pd.read_csv(file).
  • st.download_button lets users download data you generate.

Common parameters: help= adds a tooltip, disabled=, placeholder=, label_visibility="collapsed", format_func= to show nicer labels for options, and key= to give the widget an explicit identity.

Streamlit identifies a widget by its parameters (label, options, ...) or by its key. Two widgets with identical parameters raise a DuplicateWidgetID error; give them different keys. Changing a widget's label or options between reruns can reset it to its default, because Streamlit sees a new widget.

Since st.button is only True for one rerun, things shown "after clicking" disappear on the next interaction. Store the result in session state if it must persist.

Example

import streamlit as st
import pandas as pd

name = st.text_input("Your name", placeholder="Ada")
plan = st.selectbox("Plan", ["free", "pro", "team"], index=1,
                    format_func=str.title, help="Billing plan")
seats = st.slider("Seats", 1, 50, 5, disabled=(plan == "free"))
extras = st.multiselect("Extras", ["SSO", "Audit log", "Support"])
upload = st.file_uploader("Usage CSV", type="csv")

price = {"free": 0, "pro": 12, "team": 20}[plan] * seats + 15 * len(extras)
st.write(f"Hi {name or 'there'}, your monthly price is ${price}")

if upload is not None:
    st.dataframe(pd.read_csv(upload).head())

if st.button("Confirm"):          # True only on the rerun caused by the click
    st.success("Order placed")
st.download_button("Download quote", f"price={price}\n", file_name="quote.txt")

Remember

  • Widgets return their current value on every rerun
  • st.button is True only for the rerun its click caused
  • Widgets are identified by parameters or key; duplicates need distinct keys

Watch out for

  • Putting results inside if st.button(...) and expecting them to stay visible after the next interaction.

Check yourself

  1. You create two `st.text_input('Email')` widgets in the same app. What happens?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.streamlit.io/develop/api-reference/widgets