Okay, so you have built an amazing model, wrapped it in a well-designed FastAPI app and neatly containerized it as a Docker image. How do you showcase it for your boss / colleague / customer / mom? Sure you get Swagger out of the box with FastAPI but is that enough? Wouldn't it be sexier to show some visualisations? Enter Streamlit.
Streamlit is "the fastest way to build and share data apps" and you should take advantage of this light-weight tool to showcase your work.
This repository is a toy example on how to make a standalone Streamlit app communicate with a standalone FastAPI app.
Spin it all up
docker compose upIn your browser, attend 127.0.0.1:8501 and see the Streamlit app alive. Go to 127.0.0.1:5000/docs to see the Swagger documentation for the FastAPI app.
To bring it all down
docker compose downBesides git related and media stuff, the repository consist of 2 directories and 10 files (2 hidden, 8 visible):
.
├── README.md
├── docker-compose.yaml
├── fastapi
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── app.py
│ └── requirements.txt
└── streamlit
├── .dockerignore
├── Dockerfile
├── app.py
└── requirements.txtThe repository consist of two apps: FastAPI and Streamlit.
The FastAPI app is located in the directory fastapi:
fastapi
├── .dockerignore
├── Dockerfile
├── app.py
└── requirements.txtThe FastAPI app just expose one endpoint GET /random?n=, which provide n random numbers to a scatter plot. It's containerized through Dockerfile and .dockerignore makes sure, that only needed files are considered in the build proces. The needed libraries are listed in requirements.txt.
The Streamlit app is located in the directory streamlit:
streamlit
├── .dockerignore
├── Dockerfile
├── app.py
└── requirements.txtThe Streamlit app is just a basic scatter plot and a slider to choose how many random numbers should be generated. It's containerized through Dockerfile and .dockerignore makes sure, that only needed files are considered in the build proces. The needed libraries are listed in requirements.txt.
The docker-compose.yaml takes care of defining and running the multi-container Docker app:
version: "3"
services:
fastapi:
build: fastapi/
ports:
- 5000:5000
streamlitapp:
build: streamlit/
depends_on:
- fastapi
ports:
- 8501:8501This is the absolute minimum definitions needed to build the multi-container app.
It would be good practice to explicitly state a network name, making the containers able to communicate with each other, but Docker compose automatically create a default network, making another network superfluous.
The service name for the FastAPI app is the host name needed in the requests.get() method in streamlit/app.py:
Any help or feedback are very welcome! 👋🏼
