Skip to main content

fastapi-crud-engine

Async CRUD engine for FastAPI + SQLAlchemy with built-in filtering, pagination, soft delete, audit logs, cache, rate limiting, import/export, and webhooks.

fastapi-crud-engine helps you ship consistent CRUD APIs faster with less boilerplate and more production-ready defaults.

PyPI version Python versions

Table of Contents

Features

  • Automatic CRUD router:
    • GET /, GET /{pk}, POST /, PUT /{pk}, PATCH /{pk}, DELETE /{pk}
  • Soft delete and restore endpoints
  • Advanced FilterSet support:
    • exact, search, icontains, ordering, range, in, isnull
  • Pagination with consistent response schema
  • Bulk create endpoint (/bulk)
  • CSV/XLSX import and export (/import, /export)
  • Audit trail for create/update/delete/restore
  • Cache backend (in-memory or Redis)
  • Rate limiting (in-memory or Redis)
  • Webhook delivery (http or celery)
  • Lifecycle hooks (before_*, after_*)
  • Field-level permissions by role
  • Built-in exception mapping for FastAPI

Installation

Requirements: Python >=3.11

Recommended: install in a virtual environment

python -m venv .venv
source .venv/bin/activate
python -m pip install -U pip

Install from PyPI

python -m pip install fastapi-crud-engine

Install optional extras

python -m pip install "fastapi-crud-engine[excel,redis,celery]"
  • excel: enables XLSX import/export via openpyxl
  • redis: enables Redis cache and Redis rate limiter
  • celery: enables async webhook delivery through Celery workers

Quickstart

from contextlib import asynccontextmanager
from typing import AsyncGenerator

from fastapi import FastAPI
from pydantic import BaseModel
from sqlalchemy import String
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

from fastapi_crud_engine.core.handlers import register_exception_handlers
from fastapi_crud_engine.core.mixins import SoftDeleteMixin
from fastapi_crud_engine.router import CRUDRouter

engine = create_async_engine("sqlite+aiosqlite:///./app.db")
SessionLocal = async_sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)


class Base(DeclarativeBase):
    pass


class User(SoftDeleteMixin, Base):
    __tablename__ = "users"
    id: Mapped[int] = mapped_column(primary_key=True)
    email: Mapped[str] = mapped_column(String(255), unique=True, index=True)


class UserSchema(BaseModel):
    id: int | None = None
    email: str
    model_config = {"from_attributes": True}


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


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


app = FastAPI(lifespan=lifespan)
register_exception_handlers(app)

app.include_router(
    CRUDRouter(
        model=User,
        schema=UserSchema,
        db=get_db,
        prefix="/users",
        soft_delete=True,
    )
)

Run:

uvicorn main:app --reload

Core Usage

Endpoints generated by CRUDRouter

For prefix="/users":

  • GET /users
  • GET /users/{pk}
  • POST /users
  • PUT /users/{pk}
  • PATCH /users/{pk}
  • DELETE /users/{pk}
  • POST /users/bulk
  • GET /users/export?fmt=csv|xlsx
  • POST /users/import
  • GET /users/deleted (when soft_delete=True)
  • POST /users/{pk}/restore (when soft_delete=True)

Feature-by-Feature Usage

1. Filtering and pagination

from fastapi_crud_engine.core.filters import FilterSet

router = CRUDRouter(
    ...,
    filterset=FilterSet(
        fields=["role", "status"],
        search_fields=["email", "name"],
        ordering_fields=["id", "created_at", "email"],
        range_fields=["created_at"],
        in_fields=["role"],
        nullable_fields=["deleted_at"],
        default_ordering="-id",
    ),
)

Example queries:

GET /users?page=1&size=20
GET /users?role=admin
GET /users?search=john
GET /users?ordering=-created_at,email
GET /users?created_at__gte=2026-01-01&created_at__lte=2026-12-31
GET /users?role__in=admin,editor
GET /users?deleted_at__isnull=true

2. Soft delete and restore

Your model must inherit SoftDeleteMixin.

from fastapi_crud_engine.core.mixins import SoftDeleteMixin

class User(SoftDeleteMixin, Base):
    ...

router = CRUDRouter(..., soft_delete=True)

When enabled:

  • DELETE performs soft delete (deleted_at is set)
  • GET /{prefix}/deleted lists soft-deleted records
  • POST /{prefix}/{pk}/restore restores a record

3. Audit trail

router = CRUDRouter(..., audit_trail=True)

This logs create/update/delete/restore operations to the audit model generated by build_audit_log_model.

4. Cache

from fastapi_crud_engine.features.cache import Cache

cache = Cache(ttl=60, backend="memory")
# or Cache(ttl=60, backend="redis", redis_url="redis://localhost:6379/0")

router = CRUDRouter(
    ...,
    cache=cache,
    cache_endpoints=["list", "get"],
)

Write operations automatically invalidate model cache keys.

