I am trying to deploy a simple FastAPI app to vercel for the first time. Vercel.json is exactly below.
{
"devCommand": "uvicorn main:app --host 0.0.0.0 --port 3000",
"builds": [
{
"src": "api/index.py",
"use": "@vercel/python",
"config": {
"maxLambdaSize": "15mb",
"runtime": "python3.9"
}
}
],
"routes": [
{
"src": "/(.*)",
"dest": "api/index.py"
}
]
}
I have specified runtime as python3.9, but this doesn't reflect actual runtime which is still python3.12 (default).This ends up causing internal error.
How can I configure runtime version correctly?
I also read the official docs which says builds
property shouldn't be used. So I tried to rewrite like below.
{
"devCommand": "uvicorn main:app --host 0.0.0.0 --port 3000",
"functions": {
"api/index.py":
{
"runtime": "[email protected]"
}
},
"routes": [
{
"src": "/(.*)",
"dest": "api/index.py"
}
]
}
This didn't work as well. Maybe I shouldn't use vercel for python project?(little information in the internet)
I've scrolled through vercel docs but wasn't been able find any references that python version could be specified in builds
or functions
section of Vercel.json
.
@vercel/python
. I guess this is more like interface for node.js
to run python3 scripts.Ref: https://vercel.com/docs/projects/project-configuration
Solution:
However as it is listed in Vercel documentation python version could be defined in the Pipfile
.
Ref: https://vercel.com/docs/functions/runtimes/python
Note Vercel only supports python 3.12 (default) and python 3.9 (requires legacy image i.e. use Node.js 16 or 18.)
Vercel Manuals:
This links might be useful for setting up your first python project on vercel:
https://github.com/vercel/examples/tree/main/python/hello-world
https://github.com/vercel/examples/tree/main/python/flask3
https://github.com/vercel/examples/tree/main/python
What worked for me
First create your http handler
or flask app
or else:
## my_app.py
from http.server import BaseHTTPRequestHandler, HTTPServer
import sys
class GETHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type','text/plain')
self.end_headers()
self.wfile.write('Hello, world!\n'.encode('utf-8'))
python_version = f"{sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]}"
self.wfile.write(f'Python version {python_version}'.encode('utf-8'))
# variable required by Vercel
handler = GETHandler
Next create a Pipfile. This bash commands will automatically create a Pipfile.
## run in bash
pip install pipenv
pipenv install
Automatically generated pipfile should look smth like this:
## Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
pipenv = "~=2023.12"
[dev-packages]
[requires]
python_version = "3.9"
Next create package.json
. You need to set node.js version to 18.x for running your scripts in python 3.9.
## package.json
{
"engines": {
"node": "18.x"
}
}
Third, you need to define routes that will trigger executing python server:
## vercel.json
{
"builds": [
{ "src": "*.py", "use": "@vercel/python" }
],
"redirects": [
{ "source": "/", "destination": "/my_app.py" }
]
}
Finally let's set up Deployment Settings. In my project settings I don't add any run or build commands:
However for python 3.9 check that your node.js version is 18.x (same page, i.e. in the Deployment Settings).
That's it. After the deployment visit the generated route link and it will automatically redirect you to /my_app.py
. You can see that python 3.9 was used to generate the page: