Using the Python Runtime with Serverless Functions

Learn how to use the Python runtime to compile Python Serverless Functions on Vercel.
Table of Contents

The Python runtime is available in Beta on all plans

The Python runtime enables you to write Python code, including using Django and Flask, with Vercel Serverless Functions. You can use a specific Python version as well as use a requirements.txt file to install dependencies.

You can create your first function, available at the /api route, as follows:

api/index.py
from http.server import BaseHTTPRequestHandler
 
class handler(BaseHTTPRequestHandler):
 
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/plain')
        self.end_headers()
        self.wfile.write('Hello, world!'.encode('utf-8'))
        return
A hello world Python API using Vercel Serverless Functions.

By default, new projects will use the latest Python version available on Vercel.

Current available versions are:

You can specify which of the available Python versions to use by defining python_version in Pipfile:

Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
 
[packages]
flask = "*"
 
[requires]
python_version = "3.12"

An example Pipfile generated with pipenv install flask.

The python_version must exactly match one of the options above or it will be ignored. When upgrading to 3.12 please ensure Node.js 20.x is used in Project Settings.

You can install dependencies for your Python projects by defining them in requirements.txt or a Pipfile with corresponding Pipfile.lock.

requirements.txt
Flask==2.2.2

An example requirements.txt file that defines Flask as a dependency.

For basic usage of the Python runtime, no configuration is required. Advanced usage of the Python runtime, such as with Flask and Django, requires some configuration.

The entry point of this runtime is a glob matching .py source files with one of the following variables defined:

  • handler that inherits from the BaseHTTPRequestHandler class
  • app that exposes a WSGI or ASGI Application

Python uses the current working directory when a relative file is passed to open().

The current working directory is the base of your project, not the api/ directory.

For example, the following directory structure:

directory
├── README.md
├── api
|  ├── user.py
├── data
|  └── file.txt
└── requirements.txt

With the above directory structure, your function in api/user.py can read the contents of data/file.txt in a couple different ways.

You can use the path relative to the project's base directory.

api/user.py
 
from http.server import BaseHTTPRequestHandler
from os.path import join
 
class handler(BaseHTTPRequestHandler):
 
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/plain')
        self.end_headers()
        with open(join('data', 'file.txt'), 'r') as file:
          for line in file:
            self.wfile.write(line.encode())
        return

Or you can use the path relative to the current file's directory.

api/user.py
 
from http.server import BaseHTTPRequestHandler
from os.path import dirname, abspath, join
dir = dirname(abspath(__file__))
 
class handler(BaseHTTPRequestHandler):
 
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/plain')
        self.end_headers()
        with open(join(dir, '..', 'data', 'file.txt'), 'r') as file:
          for line in file:
            self.wfile.write(line.encode())
        return

The Web Server Gateway Interface (WSGI) is a calling convention for web servers to forward requests to web applications written in Python. You can use WSGI with frameworks such as Flask or Django.

The Asynchronous Server Gateway Interface (ASGI) is a calling convention for web servers to forward requests to asynchronous web applications written in Python. You can use ASGI with frameworks such as Sanic.

Instead of defining a handler, define an app variable in your Python file.

For example, define a api/index.py file as follows:

api/index.py
from sanic import Sanic
from sanic.response import json
app = Sanic()
 
 
@app.route('/')
@app.route('/<path:path>')
async def index(request, path=""):
    return json({'hello': path})

An example api/index.py file, using Sanic for a ASGI application.

Inside requirements.txt define:

requirements.txt
sanic==19.6.0

An example requirements.txt file, listing sanic as a dependency.

Last updated on June 17, 2024