Build a Chat App with Memory in Streamlit
What You Will Build
A chat interface that:
- accepts user input
- shows assistant replies
- remembers previous messages
- persists chat history across reruns
Why Chat History is Needed
Streamlit reruns the script every time the user interacts.
Without storing messages:
- chat disappears after each message
- conversation context is lost
👉 Solution → st.session_state
Step 1: Install Streamlit
Bash
pip install streamlit
Step 2: Create App File
Create:
- chat_app.py
Step 3: Full Working Chat App
Python
import streamlit as st
import openai
st.title("Chat App")
# Initialize chat history
if "messages" not in st.session_state:
st.session_state.messages = []
# Display previous messages
for msg in st.session_state.messages:
with st.chat_message(msg["role"]):
st.write(msg["content"])
# Add Clear Chat Button
with st.sidebar:
if st.button("Clear Chat"):
st.session_state.messages = []
st.rerun()
# User input
prompt = st.chat_input("Type your message")
if prompt:
# Save user message
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.write(prompt)
# Bot response
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=st.session_state.messages
)
reply = response.choices[0].message.content
st.session_state.messages.append({"role": "assistant", "content": reply})
with st.chat_message("assistant"):
st.write(reply) Step 4: Run the App
Bash
streamlit run chat_app.py
How This Works Internally
Streamlit Execution Model
Every interaction:
- Script reruns from top
- UI redraws
- Session state preserves data
Why st.session_state is Critical
Without session state:
User sends message → app reruns → message disappears
With session state:
Message stored → script reruns → messages restored
Understanding Each Component
1️⃣ Initialize Session State
if "messages" not in st.session_state:
st.session_state.messages = [] - Creates persistent storage
- Runs only once
2️⃣ Display Stored Messages
for msg in st.session_state.messages:
Each message is stored as:
{"role": "user", "content": "Hello"} Roles
- user → message from user
- assistant → bot reply
3️⃣ st.chat_message()
Creates chat bubble UI.
Available roles:
- "user"
- "assistant"
- "system" (optional)
4️⃣ Chat Input Widget
prompt = st.chat_input("Type your message") - Fixed at bottom
- Triggers rerun on submit
- Returns entered text
5️⃣ Save Messages
st.session_state.messages.append({...}) - Persists conversation
- Builds chat history