Loading repository data…
Loading repository data…
benavlabs / repository
FastCRUD is a Python package for FastAPI, offering robust async CRUD operations and flexible endpoint creation utilities.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
⚠️ Warning: If you are using a non-native column type (such as those from
sqlalchemy-utils) in your models, you may encounter aNotImplementedError. In such cases, you need to add apython_typeattribute to your column type. For more details and a discussion on this issue, see this pull request.
To install, just run:
pip install fastcrud
Or, if using UV:
uv add fastcrud
FastCRUD ships with a bundled Library Skill at fastcrud/.agents/skills/fastcrud/SKILL.md, following the Agent Skills standard.
To make it available to your coding agent, run library-skills from your project directory after fastcrud is installed:
# In any project that has fastcrud installed
uvx library-skills # for Codex, Cursor, Copilot, OpenCode, etc.
uvx library-skills --claude # for Claude Code (uses .claude/skills instead)
This symlinks the bundled skill into .agents/skills/ (or .claude/skills/ for Claude Code). Re-run after upgrading FastCRUD to pick up skill changes.
The skill teaches agents:
crud_router)limit=None footgun and the three-tier pagination defaultGROUP BY projections, bulk writes belong to raw SQLAlchemy__gte, __in, __ilike, …), soft delete, joined-table inheritance gotchasReference deep-dives live under fastcrud/.agents/skills/fastcrud/references/ for methods, filters, joins, pagination, and endpoints.
FastCRUD offers two primary ways to use its functionalities:
crud_router for automatic endpoint creation.FastCRUD directly into your FastAPI endpoints for more control.Below are examples demonstrating both approaches:
Here's a quick example to get you started:
models.py
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
pass
class Item(Base):
__tablename__ = 'items'
id = Column(Integer, primary_key=True)
name = Column(String)
description = Column(String)
schemas.py
from pydantic import BaseModel
class ItemCreateSchema(BaseModel):
name: str
description: str
class ItemUpdateSchema(BaseModel):
name: str
description: str
main.py
from typing import AsyncGenerator
from fastapi import FastAPI
from fastcrud import FastCRUD, crud_router
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
from yourapp.models import Base, Item
from yourapp.schemas import ItemCreateSchema, ItemUpdateSchema
# Database setup (Async SQLAlchemy)
DATABASE_URL = "sqlite+aiosqlite:///./test.db"
engine = create_async_engine(DATABASE_URL, echo=True)
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
# Database session dependency
async def get_session() -> AsyncGenerator[AsyncSession, None]:
async with async_session() as session:
yield session
# Create tables before the app start
async def lifespan(app: FastAPI):
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
yield
# FastAPI app
app = FastAPI(lifespan=lifespan)
# CRUD router setup
item_router = crud_router(
session=get_session,
model=Item,
create_schema=ItemCreateSchema,
update_schema=ItemUpdateSchema,
path="/items",
tags=["Items"],
)
app.include_router(item_router)
For more control over your endpoints, you can use FastCRUD directly within your custom FastAPI route functions. Here's an example:
main.py
from typing import AsyncGenerator
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
from fastcrud import FastCRUD
from models import Base, Item
from schemas import ItemCreateSchema, ItemUpdateSchema
# Database setup (Async SQLAlchemy)
DATABASE_URL = "sqlite+aiosqlite:///./test.db"
engine = create_async_engine(DATABASE_URL, echo=True)
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
# Database session dependency
async def get_session() -> AsyncGenerator[AsyncSession, None]:
async with async_session() as session:
yield session
# Create tables before the app start
async def lifespan(app: FastAPI):
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
yield
# FastAPI app
app = FastAPI(lifespan=lifespan)
# Instantiate FastCRUD with your model
item_crud = FastCRUD(Item)
@app.post("/custom/items/")
async def create_item(
item_data: ItemCreateSchema, db: AsyncSession = Depends(get_session)
):
return await item_crud.create(db, item_data)
@app.get("/custom/items/{item_id}")
async def read_item(item_id: int, db: AsyncSession = Depends(get_session)):
item = await item_crud.get(db, id=item_id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
return item
# You can add more routes for update and delete operations in a similar fashion
In this example, we define custom endpoints for creating and reading items using FastCRUD directly, providing more flexibility in how the endpoints are structured and how the responses are handled.
To read more detailed descriptions, go to the documentation.
🧠 DeepWiki Docs: deepwiki.com/benavlabs/FastAPI-boilerplate
Browse our showcase to see projects and tutorials built with FastCRUD:
Built something with FastCRUD? We'd love to feature it! Submit your project through our showcase submission process.
FastAPI Microservices by @kludex.Benav Labs – benav.io github.com/benavlabs
FastCRUD handles the data layer in FastroAI - the complete FastAPI SaaS template: auth, Stripe payments (subscriptions, credits, discounts)