Streamlit UI: upload, chat, citations
Wiring up the UI is what turns code into a product anyone can use. Two hours and you have a real app.
You wrote the engine. Now you bolt on the steering wheel, the seat, the dashboard.
UI pieces:
- Sidebar PDF uploader (calls ingest)
- Chat input and history
- Streaming responses
- Source citations expander
import streamlit as st
from rag import index_pdf, answer
st.title("PDF Chatbot")
with st.sidebar:
uploaded = st.file_uploader("Upload PDF", type=["pdf"])
if uploaded:
path = f"data/{uploaded.name}"
with open(path, "wb") as f:
f.write(uploaded.read())
n = index_pdf(path)
st.success(f"Indexed {n} chunks from {uploaded.name}")
if "messages" not in st.session_state:
st.session_state.messages = []
for msg in st.session_state.messages:
with st.chat_message(msg["role"]):
st.markdown(msg["content"])
if prompt := st.chat_input("Ask about your PDFs"):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
placeholder = st.empty()
text = ""
for delta in answer(prompt):
text += delta
placeholder.markdown(text + "_")
placeholder.markdown(text)
st.session_state.messages.append({"role": "assistant", "content": text})
That is the whole app.
Quick recall
3 prompts · think before you flip
Prompt 1 of 3
Why use `st.session_state` here?
Quiz time
1 question · tap an answer to check it
1. The sidebar uploader's main job is to
Finished lesson 9.6?
Mark complete to update your module progress and unlock the streak.
Loading