How to Build and Host Your Python Web App for Free

Hey Finxters!

  • Have you ever felt surrounded by developers boasting from their latest app in prod hosted in the cloud? 
  • Or the need for making yours too but overwhelmed by the technicalities involved?
  • Needed to set up quickly and easily a mini data science demo website without resorting to web developers?
  • Or simply wanting to share your Python work with non-technical people?

Then this article is for you.

💡 Today I will show you one of the simplest ways to set-up your very own Python web app in the cloud, using streamlit to design the app together with Heroku for the hosting part. And it is free.

This article assumes you have at least:

  • basic Python notions
  • basic Git notions
  • a Heroku account (free) (do not forget to configure your email address)
  • the Heroku CLI installed
  • basic notions of Linux commands
  • basic notions of bash scripting

Ready? Here is the plan of our journey:

What is Streamlit?

Streamlit is a data science oriented application framework. 

Its goal is to enable data scientists to release applications without requiring the assistance of a development team

Streamlit allows for example to build an app making predictions using a trained machine learning model, with very few lines of code handling the user interface and controls, and almost no design efforts.

During this tutorial, I will be referring heavily to the Streamlit documentation, and I strongly encourage you to spend some time reading it.

To use it you will first need to do the following in your terminal:

pip install streamlit
streamlit hello  # not strictly mandatory; launches the ‘hello world’ app to test it works

Then in your Python file, the canonical import will be:

import streamlit as st

What is Heroku?

From their own words: “Heroku is a cloud platform that lets companies build, deliver, monitor and scale apps — we’re the fastest way to go from idea to URL, bypassing all those infrastructure headaches.”

That’s right, at the end of this article, we will get an actual URL for our Python project!

Because we will be using a free account, the URL will look like: our_project_name.herokuapp.com, but you might want to upgrade in order to have more options.

So in a nutshell, we will be hosting our Python web app designed with Streamlit on their server, in order for other people to access it without having to have our machine running 24/7.

More info on Heroku can be found here.

Building the Project

In order to keep things as simple as possible, I will show you the minimum package needed to successfully run your app, but of course you may encounter additional files in other Streamlit/Heroku repos depending on what is achieved, such as for instance:

.gitignore, README.md, Makefile, MANIFEST.in, setup.py, runtime.txt, credentials.json, token.json, some_machine_learning_trained_model.h5, etc.

I will not comment on these files specifics in this tutorial, as we will focus on building and hosting our Python web app.

Start by creating a folder where you will put all the necessary files:

mkdir my_project_folder && cd my_project_folder

If you already have a Python project coded, say on Github: then git clone it.

Here is the list of files that we will need in our folder before pushing to Heroku, I will go over each of them:

  • main.py 
  • requirements.txt
  • Procfile
  • setup.sh

And that’s all! Let’s dive in the files specifics:

main.py

This is the Python file (you may need several depending on your project).

This is where your Python code lies and also where the web app structure comes in, thanks to streamlit. Remember you imported streamlit as st at the top of this file?

You can now design many elements thanks to this, for example:

as well as many, many more features, developed by an active community.

One more tip: to tailor things such as your app’s favicon, title etc., look into st.set_page_config and place it at the top of your Python script, just below the imports. 

You should have a look at the documentation to get a grasp of the possibilities there.

Finally, if you fancy looking at sample websites, visit the Streamlit gallery!

Please note that every time the user will interact with your app, the code will be rerun from top to bottom. This may result in unresponsiveness at times.

requirements.txt

This is the text file that specifies which (not built-in) modules will be needed for your web app to run on Heroku.

The minimum it should contain is therefore streamlit.

It basically just lists the (not built-in) modules imported in your Python file(s) for this project.

