Ship It as a Shareable Streamlit App
A terminal script is great for you. To hand the app to a colleague who does not live in a terminal, it needs a real interface: a page where they upload a file, click a button, and read the analysis. Streamlit turns your Python functions into exactly that, with almost no extra code. In this lesson you wrap the loop in a clean web app and run it locally.
Streamlit runs as its own local server, so it does not run in the in-page playground. You will run it on your machine. The code is short, and you already wrote the hard parts.
What You'll Learn
- What Streamlit is and why it fits a data app perfectly
- Build a page with a file uploader, a button, and results
- Reuse your existing functions with zero rewrites
- Show progress and handle errors in the interface
- Run the app locally and what sharing it involves
What Streamlit is
Streamlit is a Python library for building small web apps without HTML, CSS, or JavaScript. You write normal Python top to bottom, and each Streamlit function call adds a widget to the page: a title, a file uploader, a button, a table, some text. When the user interacts, Streamlit reruns your script from the top and redraws the page. That rerun model is the one thing that feels unusual at first, and we will work with it, not against it.
Install it:
pip install streamlit
The smallest possible app
Create streamlit_app.py:
import streamlit as st
st.title("AI Data Explainer")
st.write("Upload a CSV and let an AI model explain it.")
Run it from your terminal:
streamlit run streamlit_app.py
Your browser opens to a local page with a title and a line of text. That is a running web app. Now we add the real parts.
Add the uploader and a preview
st.file_uploader gives you a file picker. When the user picks a CSV, you read it with pandas exactly as before and show a preview with st.dataframe.
import streamlit as st
import pandas as pd
st.title("AI Data Explainer")
uploaded = st.file_uploader("Upload a CSV", type="csv")
if uploaded is not None:
df = pd.read_csv(uploaded) # the uploader hands pandas a file-like object
st.success(f"Loaded {len(df)} rows and {df.shape[1]} columns.")
st.dataframe(df.head())
One nice detail: st.file_uploader returns something pd.read_csv can read directly, so there is no temporary file to manage.
Reuse your functions, do not rewrite them
This is where the earlier structure pays off. Put your existing functions (summarize_dataframe, build_prompt, and the ask_ai wrapper) in a separate file, say engine.py, then import them. The web layer stays thin and the logic stays in one place.
# streamlit_app.py
import streamlit as st
import pandas as pd
from engine import summarize_dataframe, analyze_with_ai # your functions, unchanged
st.title("AI Data Explainer")
uploaded = st.file_uploader("Upload a CSV", type="csv")
if uploaded is not None:
df = pd.read_csv(uploaded)
st.success(f"Loaded {len(df)} rows.")
st.dataframe(df.head())
question = st.text_input(
"What do you want to know?",
value="What are the key findings?",
)
if st.button("Analyze with AI"):
with st.spinner("Asking the model..."):
try:
analysis = analyze_with_ai(df, question)
st.subheader("Analysis")
st.write(analysis)
except Exception as e:
st.error(f"The analysis failed: {e}")
Walk through what each Streamlit piece does:
st.text_inputlets the user phrase their own question, with a sensible default.st.buttonreturnsTrueonly on the rerun where it was just clicked, so the analysis runs on demand, not on every keystroke.st.spinnershows a "working..." indicator while the API call is in flight, which matters because that call takes a few seconds.st.errorturns a failure into a calm red message instead of a crash.
Notice you did not rewrite a single line of analysis logic. The web app is just a friendly front door to the functions you already built and tested.
Keep the key safe in the app too
The same rule from earlier applies: the API key stays in the environment, never in the code. For local runs, your .env file plus load_dotenv() inside engine.py is enough. Streamlit also has its own secrets mechanism (a .streamlit/secrets.toml file) if you later deploy to a host. Either way, the secret never goes in the source you share.
A few touches that make it feel finished
Small additions that take one line each and noticeably improve the experience:
st.caption("Your data is sent to an AI provider for analysis.")so users know what happens to their file. Being upfront about this is the honest thing to do.st.download_button("Download analysis", analysis, "analysis.txt")so they can save the result.- A check that the uploaded file is not empty before showing the button, reusing the validation idea from the previous lesson.
Running and sharing
streamlit run streamlit_app.py serves the app at a local address, usually http://localhost:8501. On your own machine, that is instantly usable. To let someone else open it, you have a few options, from simplest to most involved:
- Same network: Streamlit prints a network URL others on your Wi-Fi can open.
- Free hosting: Streamlit Community Cloud can host a public app straight from a GitHub repo. You add your API key as a secret in its dashboard, never in the repo.
- Your own server: for full control, run it on any machine that can serve a port.
For this course, running it locally is the finish line. You have built a real AI data app with a real interface, from a CSV all the way to a written analysis on a web page.
Key Takeaways
- Streamlit turns plain Python into a web app: each call adds a widget, and the script reruns on interaction.
st.file_uploaderhands pandas a readable object, so no temp files are needed.- Keep logic in an
engine.pyand import it; the web layer stays thin and your tested functions are reused unchanged. - Use
st.button,st.spinner, andst.errorfor on-demand runs, progress, and graceful failures. - The API key stays in the environment or Streamlit secrets, never in shared source.

