Streamlit Fastapi
Why Combine Streamlit + FastAPI?
Feature | Streamlit | FastAPI |
---|---|---|
Role | Frontend | Backend |
Strength | Interactive UI | High-performance API |
Best For | Data visualization, ML dashboards | CRUD operations, authentication, data processing |
This is how your folder structure should be
streamlit-fastapi-app/
│── backend/
│ ├── main.py # FastAPI backend
│── frontend/
│ ├── app.py # Streamlit frontend
│── requirements.txt
Creating the FastAPI backend
we start by installing fastapi:
pip install “fastapi[standard]”
we run the file with this command:
fastapi dev main.py
Note: ensure you are in the streamlit-fastapi-app folder.
#we start by importing FastAPI
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
#Lets create a sample in-memory database
inventory = []
class Inventory(BaseModel):
name: str
price: float
#This "/" denotes the root url.
@app.get("/")
def home():
return {"message": "Welcome to FastAPI!"}

#Here, we get all the inventory
@app.get("/inventory")
def get_inventory():
return {"inventory": inventory}

#Url for adding inventory
@app.post("/inventory")
def add_item(item: Inventory):
inventory.append(item.dict())
return {"message": "Inventory added successfully!", "inventory": inventory}
Connecting Streamlit with FastAPI
for this to work we need to import streamlit and requests
import streamlit as st
import requests
#This is the default url our fastapi uses while running locally.
API_URL = "http://127.0.0.1:8000/"
st.title("Streamlit and FastAPI Demo")
#fetch existing inventory
if st.button("Get Inventory"):
response = requests.get(f"{API_URL}/inventory")
if response.status_code == 200:
st.write(response.json())
else:
st.error("Failed to fetch inventory!")

Adding Inventory
#Add new inventory
st.subheader("Add New Inventory")
name = st.text_input("Name")
price = st.number_input("Price", min_value=0.0, format="%.2f")
if st.button("Add Inventory"):
data = {"name":name, "price":price}
response = requests.post(f"{API_URL}/inventory", json=data)
if response.status_code == 200:
st.success("Inventory added successfully!")
else:
st.error("Failed to add Inventory")

Let’s get the inventory to see if our added inventory fetches.

Secure Access
we can also secure content in the fastapi and fetch it using streamlit.
Int ths example we use a demo JWT token.
Let’s start by creating the backend(fastapi)
#Handling Authentication
#let us add JWT authentication in FastAPI
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
def verify_token(token: str = Depends(oauth2_scheme)):
if token != "mytoken":
raise HTTPException(status_code=401, detail="Invalid token")
return token
#then we create a protected endpoint
@app.get("/secured")
def secured_data(token: str = Depends(verify_token)):
return {"message": "You are authorized!"}
Next, let’s create the front end(Streamlit)
st.subheader("Secured Access")
if st.button("Get access"):
headers = {"Authorization": "Bearer mytoken"}
response = requests.get(f"{API_URL}/secured", headers=headers)
if response.status_code == 200:
st.write(response.json())
else:
st.error("An error occured")

Summary
Use Session State in Streamlit to avoid redundant API calls
Use async/await in FastAPI for high-performance endpoints
Cache API results in Streamlit with st.cache_data
Use CORS middleware in FastAPI for cross-origin requests:
Learn more about Streamlit: Click Here
Watch Videos on Streamlit: