loading...
Cover image for How to deploy a Python/Flask App to Vercel

How to deploy a Python/Flask App to Vercel

andrewbaisden profile image Andrew Baisden Updated on ・4 min read

This is just a quick simple example of course more complex applications will work as well.

Prerequisites

Step 1

Create an account with Vercel if you don't already have one.

Vercel is a cloud platform for static sites and Serverless Functions that fits perfectly with your workflow. It enables developers to host Jamstack websites and web services that deploy instantly, scale automatically, and requires no supervision, all with no configuration.

Step 2

Use npm to install Vercel globally on your computer https://www.npmjs.com/package/vercel

npm i -g vercel

Step 3

Make sure that you have the latest version of Python3 installed and the Flask framework with pip3

https://pypi.org/project/Flask/

pip install Flask

Setup the project

Create a project

If you are having problems getting the virtual environment to work then read this documentation https://docs.python.org/3/library/venv.html

mkdir vercel-python-app
cd vercel-python-app
python3 -m venv venv
. venv/bin/activate
cd venv
touch index.py

Open the project in your code editor and then create a Python/Flask server in the index.py file

from flask import Flask


app = Flask(__name__)


@app.route('/')
def home():
    return 'Home Page Route'


@app.route('/about')
def about():
    return 'About Page Route'


@app.route('/portfolio')
def portfolio():
    return 'Portfolio Page Route'


@app.route('/contact')
def contact():
    return 'Contact Page Route'


@app.route('/api')
def api():
    with open('data.json', mode='r') as my_file:
        text = my_file.read()
        return text

Setup the development environment by running these commands in your terminal.

export FLASK_APP=index.py   
export FLASK_ENV=development

If you are using Windows then see here for the environment variable syntax https://flask.palletsprojects.com/en/1.1.x/quickstart/#a-minimal-application

Now create a data.json file and put it in the root folder for venv and add the .json below into it

[
    {
        "id": 1,
        "first_name": "Rene",
        "last_name": "Clemmett",
        "email": "rclemmett0@linkedin.com",
        "gender": "Male",
        "ip_address": "42.86.99.75"
    },
    {
        "id": 2,
        "first_name": "Rustie",
        "last_name": "Chrishop",
        "email": "rchrishop1@bloomberg.com",
        "gender": "Male",
        "ip_address": "197.128.10.252"
    },
    {
        "id": 3,
        "first_name": "Joe",
        "last_name": "Cocklie",
        "email": "jcocklie2@ustream.tv",
        "gender": "Male",
        "ip_address": "124.81.44.28"
    },
    {
        "id": 4,
        "first_name": "Diane",
        "last_name": "Catt",
        "email": "dcatt3@sogou.com",
        "gender": "Female",
        "ip_address": "169.47.61.184"
    },
    {
        "id": 5,
        "first_name": "Quinton",
        "last_name": "Shellsheere",
        "email": "qshellsheere4@icq.com",
        "gender": "Male",
        "ip_address": "2.57.97.184"
    },
    {
        "id": 6,
        "first_name": "Lena",
        "last_name": "Paull",
        "email": "lpaull5@tmall.com",
        "gender": "Female",
        "ip_address": "121.4.165.63"
    },
    {
        "id": 7,
        "first_name": "Corena",
        "last_name": "Lamswood",
        "email": "clamswood6@hud.gov",
        "gender": "Female",
        "ip_address": "78.65.53.3"
    },
    {
        "id": 8,
        "first_name": "Justinian",
        "last_name": "Nequest",
        "email": "jnequest7@virginia.edu",
        "gender": "Male",
        "ip_address": "62.24.98.224"
    },
    {
        "id": 9,
        "first_name": "Vladimir",
        "last_name": "Boeter",
        "email": "vboeter8@addthis.com",
        "gender": "Male",
        "ip_address": "87.119.34.255"
    },
    {
        "id": 10,
        "first_name": "Jillene",
        "last_name": "Eades",
        "email": "jeades9@amazon.de",
        "gender": "Female",
        "ip_address": "159.173.99.31"
    }
]

Run the command below to see your Python/Flask app working locally in the browser

flask run

Deploying to Vercel

Make sure that you are in the root folder for your project so inside of the venv folder and then run the command vercel in your terminal.

Use the project setup settings below as a guide to setup your own project with Vercel.

? Set up and deploy “~/Desktop/username/vercel-python-app/venv”? [Y/n] y
? Which scope do you want to deploy to? username
? Link to existing project? [y/N] n
? What’s your project’s name? venv
? In which directory is your code located? ./
> Upload [====================] 98% 0.0sNo framework detected. Default Project Settings:
- Build Command: `npm run vercel-build` or `npm run build`
- Output Directory: `public` if it exists, or `.`
- Development Command: None
? Want to override the settings? [y/N] n

Once that is complete it is going to give you some links. The app is NOT going to work yet it is only going to give you a browser file download of your index.py file. You need to create a vercel.json file and put it in the root folder so that Vercel knows that it is a Python application. And it is very important that your index.py file remains in the root folder along with your other server side code for the project otherwise your app won't work.

Create a vercel.json file and put it in the root of your project folder and then add the code below

{
    "version": 2,
    "builds": [
        {
            "src": "./index.py",
            "use": "@vercel/python"
        }
    ],
    "routes": [
        {
            "src": "/(.*)",
            "dest": "/"
        }
    ]
}

Next manually create a requirements.txt file and put it in the root folder with the code below

flask==1.0.2

When creating a more complex application that has multiple packages installed it is best to use the command below for automatically creating a requirements.txt file. This is the equivalent to a package.json file which you should be familiar with if you have worked with Node. You will need to have your dependancies install on the server for it to work. However for this simple example it is not required as the only package that we are using is flask.

pip3 freeze > requirements.txt

Now run the command vercel --prod to deploy your app. Open the Production link and your app should be working online with full working routes.

Posted on by:

andrewbaisden profile

Andrew Baisden

@andrewbaisden

Full Stack Developer, Gamer, Anime Addict ٩(●ᴗ●)۶

Discussion

pic
Editor guide
 

Hi. It didn't work for me . It's says bad gateway. Here is the link : pyvercel.vercel.app/

 

Hey I just followed the tutorial I wrote it worked for me. What is your operating system I am using macOS. It should work fine for macOS and Windows however Linux might have some issues because it is not covered in the documentation.

 

I am using a terminal emulator Termux which emulates Linux pretty well. I don't know if that's the problem. I'll retry

I'm also interested in this demo. Big thank you Andrew for writing it up!

I too was able to get your demo running locally but when I deployed it to Vercel - I also the got the bad gateway error! It deployed successfully and I can see in my builds logs that it looks good.

In the past, I have been able to deploy a Flask app to Vercel though so I'm troubleshooting too to see if I can see what has changed.

I'm on a Mac and share same environment as Andrew. I'll try to find what's going on and report back.

Just a follow up.... in my case, I forgot to include the requirements.txt file.

Once I added the requirements, I was able to deploy the app:

venv.headwinds1.vercel.app/

I don't know what's happening really. I rebuilt the app three times and nothing. I'll retry one more time ;/

rebuilt eh?

Can you run the app locally in your browser?

Yeah. It works correctly locally

Thanks. I'll check it

Yeah that requirements.txt file is essential without it the routing is broken. As for the problems Josias is having its likely because its Linux and because you are using Termux on Android I think. I don't have any experience with that setup my guess is its something to do with the paths similar to the issues that max had.

github.com/headwinds/venv

clone git@github.com:headwinds/venv.git
cd venv/venv
vercel

Well Andrew you are probably right. Even when I cloned your repo it didn't work for as well. That's probably something with Termux. I am giving up on using only termux and I'll try another way . Thanks guys

Hey. I gave myself a last try but this time I took away the virtual env. This means that the problem came from he fact that the virtual env replicated my architecture (aarch64) which is not compatible with vercel. I redeployed only with the main server, requirements.txt and the vercel.json config. Here is the basic server running and the
repo

Well done you worked hard to find a solution congrats!

Thanks. I am happy it works now

amazing - very happy to hear and also great that you shared your solution for others!

 

Hello, thank you for this tutorial.

Locally, if I do an export FLASK_APP=index.py I get a 127.0.0.1 - - [18/Sep/2020 08:24:15] "GET / HTTP/1.1" 500 terminal message and a flask.cli.NoAppException: Could not import "index". browser message.

Works correctly for routes with an export FLASK_APP=/absolute/path/to/index.py, but again I get a FileNotFoundError: [Errno 2] No such file or directory: './data.json'. If I use an absolute path also for the data.json file, it works (locally, but, obviously, breaks the api route when deployed).

flask --version
Python 3.7.7
Flask 1.1.2
Werkzeug 1.0.1

Your version works perfectly when deployed to Vercel.

Any idea about those local paths?

P.S.: Vercel build log reports Warning: Due tobuildsexisting in your configuration file, the Build and Development Settings defined in your Project Settings will not apply. Is that right?

 

Hi what operating system and code editor are you using? Check out the official docs here they might help flask.palletsprojects.com/en/1.1.x...

So about the build logs I just did a test. If you remove this code below from the vercel.json file then that log goes away however the routing will not work so it is needed. It's probably just a note and not a serious warning. And you can use the command vercel --prod for production deployments that will get rid of the production log note too I updated the guide to reflect this.

    "builds": [
        {
            "src": "./index.py",
            "use": "@vercel/python"
        }
    ],
 

Thank for the reply.

I use nvim on Solus.

I did not find anything really useful in the documentation about this case, probably because it is the first time I meet Flask :)

As a temporary solution I got this:

import os

with open(
            os.path.join(
            os.path.dirname(
            os.path.abspath(__file__)),
            'data.json')) as file:

I guess is not an optimal solution, but things like this are the only way that I found so far to make it work (don't mind the indentation). Quickly tested and works on Vercel too.

It seems related to how open behaves in Flask (perhaps the version I do have?). I am really curious about what can be the cause.

Ah ok that explains it. So Solus is a version of Linux? The Flask documentation only mentions Mac and Windows in the documentation as far as I can see. However you seem to have figured out how to get it working. I am sure you will figure it out as you have experience working with Solus which I have never used before.

Yes, it is a Linux flavor. Thank you again for the tutorial :)

 

I know there are devs at Vercel who are very passionate about Python but - from an outsider's perspective - it appears that they are focussing on marketing & promoting more Node-related hosting like NextJS or Gatsby over other languages - there used to be more tutorials for Go and Python but they all seem to be javascript today:

vercel.com/docs

But where is the Python Flask quick start?! Well...right here.

 

Javascript seems to have far more popularity because there are so many frameworks available and it is one of the core technologies of the web. I'm not sure there is even an official tag for Flask on here I know there is one for Django.

I think a lot of people prefer to use Python for scripting, scraping and machine learning as opposed to web development first and foremost.