
Fastapi Expert
Scaffold async SQLAlchemy engines, sessions, and ORM models the way FastAPI solo builders ship production APIs.
Install
npx skills add https://github.com/jeffallan/claude-skills --skill fastapi-expertWhat is this skill?
- create_async_engine + async_sessionmaker with pool_pre_ping and expire_on_commit=False
- SQLAlchemy 2.0 DeclarativeBase models using Mapped and mapped_column typing
- Relationship patterns with back_populates and lazy="selectin" for async-friendly loads
- User/Post-style FK and unique indexed email/username conventions ready to extend
Adoption & trust: 3.5k installs on skills.sh; 9.7k GitHub stars; 3/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
Recommended Skills
Entra App Registrationmicrosoft/azure-skills
Azure Aigatewaymicrosoft/azure-skills
Lark Openapi Explorerlarksuite/cli
Supabasesupabase/agent-skills
Firebase Auth Basicsfirebase/agent-skills
Firebase Data Connectfirebase/agent-skills
Journey fit
Primary fit
Backend API construction is the canonical Build-phase shelf for persistence and route-layer foundations. Models, async sessions, and relationship loading are core backend work before you wire FastAPI routers and dependency injection.
Common Questions / FAQ
Is Fastapi Expert safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Fastapi Expert
# Async SQLAlchemy ## Engine & Session Setup ```python from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker from sqlalchemy.orm import DeclarativeBase engine = create_async_engine( settings.DATABASE_URL, echo=settings.DEBUG, pool_pre_ping=True, ) async_session = async_sessionmaker( engine, class_=AsyncSession, expire_on_commit=False, ) class Base(DeclarativeBase): pass ``` ## Model Definition ```python from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy import String, ForeignKey, DateTime, func from datetime import datetime class User(Base): __tablename__ = "users" id: Mapped[int] = mapped_column(primary_key=True) email: Mapped[str] = mapped_column(String(255), unique=True, index=True) username: Mapped[str] = mapped_column(String(50), unique=True) hashed_password: Mapped[str] = mapped_column(String(255)) is_active: Mapped[bool] = mapped_column(default=True) created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) # Relationships posts: Mapped[list["Post"]] = relationship(back_populates="author", lazy="selectin") class Post(Base): __tablename__ = "posts" id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(200)) content: Mapped[str] author_id: Mapped[int] = mapped_column(ForeignKey("users.id")) author: Mapped["User"] = relationship(back_populates="posts") ``` ## Database Dependency ```python from typing import AsyncGenerator from fastapi import Depends async def get_db() -> AsyncGenerator[AsyncSession, None]: async with async_session() as session: try: yield session await session.commit() except Exception: await session.rollback() raise # Type alias for injection DB = Annotated[AsyncSession, Depends(get_db)] ``` ## CRUD Operations ```python from sqlalchemy import select, update, delete from sqlalchemy.orm import selectinload async def get_user(db: AsyncSession, user_id: int) -> User | None: result = await db.execute(select(User).where(User.id == user_id)) return result.scalar_one_or_none() async def get_user_with_posts(db: AsyncSession, user_id: int) -> User | None: result = await db.execute( select(User) .options(selectinload(User.posts)) .where(User.id == user_id) ) return result.scalar_one_or_none() async def get_users(db: AsyncSession, skip: int = 0, limit: int = 100) -> list[User]: result = await db.execute(select(User).offset(skip).limit(limit)) return list(result.scalars().all()) async def create_user(db: AsyncSession, user_in: UserCreate) -> User: user = User(**user_in.model_dump()) db.add(user) await db.flush() await db.refresh(user) return user async def update_user(db: AsyncSession, user_id: int, user_in: UserUpdate) -> User: await db.execute( update(User) .where(User.id == user_id) .values(**user_in.model_dump(exclude_unset=True)) ) return await get_user(db, user_id) async def delete_user(db: AsyncSession, user_id: int) -> bool: result = await db.execute(delete(User).where(User.id == user_id)) return result.rowcount > 0 ``` ## Lifespan Handler ```python from contextlib import asynccontextmanager from fastapi import FastAPI @asynccontextmanager async def lifespan(app: FastAPI): # Startup async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) yield # Shutdown await engine.dispose() app = FastAPI(lifespan=lifespan) ``` ## Quick Reference | Operation | Method | |-----------|--------| | Select one | `result.scalar_one_or_none()` | | Select many | `result.scalars().all()` | | Eager load | `.options(selectinload(...))` | | Create | `db.add(obj)` + `await db.flush()` | | Update | `update(Model).where(...).values(...)` | | Delete | `delete(Model).whe