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.
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.
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.
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
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==184.108.40.206 urllib3==1.26.4 uvicorn==0.13.4 uvloop==0.15.1
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:
The final file is the famous Heroku
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"
$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
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
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
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.
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!