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
Building an Event-Driven Architecture in Python Using ReactiveX (RxPy)

ReactiveX (RxPy) enables event-driven architectures in Python, handling asynchronous data streams and complex workflows. It offers powerful tools for managing concurrency, error handling, and composing operations, making it ideal for real-time, scalable systems.

Blog Image
Is FastAPI Your Secret Weapon for Rock-Solid API Security with RBAC?

Exclusive Access: Elevate FastAPI Security with Role-Based Control

Blog Image
Is Your FastAPI App Missing This Essential Trick for Database Management?

Riding the Dependency Injection Wave for Agile Database Management in FastAPI

Blog Image
Python DevOps Mastery: 7 Essential Libraries for Automated Infrastructure

Discover 8 essential Python libraries that streamline DevOps automation. Learn how Ansible, Docker SDK, and Pulumi can help you automate infrastructure, deployments, and testing for more efficient workflows. Start coding smarter today.

Blog Image
Essential Python Security Libraries Every Developer Should Master in 2024

Master Python security with 6 essential libraries for encryption, authentication, and vulnerability protection. Learn cryptography, JWT, bcrypt implementation with code examples.

Blog Image
NestJS with Machine Learning: Integrating TensorFlow for Smart APIs

NestJS and TensorFlow combine to create smart APIs with machine learning capabilities. This powerful duo enables developers to build adaptive backends, integrating AI into web applications for tasks like price prediction and sentiment analysis.