5. Rate limiting

from fastapi_crud_engine.features.rate_limiter import RateLimiter

router = CRUDRouter(
    ...,
    rate_limit=RateLimiter(requests=100, window=60),
)

Default key strategy is client IP. If limit is exceeded, API returns 429 with Retry-After.

6. Field-level permissions

from fastapi_crud_engine.core.permissions import FieldPermissions

permissions = FieldPermissions(
    hidden_by_default=["password_hash"],
    read={"admin": "__all__", "user": ["id", "email", "role"]},
    write={"admin": "__all__", "user": ["email"]},
)

router = CRUDRouter(..., field_permissions=permissions)

Role is read from request.state.role (fallback: "user").

7. Lifecycle hooks

from fastapi_crud_engine.router import CRUDHooks

async def before_create(db, payload):
    ...

async def after_create(db, obj):
    ...

router = CRUDRouter(
    ...,
    hooks=CRUDHooks(
        before_create=before_create,
        after_create=after_create,
    ),
)

Available hooks:

  • before_create, after_create
  • before_update, after_update
  • before_delete, after_delete
  • before_restore, after_restore

8. Webhooks

from fastapi_crud_engine.features.webhooks import WebhookConfig, WebhookEndpoint

webhooks = WebhookConfig(
    delivery="http",  # or "celery"
    max_retries=3,
    timeout=10,
    endpoints=[
        WebhookEndpoint(
            url="https://example.com/webhook",
            events=["user.created", "user.updated"],
            secret="super-secret",
            headers={"X-App": "my-service"},
        )
    ],
)

router = CRUDRouter(..., webhooks=webhooks)

Event names look like: modelname.created, modelname.updated, modelname.deleted, modelname.restored.

9. Import and export

  • Export: GET /{prefix}/export?fmt=csv|xlsx
  • Import: POST /{prefix}/import with a CSV/XLSX file

Disable them if you do not need them:

router = CRUDRouter(..., disable=["import", "export"])

10. Bulk create

  • Endpoint: POST /{prefix}/bulk
  • Payload: list of create schema objects

Disable if not needed:

router = CRUDRouter(..., disable=["bulk"])

11. Global exception handling

from fastapi_crud_engine.core.handlers import register_exception_handlers

register_exception_handlers(app)

This handles library exceptions consistently (not found, permission denied, lock conflict, rate limit, bulk errors).

12. Using repository directly

from fastapi_crud_engine.repository import CRUDRepository

repo = CRUDRepository(User, soft_delete=True)

# Inside your service/endpoint:
# obj = await repo.create(db, {"email": "a@b.com"})
# page = await repo.list(db, params=PageParams(page=1, size=20), filter_params=request.query_params)

Configuration

Common router options

  • soft_delete=True
  • audit_trail=True
  • filterset=FilterSet(...)
  • cache=Cache(...)
  • rate_limit=RateLimiter(...)
  • webhooks=WebhookConfig(...)
  • hooks=CRUDHooks(...)
  • field_permissions=FieldPermissions(...)
  • disable=["import", "bulk", "export", "deleted", "restore"]

Environment variables

  • REDIS_URL
    • Used by Cache(backend="auto") and RateLimiter(redis_url=None)
  • CELERY_BROKER_URL
    • Used when WebhookConfig(delivery="celery")

Contributing

  • Read CONTRIBUTING.md
  • Create a branch from main
  • Add tests for any behavior change
  • Open a pull request with clear scope and rationale

License

MIT License. See LICENSE.

Acknowledgements

Metadata

Release files for fastapi-crud-engine 0.1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastapi-crud-engine 0.1.6
File Size Uploaded
fastapi_crud_engine-0.1.6.tar.gz 38.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fastapi-crud-engine 0.1.6
File Interpreter ABI Platform
fastapi_crud_engine-0.1.6-py3-none-any.whl Python 3 none any Details

Total release size: 68.7 kB

Release files / fastapi_crud_engine-0.1.6.tar.gz

Download URL fastapi_crud_engine-0.1.6.tar.gz
Size 38.4 kB
Tags Source
SHA-256 checksum
How to use checksums
44bf37d05ee85a4321c6730fadfed13e6d340a0f48209b4f10bb55c8039652ad
BLAKE2b-256 checksum
How to use checksums
b2e34cde57b9b6dcd928611be9d3bb19eda6b24151c0c1147ce51ae4af23a922
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / fastapi_crud_engine-0.1.6-py3-none-any.whl

Download URL fastapi_crud_engine-0.1.6-py3-none-any.whl
Size 30.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
067c41bd9671cd99a67f582b911e7e1b2c38d98fa01d69e9d4ab1caea2b0f8ac
BLAKE2b-256 checksum
How to use checksums
ca1a77d4063817db9601d3f885c809cbf8ef0540d3c457a7d6022eb29638fa41
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release history Release notifications | RSS feed

This release

0.1.6 This release

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page