I have a simple FastAPI application. It has a lifespan function that defines a custom attribute on the app object (an HTTPX AsyncClient), and a route function that tries to access said attribute.
from fastapi import FastAPI, Request
from contextlib import asynccontextmanager
import uvicorn
import httpx
@asynccontextmanager
async def lifespan(_app: FastAPI):
_app.client = httpx.AsyncClient(base_url="https://example.com")
yield
await _app.client.aclose()
app = FastAPI(lifespan=lifespan)
@app.get("/test")
async def test(request: Request):
return str(request.app.client)
if __name__ == "__main__":
uvicorn.run(app)
When running the app locally, the route function is able to access the attribute without a problem.
When the app is deployed to Vercel however, I get the following error.
AttributeError: 'FastAPI' object has no attribute 'client'
How come the attribute is accessible locally, but not on Vercel?
Project info:
-
Local Python version: 3.12.4 w/ virtual environment
-
Vercel Python version: 3.12 according to Vercel’s docs
-
requirements.txtannotated-types==0.7.0 anyio==4.4.0 certifi==2024.7.4 click==8.1.7 colorama==0.4.6 fastapi==0.112.0 h11==0.14.0 httpcore==1.0.5 httpx==0.27.0 idna==3.7 pydantic==2.8.2 pydantic_core==2.20.1 sniffio==1.3.1 starlette==0.37.2 typing_extensions==4.12.2 uvicorn==0.30.5 -
vercel.json{ "version": 2, "builds": [{ "src": "main.py", "use": "@vercel/python" }], "routes": [{ "src": "/(.*)", "dest": "main.py" }] }
I’ve tried:
-
Modifying FastAPI’s own lifespan example to suit my needs, but the variable would always be a NoneType.
client = None @asynccontextmanager async def lifespan(_app: FastAPI): client = httpx.AsyncClient(base_url="example.com") yield await client.aclose() app = FastAPI(lifespan=lifespan)AttributeError: 'NoneType' object has no attribute 'get' -
Letting FastAPI install its own version of Starlette by removing it from
requirements.txt, as suggested by this issue.
J4TAPI is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
