Top Rated Plus on Upwork with a 100% Job Success ScoreView on Upwork
retzdev logo
logo
Building a Python API with FastAPI

Deploying to Heroku

by Jarrett Retz

May 20th, 2021

Introduction

For the last post in the series, I'll briefly talk about deploying FastAPI to Heroku. Additionally, I'll talk about adding environment variables into our app that it may depend on.

Getting Started

You'll need an account on Heroku to spin up a server for deployment. Additionally, you'll need a Github account because we are deploying from Github.

Github

Create a new repository on Github and follow the directions to push an existing project to the new repository.

You'll have to commit all the changes before pushing the code upstream.

Heroku

On Heroku, create a new app and give it a unique name.

On the next screen, connect Heroku to your Github account. This allows the app to update after you push new code.

Give Heroku the permissions it needs, then—I recommend—doing automatic deploys. Make sure you're deploying from your main or master branch.

You can run a manual deployment, but your app will fail. We have to add a couple of files and environment variables.

Deployment Configuration

requirements.txt

To generate the file, open up a new terminal and activate your Python environment. Run the command pip freeze > requirements.txt. This collects the project dependencies and the versions used. The first time I did this, I had a couple of packages that gave me trouble a few weeks ago. Unfortunately, I don't remember which ones they were! Therefore, I'll post my requirements.txt.

appdirs==1.4.4
black==20.8b1
certifi==2020.12.5
chardet==4.0.0
click==7.1.2
fastapi==0.63.0
gunicorn==20.0.4
h11==0.12.0
httptools==0.1.1
idna==2.10
joblib==1.0.1
mypy-extensions==0.4.3
numpy==1.19.5
pandas==1.1.5
pathspec==0.8.1
pydantic>=1.8,<2.0.0
python-dateutil==2.8.1
pytz==2021.1
regex==2020.11.13
requests==2.25.1
scikit-learn==0.24.1
scipy==1.5.4
six==1.15.0
sklearn==0.0
starlette==0.13.6
threadpoolctl==2.1.0
toml==0.10.2
typed-ast==1.4.2
typing-extensions==3.7.4.3
urllib3==1.26.4
uvicorn==0.13.4
uvloop==0.15.1

runtime.txt

Next, we need to specify the Heroku runtime and Python version.

Create a new file in the project root named runtime.txt. Inside the file, enter the text:

python-3.9.0a

Procfile

The final file is the famous Heroku Procfile.

Here we define the starting command for our web application. Consequently, we have the opportunity to inject our environment variables into the app.

web: SANITY_API_KEY=$SANITY_API_KEY API_KEY=$API_KEY ENV="production" gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app

This is all one statement, but it's composed of different parts.

The first part is the list of environment variables:

SANITY_API_KEY=$SANITY_API_KEY API_KEY=$API_KEY ENV="production"

The syntax $variable means that this is an environment variable relative to the server. We can define these in the Heroku instance settings.

These values depend on your application.

The second part is for starting our application:

gunicorn -w 4 -k uvicorn.workers.UvicornWorker

I cannot remember if gunicorn and uvicorn were installed in the application, but they may need to be downloaded. If so, generate or add them to the requirements.txt file. The workers part is beyond the scope of this series.

The last part, main:app, is the location of the FastAPI object in the project. For us, this is inside the main.py file. And the object's name is app.

Save the files and push them to your Github repository. This should trigger a build for your Heroku app. Now when you visit the app, you should see your index route and see your docs at /docs.

If you're like me, you need to update your host header security in main.py. I currently am seeing the response Invalid host header.

Conclusion

This article series took longer than I planned! Unfortunately, I wasn't able to get into the topic of API management partly because it took longer and partly because the Azure API Management deployment cost more than I wanted to pay.

Although it wasn't a deep dive into the actual code, I hope what was covered is helpful!

Jarrett Retz

Jarrett Retz is a freelance web application developer and blogger based out of Spokane, WA.

jarrett@retz.dev

Subscribe to get instant updates

Contact

jarrett@retz.dev

Legal

Any code contained in the articles on this site is released under the MIT license. Copyright 2024. Jarrett Retz Tech Services L.L.C. All Rights Reserved.