Lab 8: Introduction to Web Applications

Part 4: Converting an Existing Flask App to Use Heroku

If you find typos or problems with the lab instructions, please let us know.

Deploying an existing Flask App on Heroku

If you already have a Flask app running from the command line (e.g. python hello.py) and you want to convert it to run on Heroku, you need to do three things. Each is very simple:

  • It needs to be in a git repository.

  • You need a file named Procfilewhich usually includes just one line of code (see below).

  • You need a requirements.txt file. This is generated automatically with one unix command (see below).

  • You use the command heroku create to set up a remote repository on heroku where you can deploy your application.

  • You use git push heroku master to deploy your application.

  • You can see your application on the web, or use heroku logs to see the logs (if there are errors.)

Let’s try this now with the webapp you created with the conversions. Open up the Repl.it project in which you coded lab 8 part 1, 2, and 2.5.

First, to deploy on Heroku, we need to create two extra files. We need a file called Procfile in our git repo. This file tells Heroku what to do with our github repo when we push it to github. It should contain the following:

web: gunicorn hello_name:app --log-file=-

Important: The part of this line that reads hello_name:app assumes that the main python code for your web app is in hello_name.py, and that the variable app is the one that appears in the line of code app = Flask(__name__). Thus, you must change name in hello_name from the above line to your name (it must match the hello_name.py file from part 1 and 2, but without the .py file extension). For future projects, make sure to change hello_name:app as needed.

Now that we have that file, you will want to write these commands to commit this file to our github repo. Either use Repl.it's version control, or do this in the command line:

git add Procfile

git commit -m "Added Procfile needed by Heroku"

git push origin master


We also need a file called requirements.txt which is a list of the Python modules that are needed for our Heroku flask application.

This file will list all of the Python modules that we may have installed using pip install --user blah, including flask, and anything else that flask might have required. pip is a package manager built for python. You might not have directly used it to install flask (or other packages) because Repl.it usually automatically installs them for you whenever you import them.

Note that before you do the next step, you should do the following pip install command if you haven’t already. While this next line isn’t necessarily needed for running Flask applications locally, it is needed for Heroku.

pip install gunicorn

We can create the file requirements.txt with this command (Don't use this command though! We'll explain why below):

pip freeze > requirements.txt

But we won’t do that! Because “pip freeze” outputs the installed packages in the requirements format; however, Repl.it has tons of preinstalled packages that we don't use and don't need in the requirements.txt file! If we were to do this, the list would be very very long; also heroku does not like some of the packages.

Instead, go ahead and create a file called requirements.txt, and then paste this into the file:

Flask==1.1.2

itsdangerous==1.1.0

Jinja2==2.11.2

MarkupSafe==1.1.1

Werkzeug==1.0.1

wheel==0.24.0

gunicorn==20.0.4

We now have a list of packages our program needs to run.

Now let's push that to Github as well, either with Repl.it's version control or:

git add requirements.txt

git commit -m "Added list of Python modules needed by Heroku"

git push origin master

Setting up Heroku CLI and deploying

First, we'll download Heroku CLI and setup our account

Now, we need to setup heroku on Repl.it, just as we did in Part 3:

First, run npm install heroku in the terminal to download the Heroku CLI. Then, once it's downloaded, run alias heroku='node_modules/heroku/bin/run'.

If you want an explanation of running the above code, take a look at Part 3.

Test that you downloaded it correctly by running heroku --version (if you see (node:38) [ENOENT] Error: spawn heroku ENOENT , ignore that error). You should see this output: heroku/7.42.6 linux-x64 node-v10.21.0.

Once you've ensured that the Heroku CLI is downloaded correctly, you should be able to type the command heroku login -i in the terminal and enter your heroku login credentials. Try that now. If you run into issues, ask a mentor for help.


A few file additions (needed for the npm workaround)

Here, we have to do a few special things. First, we need to create a special file called Pipfile (it should be at the same level as your hello_name.py file). Within the Pipfile, add this:

[requires]

python_version = "3.8.3"

We need Pipfile so that Heroku knows we are running a Python application. Since we used npm, the package manager for a different language, Heroku isn't sure if we created a Python app or an app with a different language. With Pipfile, we are specifying that we are using python, version 3.8.3. You won't need this when you're not working on Repl.it.

The second special thing we need to do is add a .gitignore file and copy this into the file:

node_modules/

package-lock.json

This will tell git to ignore the node_modules folder (where we downloaded the Heroku CLI to) and the package-lock.json file, which is used by npm (when using npm, you should normally save the package file to Github, but this is an exception). We want to ignore both the package file, and the node_modules folder because we are only using those to access the Heroku CLI on Repl.it; we don't need to store them on Github or Heroku (and shouldn't store them on Github or Heroku because of their large size).


Finishing Deployment

Now type heroku create in the terminal and notice the name of the application created.

  • It will take the form word-word-number, e.g. flying-tomato-4321

Ok, the next step is to type:

git push heroku master

After doing git push heroku master, you’ll probably see lots of output, showing that your webapp is now running on Heroku.


If there are other errors, check them by typing heroku logs in the terminal.

Try entering your unique URL for you webapp on your phone or your laptop! You should be able to convert temperatures and miles to kilometers from anywhere now!

Before pushing to Github, add a link in a README.txt to the address of the running app on Heroku, and then finally push to Github.

Brief recap on order of commands

We just added another step in our software development. Just as a reminder, this is the order you should follow as you make changes to your programs:

  1. git add filename

  2. git commit -m “Meaningful and informative message”

  3. git push origin master

  4. git push heroku master


A side note about that “itsdangerous” thing

When I first saw that name show up in the modules we were downloading, I was a little taken aback. If you are worried about having something called “itsdangerous” in your account, this paragraph is to reassure you that it's not dangerous.

I read the documentation for the itsdangerous module and realized that that the only thing dangerous about it was its name. The name refers to the fact that sometimes data has to be passed from a “trusted environment” to an “untrusted environment” or vice-versa, and when that happens, you want to “sign” the data—that is, do some cryptography with it—to ensure that it isn’t modified enroute. There isn’t anything “dangerous” about the software itself. On the contrary—not using it would be dangerous.


Extra information to build a better web app

To be able to learn how to better develop your webapps read onto the next lesson, Part 5.

Potential project ideas

  • Create a bot for the web - A way to interact with websites and automate tasks.

  • Webapp - Any website idea that you have (almost endless opportunities) that uses python, html, and css (Minimal Javascript).

  • Web Scraping - Can extract information from webpages using something like BeautifulSoup library in python.

  • Any other idea that you can come up with that interacts with the web and uses python.