Tour the FastAPI Starter
The Python side of this project will feel immediately familiar. A single file in an api/ folder, a list of furniture items, two routes. Nothing surprising. But before we connect it to anything, it's worth understanding exactly what's there. The location of this file is what Vercel looks for when it's time to deploy.
Outcome
Get the FastAPI starter running locally and confirm the /api/items endpoint is returning data.
Fast Track
- Clone the starter repo and
cdinto it pip install "fastapi[standard]"fastapi dev api/index.py- Open
http://localhost:8000/api/items
Hands-On
Get the starter
Clone the course starter repo into a folder called starter and step into it:
git clone https://github.com/vercel-labs/academy-python-course.git starter
cd starterInside starter/ you'll see an api/ folder with Python and an app/ folder with Next.js side by side at the root.
Install dependencies
From the project root, install the Python dependencies:
pip install "fastapi[standard]"The [standard] extra includes uvicorn, which FastAPI uses as its development server. If you already have a virtual environment set up, activate it first.
Start the server
fastapi dev api/index.pyYou'll see output like this:
INFO: Will watch for changes in these directories: ['/path/to/starter']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [12345] using WatchFiles
INFO: Started server process [12346]
INFO: Waiting for application startup.
INFO: Application startup complete.
Explore the endpoints
Open http://localhost:8000/api/items in your browser. You'll get the full inventory:
[
{"id": 1, "name": "Fernwood Sectional", "category": "Seating", "price": 2499.0, "in_stock": true},
{"id": 2, "name": "Knotted Oak Coffee Table", "category": "Tables", "price": 849.0, "in_stock": true},
{"id": 3, "name": "Garrison Bookshelf", "category": "Storage", "price": 629.0, "in_stock": false}
]FastAPI also generates interactive API docs automatically. Visit http://localhost:8000/docs to see them. Handy for testing endpoints without curl.
Read the code
Open starter/api/index.py. The whole thing is about 20 lines:
from fastapi import FastAPI
app = FastAPI()
items = [...]
@app.get("/api")
def home():
return {"message": "Hazel Home Furniture API"}
@app.get("/api/items")
def get_items():
return itemsThree things to notice. First, the variable is named app. That's not a style choice. Vercel looks for a top-level variable named exactly app when it deploys a Python project. If it's named anything else, the deploy fails.
Second, the file lives at api/index.py. Vercel treats the api/ folder specially: any Python file there becomes a serverless function at deploy time. index.py is the catch-all that handles requests to /api/*.
Third, every route starts with /api. That's because when a request hits /api/items in production, Vercel routes it to api/index.py, and FastAPI needs to match the full path. Keeping the prefix explicit in the route definitions is the clearest mental model: the URL the browser requests is the URL FastAPI expects.
Check the dependency file
Open starter/pyproject.toml at the project root:
[project]
name = "hazel-home"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.136.0",
]Vercel reads this file to install Python dependencies at build time. The requires-python field sets the Python version. Without it, Vercel uses its default, which may not match your local environment.
Vercel also reads requirements.txt and Pipfile. This course uses
pyproject.toml because it handles Python version pinning and dependency
management in one place.
Try It
With the server running, confirm both endpoints work:
curl http://localhost:8000/api{"message": "Hazel Home Furniture API"}curl http://localhost:8000/api/items[
{"id":1,"name":"Fernwood Sectional","category":"Seating","price":2499.0,"in_stock":true},
...
]Troubleshooting
fastapi: command not found: The [standard] extra installs the fastapi CLI along with uvicorn. If the command isn't found, your virtual environment may not be activated, or the install didn't complete. Run pip install "fastapi[standard]" again inside an active venv.
Port 8000 already in use: Another process is using the port. Run fastapi dev api/index.py --port 8001 to use a different port, or kill the existing process with lsof -ti:8000 | xargs kill.
Done-When
fastapi dev api/index.pystarts without errorshttp://localhost:8000/api/itemsreturns all 8 furniture items- You can identify the
appvariable and theapi/index.pyentrypoint in the code
Solution
# starter/api/index.py
from fastapi import FastAPI
app = FastAPI()
items = [
{"id": 1, "name": "Fernwood Sectional", "category": "Seating", "price": 2499.00, "in_stock": True},
{"id": 2, "name": "Knotted Oak Coffee Table", "category": "Tables", "price": 849.00, "in_stock": True},
{"id": 3, "name": "Garrison Bookshelf", "category": "Storage", "price": 629.00, "in_stock": False},
{"id": 4, "name": "The Long Table", "category": "Tables", "price": 1199.00, "in_stock": True},
{"id": 5, "name": "Pivot Desk Chair", "category": "Seating", "price": 449.00, "in_stock": True},
{"id": 6, "name": "Ember Side Table", "category": "Tables", "price": 299.00, "in_stock": True},
{"id": 7, "name": "Stacked Nightstand", "category": "Storage", "price": 389.00, "in_stock": False},
{"id": 8, "name": "Canvas Floor Lamp", "category": "Lighting", "price": 219.00, "in_stock": True},
]
@app.get("/api")
def home():
return {"message": "Hazel Home Furniture API"}
@app.get("/api/items")
def get_items():
return itemsWas this helpful?