This repo is a template for your semester project. It includes most of the infrastructure setup (containers), sample databases, and example UI pages. Explore it fully and ask questions!
- A GitHub Account
- A terminal-based git client or GUI Git client such as GitHub Desktop or the Git plugin for VSCode.
- VSCode with the Python Plugin
- A distribution of Python running on your laptop. The distro supported by the course is Anaconda or Miniconda.
Currently, there are three major components that will each run in their own Docker Containers:
- Streamlit App in the
./appdirectory - Flask REST api in the
./apidirectory - MySQL Database that will be initialized with SQL script files from the
./database-filesdirectory
If you are not familiar with web app development, this code base might be confusing. But don't worry, it's not that bad. Here are some suggestions for learning the code base:
- Have two versions of the template repo - one for you to individually explore and lear and another for the team's project implementation.
- Start by exploring the
./appdirectory. This is where the Streamlit app is located. The Streamlit app is a Python-based web app that is used to interact with the user. It's a great way to build a simple web app without having to learn a lot of web development. - Next, explore the
./apidirectory. This is where the Flask REST API is located. The REST API is used to interact with the database and perform other server-side tasks. - Finally, explore the
./database-filesdirectory. This is where the SQL scripts are located that will be used to initialize the MySQL database.
- In GitHub, click the fork button in the upper right corner of the repo screen.
- When prompted, give the new repo a unique name, perhaps including your last name and the word 'personal'.
- Once the fork has been created, clone YOUR forked version of the repo to your computer.
- Set up the
.envfile in theapifolder based on the.env.templatefile. - For running the testing containers (for your personal repo), you will tell
docker composeto use a different configuration file nameddocker-compose-testing.yaml.docker compose -f docker-compose-testing.yaml up -dto start all the containers in the backgrounddocker compose -f docker-compose-testing.yaml downto shutdown and delete the containersdocker compose -f docker-compose-testing.yaml up db -donly start the database container (replace db with api or app for the other two services as needed)docker compose -f docker-compose-testing.yaml stopto "turn off" the containers but not delete them.
Before you start: As a team, one person needs to assume the role of Team Project Repo Owner.
- The Team Project Repo Owner needs to fork this template repo into their own GitHub account and give the repo a name consistent with your project's name. If you're worried that the repo is public, don't. Every team is doing a different project.
- In the newly forked team repo, the Team Project Repo Owner should go to the Settings tab, choose Collaborators and Teams on the left-side panel. Add each of your team members to the repository with Write access.
Remaining Team Members
- Each of the other team members will receive an invitation to join. Obviously accept the invite.
- Once that process is complete, each team member, including the repo owner, should clone the Team's Repo to their local machines (in a different location your Personal Project Repo).
- Set up the
.envfile in theapifolder based on the.env.templatefile. - For running the testing containers (for your team's repo):
docker compose up -dto start all the containers in the backgrounddocker compose downto shutdown and delete the containersdocker compose up db -donly start the database container (replace db with api or app for the other two services as needed)docker compose stopto "turn off" the containers but not delete them.
Note: You can also use the Docker Desktop GUI to start and stop the containers after the first initial run.
In most applications, when a user logs in, they assume a particular role. For instance, when one logs in to a stock price prediction app, they may be a single investor, a portfolio manager, or a corporate executive (of a publicly traded company). Each of those roles will likely present some similar features as well as some different features when compared to the other roles. So, how do you accomplish this in Streamlit? This is sometimes called Role-based Access Control, or RBAC for short.
The code in this project demonstrates how to implement a simple RBAC system in Streamlit but without actually using user authentication (usernames and passwords). The Streamlit pages from the original template repo are split up among 3 roles - Political Strategist, USAID Worker, and a System Administrator role (this is used for any sort of system tasks such as re-training ML model, etc.). It also demonstrates how to deploy an ML model.
Wrapping your head around this will take a little time and exploration of this code base. Some highlights are below.
- We need to turn off the standard panel of links on the left side of the Streamlit app. This is done through the
app/src/.streamlit/config.tomlfile. So check that out. We are turning it off so we can control directly what links are shown. - Then I created a new python module in
app/src/modules/nav.py. When you look at the file, you will se that there are functions for basically each page of the application. Thest.sidebar.page_link(...)adds a single link to the sidebar. We have a separate function for each page so that we can organize the links/pages by role. - Next, check out the
app/src/Home.pyfile. Notice that there are 3 buttons added to the page and when one is clicked, it redirects viast.switch_page(...)to that Roles Home page inapp/src/pages. But before the redirect, I set a few different variables in the Streamlitsession_stateobject to track role, first name of the user, and that the user is now authenticated. - Notice near the top of
app/src/Home.pyand all other pages, there is a call toSideBarLinks(...)from theapp/src/nav.pymodule. This is the function that will use the role set insession_stateto determine what links to show the user in the sidebar. - The pages are organized by Role. Pages that start with a
0are related to the Political Strategist role. Pages that start with a1are related to the USAID worker role. And, pages that start with a2are related to The System Administrator role.
Note: This project only contains the infrastructure for a hypothetical ML model.
- Build, train, and test your ML model in a Jupyter Notebook.
- Once you're happy with the model's performance, convert your Jupyter Notebook code for the ML model to a pure python script. You can include the
trainingandtestingfunctionality as well as thepredictionfunctionality. You may or may not need to include data cleaning, though. - Check out the
api/backend/ml_modelsmodule. In this folder, I've put a sample (read fake) ML model inmodel01.py. Thepredictfunction will be called by the Flask REST API to perform 'real-time' prediction based on model parameter values that are stored in the database. Important: you would never want to hard code the model parameter weights directly in the prediction function. tl;dr - take some time to look over the code inmodel01.py. - The prediction route for the REST API is in
api/backend/customers/customer_routes.py. Basically, it accepts two URL parameters and passes them to thepredictionfunction in theml_modelsmodule. Thepredictionroute/function packages up the value(s) it receives from the model'spredictfunction and send its back to Streamlit as JSON. - Back in streamlit, check out
app/src/pages/11_Prediction.py. Here, I create two numeric input fields. When the button is pressed, it makes a request to the REST API URL/c/prediction/.../...function and passes the values from the two inputs as URL parameters. It gets back the results from the route and displays them. Nothing fancy here.