Using the Python Runtime with Vercel Functions
The Python runtime enables you to write Python code, including using FastAPI, Django, and Flask, with Vercel 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:
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
By default, new projects will use the latest Python version available on Vercel. The current available version is Python 3.12.
You can specify which of the available Python versions to use by specifying it with a pyproject.toml
file. The latest available Python version
satisfying the constraint will be used.
[project]
name = "my-python-api"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []
An example pyproject.toml
generated with
uv init my-python-api
.
You can also use 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
, ensure you set Node.js
20.x
or
22.x
in your project
settings.
Vercel Functions support streaming responses when using the Python runtime. This allows you to render parts of the UI as they become ready, letting users interact with your app before the entire page finishes loading.
You can install dependencies for your Python projects by defining them in a pyproject.toml
with or without a corresponding uv.lock
, requirements.txt
, or a Pipfile
with corresponding Pipfile.lock
.
fastapi==0.117.1
An example requirements.txt
file that defines
FastAPI
as a dependency.
[project]
name = "my-python-api"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"fastapi>=0.117.1",
]
An example pyproject.toml
file that defines
FastAPI
as a dependency.
By default, Python Vercel Functions include all files from your project that are reachable at build time. Unlike the Node.js runtime, there is no automatic tree-shaking to remove dead code or unused dependencies.
You should make sure your pyproject.toml
or requirements.txt
only lists packages necessary for runtime and you should also explicitly exclude files you don't need in your functions to keep bundles small and avoid hitting size limits.
Python functions have a maximum uncompressed bundle size of 250 MB. See the bundle size limits.
To exclude unnecessary files (for example: tests, static assets, and test data), configure excludeFiles
in vercel.json
under the functions
key. The pattern is a glob relative to your project root.
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"functions": {
"api/**/*.py": {
"excludeFiles": "{tests/**,__tests__/**,**/*.test.py,**/test_*.py,fixtures/**,__fixtures__/**,testdata/**,sample-data/**,static/**,assets/**}"
}
}
}
Exclude common development and static folders from all Python functions to stay under the 250 MB bundle limit.
FastAPI is a modern, high-performance, web framework for building APIs with Python. For information on how to use FastAPI with Vercel, review this guide.
For FastAPI or basic usage of the Python runtime, no configuration is required. Usage of the Python runtime with other frameworks, including 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 theBaseHTTPRequestHandler
classapp
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:
├── 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.
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.
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:
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:
sanic==19.6.0
An example requirements.txt
file, listing
sanic
as a dependency.
Was this helpful?