Welcome to Module 4!

You already have a robust interface, you understand how to save state, manage the cache, and design the visual system. But we’re still not ready for production!

In this final module, we’ll focus on security, advanced optimization, and adding spectacular features like Chat interfaces.


Forms: Why group interactions?

Remember the Scripting Flow: every time you move a slider or type a letter, the entire code re-runs. Imagine you have 5 filters (start date, end date, region, salesperson, budget). If you had to query the production database every time you touch ONE of those 5 controls, you’d bring the server down.

The solution: st.form

Forms “freeze” interactions until the user explicitly presses the “Submit” button.

with st.form("filters_form"):
 st.write("Configure your exhaustive search:")

 col1, col2 = st.columns(2)
 city = col1.selectbox("City", ["Quito", "Guayaquil", "Cuenca"])
 budget = col2.slider("Budget", 50000, 300000)

 # This button is the key: it will trigger the reload ONLY ON CLICK
 submitted = st.form_submit_button("Query Database")

if submitted:
 st.success(f"Searching for properties in {city} under ${budget}...")
 # Here you would run your heavy SQL query.

Secrets Management and Secure Configuration

NEVER, under any circumstances, write passwords, JWT tokens, or database keys directly in your source code (.py). If you push that code to GitHub, anyone could hack you!

For this, Streamlit uses the st.secrets secrets manager:

  1. Create a hidden folder called .streamlit at the root of your project.

  2. Inside it, create a file called secrets.toml. Make sure to add .streamlit/secrets.toml to your .gitignore file!

  3. Write your credentials in the file:

    [database]
    user = "admin"
    password = "super_secret_123"
    
    OPENAI_KEY = "sk-abcd123456"

From your Python code, you call these credentials with complete security:

import streamlit as st

api_key = st.secrets["OPENAI_KEY"]
db_user = st.secrets.database.user

If you host your app on Streamlit Community Cloud, you can paste the contents of your secrets.toml file directly into your app’s web settings (in the “Secrets” tab), and your code will work exactly the same without uploading credentials.

We’ve also explored advanced libraries like streamlit-authenticator and backends in FastAPI to build complex Login systems with cookies and roles (RBAC).


Fragments (@st.fragment): Breaking the Golden Rule

The @st.fragment decorator is a recent and powerful addition.

Imagine you have a heavy page with lots of charts, but at the bottom there’s a small “Like” button. If the user clicks that button, Streamlit would re-run everything, including the heavy charts.

If you wrap the button with @st.fragment, Streamlit allows only that portion of code to re-run, skipping the global reload and saving tons of resources.

import streamlit as st

st.write("Very heavy chart up here...")

@st.fragment
def quick_widget():
 liked = st.button("Like")
 if liked:
 st.success("Thanks for your like!")
 # The rest of the application did NOT re-run.

quick_widget()

Building Chat Interfaces (LLM Apps)

Streamlit has become the gold standard for creating Artificial Intelligence demos (ChatGPT, LangChain, LlamaIndex). You have two native widgets for building chat experiences:

  • st.chat_message("user") or st.chat_message("assistant"): Draws a chat bubble with its respective avatar.
  • st.chat_input("Type your question..."): A chat bar anchored at the bottom of the screen that, unlike text_input, was designed specifically for long interactions.

Paired with st.session_state (to remember the history), building a chat is extremely simple:

# Initialize chat history
if "messages" not in st.session_state:
 st.session_state.messages = []

# Display the full history
for msg in st.session_state.messages:
 with st.chat_message(msg["role"]):
 st.write(msg["content"])

# Widget to capture a new user question
question = st.chat_input("Tell me something...")

if question:
 # 1. Save and display the user message
 st.session_state.messages.append({"role": "user", "content": question})
 with st.chat_message("user"):
 st.write(question)

 # 2. Get the bot response (simulated)
 response = f"Interesting... You said '{question}'"
 st.session_state.messages.append({"role": "assistant", "content": response})

 with st.chat_message("assistant"):
 st.write(response)

With this knowledge, you’re one step away from building high-impact projects and integrating them into robust, large-scale web infrastructures!

You’ve completed the Streamlit Course. Time to code your own Dashboard and deploy it to the cloud!