python

Are You Ready to Master CRUD Operations with FastAPI?

Whip Up Smooth CRUD Endpoints with FastAPI, SQLAlchemy, and Pydantic

Are You Ready to Master CRUD Operations with FastAPI?

Dive Into CRUD With FastAPI, SQLAlchemy, and Pydantic

Creating CRUD (Create, Read, Update, Delete) endpoints is like the bread and butter of building web apps. If you’re using FastAPI along with SQLAlchemy and Pydantic, you’re setting yourself up for a smooth ride. Let’s break down how to whip up a CRUD app with these tools, and don’t worry — we’ll keep things chill and easy to follow.

Getting Your Playground Ready

First things first, you need to make sure you’ve got all the necessary goodies installed. Use pip for that:

pip install fastapi uvicorn sqlalchemy psycopg2-binary

In this example, we’re rolling with SQLite because it’s straightforward, but if you vibe more with PostgreSQL or something else, switch it up however you like.

Building the Database Models

Alright, let’s start by creating our database models using SQLAlchemy. Think of these models as blueprints for your database tables.

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession

Base = declarative_base()

class Item(Base):
    __tablename__ = "items"
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    description = Column(String, index=True)

DATABASE_URL = "sqlite+aiosqlite:///./test.db"
engine = create_async_engine(DATABASE_URL, echo=True)
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

async def lifespan(app: FastAPI):
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)
    yield

Crafting Pydantic Models

Next up, we gotta define some Pydantic models. These schemas help in validating and serializing the data. They should mirror your database models but are used specifically for API interactions.

from pydantic import BaseModel

class ItemBase(BaseModel):
    name: str
    description: str

class ItemCreate(ItemBase):
    pass

class Item(ItemBase):
    id: int

    class Config:
        orm_mode = True

Setting Up FastAPI With Style

Now it’s time to roll up our sleeves and set up FastAPI and define those CRUD endpoints.

from fastapi import FastAPI, Depends
from fastapi.responses import JSONResponse
from fastapi.requests import Request
from fastapi.exceptions import HTTPException

app = FastAPI(lifespan=lifespan)

async def get_session() -> AsyncGenerator[AsyncSession, None]:
    async with async_session() as session:
        yield session

@app.post("/items/", response_model=Item)
async def create_item(item: ItemCreate, session: AsyncSession = Depends(get_session)):
    db_item = Item(name=item.name, description=item.description)
    session.add(db_item)
    await session.commit()
    await session.refresh(db_item)
    return db_item

@app.get("/items/", response_model=list[Item])
async def read_items(session: AsyncSession = Depends(get_session)):
    items = await session.execute(select(Item))
    return items.scalars().all()

@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: int, session: AsyncSession = Depends(get_session)):
    item = await session.get(Item, item_id)
    if not item:
        raise HTTPException(status_code=404, detail="Item not found")
    return item

@app.put("/items/{item_id}", response_model=Item)
async def update_item(item_id: int, item: ItemCreate, session: AsyncSession = Depends(get_session)):
    db_item = await session.get(Item, item_id)
    if not db_item:
        raise HTTPException(status_code=404, detail="Item not found")
    db_item.name = item.name
    db_item.description = item.description
    await session.commit()
    await session.refresh(db_item)
    return db_item

@app.delete("/items/{item_id}")
async def delete_item(item_id: int, session: AsyncSession = Depends(get_session)):
    item = await session.get(Item, item_id)
    if not item:
        raise HTTPException(status_code=404, detail="Item not found")
    await session.delete(item)
    await session.commit()
    return JSONResponse(content={"message": "Item deleted"}, status_code=200)

Let’s Get This Show on the Road

To get everything up and running, just use this command:

uvicorn main:app --reload

Your FastAPI server will come alive, and you can start playing with your CRUD endpoints at http://localhost:8000.

Automated Swagger Documentation

One of the coolest things about FastAPI is the automated documentation it provides through Swagger UI. You can check it out at http://localhost:8000/docs and test your API endpoints right from your browser.

Taking It Up a Notch with FastCRUD

If you’re feeling adventurous and want even more streamlined CRUD operations, try using packages like FastCRUD. It brings features like automatic endpoint creation, dynamic query building, and pagination to the table, simplifying complex CRUD operations.

from fastcrud import FastCRUD, crud_router

item_router = crud_router(
    session=get_session,
    model=Item,
    create_schema=ItemCreate,
    update_schema=ItemUpdateSchema,
    path="/items",
    tags=["Items"],
)

app.include_router(item_router)

With this setup, you get CRUD endpoints for your Item model on autopilot, including support for joins, sorting, and pagination.

Wrapping Up

Building CRUD endpoints with FastAPI, SQLAlchemy, and Pydantic is super effective for managing data in your web apps. By following the steps above, you’ll have a robust and efficient API handling your basic operations — creating, reading, updating, and deleting data. Whether you stick with the basics or dive into advanced tools like FastCRUD, FastAPI’s got your back with a flexible and high-performance framework to meet all your needs. Happy coding!

Keywords: FastAPI, SQLAlchemy, Pydantic, CRUD endpoints, web apps, SQLite, PostgreSQL, automated documentation, FastCRUD, uvicorn



Similar Posts
Blog Image
7 Essential Python Libraries Every Machine Learning Engineer Should Master in 2024

Discover 7 essential Python libraries for machine learning: scikit-learn, TensorFlow, PyTorch, XGBoost, LightGBM, OpenCV, and FastAI. Complete guide with code examples and practical tips to accelerate your ML projects.

Blog Image
Why Is FastAPI the Ultimate Choice for Building Secure Multi-Tenant SaaS Applications?

FastAPI Powers Efficient and Secure Multi-Tenant SaaS Solutions

Blog Image
How Can You Make User Authentication Magical in Flask with OAuth2?

Experience the Magic of OAuth2: Transforming User Authentication in Your Flask App

Blog Image
Turning Python Functions into Async with Zero Code Change: Exploring 'Green Threads'

Green threads enable asynchronous execution of synchronous code without rewriting. They're lightweight, managed by the runtime, and ideal for I/O-bound tasks. Libraries like gevent in Python implement this concept, improving concurrency and scalability.

Blog Image
Unlocking Python's Hidden Power: Mastering the Descriptor Protocol for Cleaner Code

Python's descriptor protocol controls attribute access, enabling custom behavior for getting, setting, and deleting attributes. It powers properties, methods, and allows for reusable, declarative code patterns in object-oriented programming.

Blog Image
The Untold Secrets of Marshmallow’s Preloaders and Postloaders for Data Validation

Marshmallow's preloaders and postloaders enhance data validation in Python. Preloaders prepare data before validation, while postloaders process validated data. These tools streamline complex logic, improving code efficiency and robustness.