FastAPI Complete Beginner Tutorial: Build and Run Your First App
Introduction
FastAPI is a modern, high‑performance framework for building APIs with Python 3.8+. In this hands‑on tutorial, you'll set up a FastAPI project from scratch and learn the core concepts by building a small API. Keep this guide as a command cheat sheet you can reuse for new projects.
Prerequisites
You'll need Python 3.8+ and pip. Optional: Git, Docker. Run commands from your terminal (PowerShell, bash, or zsh).
1) Create Project and Virtual Environment
On Windows (PowerShell):
- `mkdir fastapi-app && cd fastapi-app`
- `py -m venv .venv`
- `.venv\Scripts\Activate.ps1`
On macOS/Linux:
- `mkdir fastapi-app && cd fastapi-app`
- `python3 -m venv .venv`
- `source .venv/bin/activate`
2) Install Dependencies
Install FastAPI and an ASGI server (Uvicorn):
- `pip install fastapi uvicorn`
- (Optional dev extras) `pip install python-dotenv pydantic[email]`
3) Your First App (Hello World)
Create `main.py` with a simple route:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello FastAPI!"}
Run the server:
- `uvicorn main:app --reload`
Open docs: `http://127.0.0.1:8000/docs` (Swagger UI) or `http://127.0.0.1:8000/redoc`.
4) Path and Query Parameters
Add dynamic routes:
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "query": q}
5) Request Bodies with Pydantic
Define models and validate input automatically:
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(min_length=1)
price: float = Field(gt=0)
in_stock: bool = True
Use it in a POST endpoint:
@app.post("/items")
def create_item(item: Item):
return {"created": item}
6) Basic CRUD with SQLAlchemy + SQLite
Install deps: `pip install sqlalchemy aiosqlite` (or `pip install sqlalchemy sqlite3` for sync). Minimal sync example:
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import declarative_base, sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./app.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
class Product(Base):
__tablename__ = "products"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
Base.metadata.create_all(bind=engine)
Wire sessions via dependencies:
from fastapi import Depends
from sqlalchemy.orm import Session
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/products")
def create_product(name: str, db: Session = Depends(get_db)):
p = Product(name=name)
db.add(p)
db.commit()
db.refresh(p)
return p
7) Settings via .env (optional)
`pip install python-dotenv` then create a `.env` file:
```.env
APP_NAME=fastapi-app
DATABASE_URL=sqlite:///./app.db
Load with:
python
from dotenv import load_dotenv
import os
load_dotenv()
DATABASE_URL = os.getenv("DATABASE_URL")
```
8) Auth Basics (JWT)
Install: `pip install python-jose[cryptography] passlib[bcrypt]`
Core steps:
- Hash passwords with `passlib`
- Issue JWTs with `python-jose`
- Protect routes using dependencies that verify the token For production, store secrets in env vars and use HTTPS.
9) Testing with pytest
Install: `pip install pytest httpx`
Example test using `TestClient`:
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_root():
r = client.get("/")
assert r.status_code == 200
assert r.json()["message"] == "Hello FastAPI!"
10) Dockerize (optional)
Create `Dockerfile`:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Build and run:
- `pip freeze > requirements.txt`
- `docker build -t fastapi-app .`
- `docker run -p 8000:8000 fastapi-app`
11) Deployment Tips
Use a process manager (e.g., `gunicorn` with `uvicorn.workers.UvicornWorker`), put an Nginx/ALB in front, enable HTTPS, configure health checks, and set proper timeouts. For serverless, look at FastAPI + API Gateway or Cloud Run.
Common Commands Cheat Sheet
- Create venv (Win): `py -m venv .venv && .venv\\Scripts\\Activate.ps1`
- Create venv (Unix): `python3 -m venv .venv && source .venv/bin/activate`
- Install: `pip install fastapi uvicorn`
- Run dev: `uvicorn main:app --reload`
- Run prod: `uvicorn main:app --host 0.0.0.0 --port 8000`
- Freeze: `pip freeze > requirements.txt`
- Test: `pytest -q`
- Docker build: `docker build -t fastapi-app .`
- Docker run: `docker run -p 8000:8000 fastapi-app`
Conclusion
You built a FastAPI app, learned routes, validation, simple CRUD, testing, and containerization. From here, extract settings to config, add robust auth, switch to Postgres + Alembic migrations, and set up CI/CD.