Beware the 3 following items:

  • version constraints must be stated (ex: scikit-learn>=0.21.3 or requests==2.*
  • as well as the exact module name (the name may differ between what is pip installed and what is imported)
  • as we are using a free Heroku plan, the slug size is limited to 500mB thus preventing heavy modules, such as Tensorflow

touch requirements.txt then add manually the modules, or use a script that does it for you, or echo “modules” > requirements.txt

if you setup a virtual env for your app, they can be obtained through a pip freeze

Procfile

That’s right, this file has no extension. It is a process file specific to Heroku that details which commands should be executed by the app on startup. In our case a web process. More details here

For now, you can simply echo > the following snippet in your Procfile:

web: sh setup.sh && streamlit run <your_python_file>.py

Of course, you should adapt it with your own Python file’s name (main.py in this tutorial).

setup.sh

Custom script launched by the Procfile command. Indicates to Streamlit the app owner’s email and Heroku’s dynamically assigned port on which to run.

Like before, for now you can just copy this piece of code:

mkdir -p ~/.streamlit/

echo "\
[general]\n\
email = \"${HEROKU_EMAIL_ADDRESS}\"\n\
" > ~/.streamlit/credentials.toml

echo "\
[server]\n\
headless = true\n\
enableCORS = false\n\
port = $PORT\n\
" > ~/.streamlit/config.toml

And that’s it! Now that you have the full structure in mind, let’s see an example.

Perhaps you’ve read my article about sending email from a Gmail account with Python?

Well, I actually made a Streamlit/Heroku web app with it, and here is the resulting directory:

Testing the App Locally

To check that your Python file works and make modifications to it quickly, use the following command to run it locally:

streamlit run <your_python_file>.py

Either your browser will open and show your app, or two URLs will appear, allowing you to view your app. Click on Network URL.

Here is what I’d get in my browser in my example email project:

If you want to have a closer look, find my repo here.

Pushing the Project

Last but not least, we now need to make our web app available to the world, as for now it only runs locally.

How to proceed?

Like so:

# if not already done, log in to Heroku
heroku login

# create the app in your region and pick an available APP_NAME
heroku create APP_NAME --region eu

An example for say, a Finxter web app, would go:

# you should see the origin remote for GitHub if you cloned a repo
# and the heroku remote for Heroku
git remote -v

Example from my terminal:

# manually add the heroku remote if necessary
git remote add heroku https://git.heroku.com/APP_NAME.git

# if not already done
git add . # or specify files if you don’t want to push everything
git commit -m “<your commit comment>”

# deploy the app 
git push heroku master  # this could take up to a few minutes and you will witness the build. Change the branch name if needed (eg “main” instead of “master”)

If you read the logs above, you should now be able to understand the deployment process.

# start the web dyno (this is not strictly necessary in most cases)
heroku ps:scale web=1

# open a browser to your deployed web app!
heroku open

Now, you may experience issues at deployment stage.

Hence a useful command to know is:

# check the logs for errors
heroku logs --tail  
# will help you troubleshoot, by showing the build logs (you can also view them on your Heroku app profile on Heroku’s website)

The Heroku GUI in your profile will look like this:

Last, a few remarks:

  • this requires a bit of practice before deploying with ease but is definitely worth it!
  • with a free plan, expect your app to sleep after some time of inactivity. I found a possible remedy to this here
  • whenever your app is awakened, it may take up to 30 seconds to load, that is perfectly normal
  • with a free, unverified Heroku account, you can have up to 5 apps running at the same time
  • the free plan allocates some number of dyno hours per month after which your app will sleep
  • despite all these limitations, you can still very much present data science results or any Python work really and get a reliable app!

I hope you enjoyed our journey into the Python web app deployment universe and that you will create amazing apps!

Oh wait! I said I deployed my email sender project, fancy seeing it?

Here it is: https://email-sender-finxter.herokuapp.com/

You can add several recipients as well as add attachments.

With great power comes great responsibility: use it responsibly.

Where to Go From Here

  • make your own Python web app!
  • tune it
  • maybe onboard a trained machine learning model on it?
  • share it to the world!
  • filter email content with NLP

I hope you will benefit from my experience on this topic, see you next time guys! 🙂