FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints. Itβs designed to be easy to use while delivering the best developer experience.
In this blog, we'll walk through building a full CRUD (Create, Read, Update, Delete) application using FastAPI with a SQLite database via SQLAlchemy.
π§ What You'll Learn
- Setting up a FastAPI project
- Connecting FastAPI to a SQLite database using SQLAlchemy
- Creating database models
- Writing API routes for CRUD operations
- Using Pydantic models for validation
- Testing the API using Swagger UI
π Project Structure
fastapi-crud/
β
βββ app/
β βββ main.py
β βββ database.py
β βββ models.py
β βββ schemas.py
β βββ crud.py
β
βββ requirements.txt
βββ README.md
βοΈ Step 1: Setup and Installation
Create a folder and install FastAPI and dependencies:
mkdir fastapi-crud
cd fastapi-crud
python -m venv env
source env/bin/activate
pip install fastapi uvicorn sqlalchemy pydantic
Create a requirements.txt:
fastapi
uvicorn
sqlalchemy
pydantic
π οΈ Step 2: Database Configuration β database.py
# app/database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
π§± Step 3: Models β models.py
# app/models.py
from sqlalchemy import Column, Integer, String
from .database import Base
class Item(Base):
__tablename__ = "items"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
description = Column(String, index=True)
π¦ Step 4: Schemas β schemas.py
# app/schemas.py
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: str
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
class Config:
orm_mode = True
βοΈ Step 5: CRUD Logic β crud.py
# app/crud.py
from sqlalchemy.orm import Session
from . import models, schemas
def get_item(db: Session, item_id: int):
return db.query(models.Item).filter(models.Item.id == item_id).first()
def get_items(db: Session, skip: int = 0, limit: int = 10):
return db.query(models.Item).offset(skip).limit(limit).all()
def create_item(db: Session, item: schemas.ItemCreate):
db_item = models.Item(title=item.title, description=item.description)
db.add(db_item)
db.commit()
db.refresh(db_item)
return db_item
def delete_item(db: Session, item_id: int):
item = db.query(models.Item).filter(models.Item.id == item_id).first()
if item:
db.delete(item)
db.commit()
return item
def update_item(db: Session, item_id: int, item_data: schemas.ItemCreate):
item = db.query(models.Item).filter(models.Item.id == item_id).first()
if item:
item.title = item_data.title
item.description = item_data.description
db.commit()
db.refresh(item)
return item
π Step 6: FastAPI Main App β main.py
# app/main.py
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from . import models, schemas, crud
from .database import SessionLocal, engine, Base
Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/items/", response_model=schemas.Item)
def create_item(item: schemas.ItemCreate, db: Session = Depends(get_db)):
return crud.create_item(db=db, item=item)
@app.get("/items/", response_model=list[schemas.Item])
def read_items(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
return crud.get_items(db, skip=skip, limit=limit)
@app.get("/items/{item_id}", response_model=schemas.Item)
def read_item(item_id: int, db: Session = Depends(get_db)):
db_item = crud.get_item(db, item_id=item_id)
if db_item is None:
raise HTTPException(status_code=404, detail="Item not found")
return db_item
@app.put("/items/{item_id}", response_model=schemas.Item)
def update_item(item_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)):
updated = crud.update_item(db, item_id, item)
if updated is None:
raise HTTPException(status_code=404, detail="Item not found")
return updated
@app.delete("/items/{item_id}", response_model=schemas.Item)
def delete_item(item_id: int, db: Session = Depends(get_db)):
deleted = crud.delete_item(db, item_id)
if deleted is None:
raise HTTPException(status_code=404, detail="Item not found")
return deleted
π§ͺ Step 7: Run and Test
Run the app:
uvicorn app.main:app --reload
Navigate to:
π Swagger UI: http://127.0.0.1:8000/docs
π§Ύ Redoc UI: http://127.0.0.1:8000/redoc
π§Ό Optional Enhancements
- Add authentication (JWT)
- Migrate to PostgreSQL/MySQL
- Integrate Alembic for migrations
- Use
FastAPI Usersfor user management
π Conclusion
FastAPI makes it incredibly easy to build powerful APIs with Python. This CRUD app demonstrated how to set up models, schemas, database interaction, and API routes.
Want to go further? Add frontend integration with React or Vue, deploy with Docker, or move to production with Gunicorn + Uvicorn!
Top comments (0)