Recently I needed to set up a very simple proof of concept (POC) to demonstrate to myself and eventually my team that an idea would work. A POC isn't production ready, it doesn't need to be robust and in my case wasn't even going to be written using the same framework we use in production. I just needed to see if the integration would work as I thought it would. If it did, I'd work with my team to build a production ready version. If it didn't work, no problem. I expected this POC to take about two hours of my time, including initial research around the integration itself.
My background is utilizing Python. I've been using it for nearly 15 years now. In my previous role I utilized Sanic to build our API. I've also used Django and Flask in the path, but it had been five or more years so I was rusty in those. Plus, I have a fancy new book written by Adam Hopkins, the core developer of Sanic and an amazing former colleague, called Python Web Development with Sanic that I wanted to work through. I've been meaning to get to this, and haven't had a lot of time with my recent job change. This small POC won't get far, but I've found that if I start following a long tutorial or course or book, I'll dedicate more time so that I can finish it.
By the way, I highly recommend the book if you are utilizing Sanic.
IMPORTANT UPDATE: This post was written and utilized a free Heroku Dyno. On August 25, 2022, it was announced that the free tier would be going away on November 28, 2022. All of this will continue to work, but you won't be able to utilize the free tier to try it out after that date.
The problem I encounted during this POC wasn't the integration, like I expected. Instead, the problem I ran into was figuring out where I could deploy this POC at no cost. I considered ngrok, but that meant leaving something running on my machine until my team had a chance to play with the POC. Instead, I turned to Heroku. The next problem I ran into was determining how to deploy a Sanic application to Heroku. Google returned 5 year old articles, forum posts that don't have answers (denvercoder9, is that you?), and Flask tutorials.
Toy Sanic App¶
Before I get to the solution, here is a toy Sanic app that simply prints
Ok! when you hit the root endpoint. Save this in a file called
from sanic import Sanic from sanic.response import text import os app = Sanic(__name__) @app.get("/") async def root_path(request): return text("Ok!") app.run(host="0.0.0.0", port=os.environ["PORT"], debug=True, access_log=False)
The one important thing to notice is that
port parameter in
app.run(). Heroku supplies the port it is listening on on an environment variable, and this is needed for Sanic.
The quick solution¶
In Adam's book, in the "Organizing a Project" chapter, he shows that running an application uses a command like:
sanic src.server:app -p 7777 --debug --workers=2
Simplifying that command a bit and setting up the Heroku
Procfile (capitization matters and no extension) I have a single line in my
Procfile that reads:
web: sanic server:app
requirements.txt file with Sanic as an item was also required. If you're using a virtualenv, you can simply
pip freeze > requirements.txt to get everything in your environment into the file.
Thus, my directory looks like this:
./poc Procfile requirements.txt server.py
Push this to Heroku and the application fires right up.
I did not have a personal Heroku account or the CLI installed on my machine before starting. That was easily resolved by creating an account at Heroku. For the
heroku-cli, I followed the documentation to get that set up. Namely:
curl https://cli-assets.heroku.com/install.sh | sh
Note: This does require
Once that's done, I verified the installation:
$ heroku --version heroku/7.60.2 linux-x64 node-v14.19.0
Set up the new application in your Heroku account by logging in. Then click
Create new app.
Enter a unique application name.
Then add Python to the build path. Do this by going to
Add buildpack -> Selecting Python and clicking save.
The next step is setting up the two files I mentioned earlier -
requirements.txt. Since the
Procfile is a single line for this simple proof of concept, that can been done in a single line from the shell.
$ echo "web: sanic server:app" > Procfile
Assuming you've been using a virtualenv - because you should be using a virtualenv - the
requirements.txt file is just as easy.
$ pip freeze > requirements.txt
Everything is setup and ready to be loaded to Heroku. Next, login in your terminal. I used the browser based method, but you can do this entirely in the command line if you wish. My command was:
Last, I set up a heroku git remote endpoint so that I could push
heroku git:remote -a NAME_OF_YOUR_HEROKU_APP git add . git commit -m "Deployment commit" git push heroku master
NAME_OF_YOUR_HEROKU_APP to match the name you input in the UI when setting it up.
Wait a minute or so, and then navigate to
NAME_OF_YOUR_HEROKU_APP.herokuapp.com and see
With the steps above, I got a very simple Sanic proof of concept running on Heroku in a matter of minutes. This was very helpful as I was able to easily show my team that the work we're thinking of doing can be accomplished. All told, my proof of concept took two hours of time. The next step will be building a production version.