Tour the FastAPI Starter
The Hazel Home API is small enough to read without a guided expedition: one Python file with two routes. Its location matters as much as its contents because Vercel uses api/index.py as the Python entrypoint.
Outcome
Get the FastAPI starter running locally and confirm the /api/items endpoint is returning data.
Hands-on exercise 1.2
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/, the Python api/ folder and Next.js app/ folder sit beside each other at the project 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 at http://localhost:8000/docs. We can use them to inspect responses without reaching for 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 itemsThe module exposes the FastAPI instance as app, the name Vercel expects at a supported FastAPI entrypoint. Renaming that variable prevents Vercel from finding the application.
The file path controls routing. Vercel packages Python files in api/ as functions, and api/index.py receives requests under /api/*. The FastAPI route declarations include that prefix so they match the full incoming path.
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.141.1",
]Vercel reads this file to install Python dependencies at build time. The requires-python field declares the versions that the project supports. The Python runtime currently supports Python 3.12, 3.13, and 3.14, with 3.12 as the default when the project does not request a supported version.
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},
...
]Commit
This lesson only inspects the starter, so there are no changes to commit.
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?