Skip to content

How to use Fastapi Expert in Claude Code for Backend Development

Purpose

This post demonstrates how to use the Fastapi Expert skill in Claude Code to build better FastAPI applications.

Environment

  • Claude Code with claude-skills plugin
  • Python 3.8+
  • FastAPI framework
  • Backend development context

What is Fastapi Expert?

The Fastapi Expert is a specialized skill in the claude-skills ecosystem that provides idiomatic FastAPI patterns and best practices. When I’m building backend APIs with FastAPI, this skill helps me avoid common mistakes and follow established conventions.

There are four main benefits:

  • Idiomatic patterns: Uses FastAPI’s features the right way
  • Security first: Built-in security considerations for authentication and input validation
  • Performance optimization: Database query optimization and async patterns
  • Testing guidance: Proper test structure for FastAPI applications

I should use this skill when I’m working on:

  • Creating new FastAPI applications
  • Adding API endpoints with Pydantic models
  • Implementing authentication and authorization
  • Writing database operations with SQLAlchemy
  • Setting up dependency injection
  • Writing tests for FastAPI apps

Installation and Setup

First, I need to install the claude-skills plugin. The Fastapi Expert skill comes bundled with it.

Terminal window
# Install claude-skills
npm install -g @jeffallan/claude-skills
# Verify installation
claude-skills --version

Then I activate it in my Claude Code session by simply using the skill name when I start working on FastAPI projects.

Core Usage Patterns

The Fastapi Expert skill activates automatically when I mention FastAPI-related tasks. Here are common ways I trigger it:

Direct invocation:

Use fastapi-expert to create a user registration endpoint

Context-based activation:

I'm building a FastAPI app with JWT authentication

Specific problem statements:

How do I implement dependency injection in FastAPI for database sessions?

Practical Examples

Example 1: Creating a CRUD Endpoint

When I need to create a CRUD endpoint, I use fastapi-expert to ensure I follow the right pattern.

app/routers/users.py
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List
from app.database import get_db
from app.schemas.user import UserCreate, UserResponse
from app.models.user import User
router = APIRouter()
@router.post("/", response_model=UserResponse)
def create_user(
user: UserCreate,
db: Session = Depends(get_db)
):
"""Create a new user."""
# Check if user exists
existing = db.query(User).filter(User.email == user.email).first()
if existing:
raise HTTPException(
status_code=400,
detail="Email already registered"
)
# Create new user
db_user = User(**user.dict())
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user

The skill guided me to:

  • Use dependency injection for database sessions
  • Return proper HTTP status codes
  • Validate input with Pydantic models
  • Handle duplicate email checks

Example 2: Authentication with JWT

For authentication, fastapi-expert showed me the secure pattern:

app/core/security.py
from datetime import datetime, timedelta
from jose import JWTError, jwt
from passlib.context import CryptContext
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

Then in my endpoint:

app/routers/auth.py
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from sqlalchemy.orm import Session
from app.core.security import verify_password, create_access_token
from app.database import get_db
from app.models.user import User
router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/login")
@router.post("/login")
def login(email: str, password: str, db: Session = Depends(get_db)):
user = db.query(User).filter(User.email == email).first()
if not user or not verify_password(password, user.hashed_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect email or password"
)
access_token = create_access_token(data={"sub": user.email})
return {"access_token": access_token, "token_type": "bearer"}

Example 3: Database Query Optimization

Fastapi-expert helped me optimize my database queries to avoid the N+1 problem:

# Before: N+1 query problem
@router.get("/posts", response_model=List[PostResponse])
def get_posts(db: Session = Depends(get_db)):
posts = db.query(Post).all()
# This would trigger N+1 queries when accessing comments
return posts
# After: Optimized with eager loading
from sqlalchemy.orm import joinedload
@router.get("/posts", response_model=List[PostResponse])
def get_posts(db: Session = Depends(get_db)):
posts = db.query(Post).options(
joinedload(Post.comments),
joinedload(Post.author)
).all()
return posts

Best Practices

DO ✓

1. Use Pydantic for validation

  • All input should be validated through Pydantic models
  • Separate request schemas from response schemas
  • Use Pydantic’s built-in validators for complex rules

2. Implement proper dependency injection

  • Database sessions should be dependencies
  • Authentication checks should be dependencies
  • Reuse dependencies across endpoints

3. Return appropriate HTTP status codes

  • 200 for successful GET
  • 201 for successful POST
  • 400 for client errors
  • 401 for authentication failures
  • 404 for missing resources
  • 422 for validation errors

4. Write tests for endpoints

tests/test_users.py
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_create_user():
response = client.post(
"/users/",
json={"email": "[email protected]", "password": "testpass"}
)
assert response.status_code == 201
assert response.json()["email"] == "[email protected]"

DON’T ✗

1. Don’t use global database sessions

# WRONG: Global session
db = SessionLocal()
@router.get("/users")
def get_users():
return db.query(User).all()
# CORRECT: Dependency injection
@router.get("/users")
def get_users(db: Session = Depends(get_db)):
return db.query(User).all()

2. Don’t skip error handling

# WRONG: No error handling
@router.get("/users/{user_id}")
def get_user(user_id: int, db: Session = Depends(get_db)):
return db.query(User).get(user_id)
# CORRECT: Handle missing resources
@router.get("/users/{user_id}")
def get_user(user_id: int, db: Session = Depends(get_db)):
user = db.query(User).get(user_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user

3. Don’t hardcode configurations

  • Use environment variables for sensitive data
  • Use pydantic-settings for configuration management
  • Never commit API keys or secrets

Complementary skills that work well with fastapi-expert:

  • backend-patterns: General backend architecture patterns
  • security-review: Security analysis for authentication flows
  • postgresql-patterns: Database optimization for Postgres

Official resources:

Summary

In this post, I showed how to use the Fastapi Expert skill in Claude Code to build better FastAPI applications. The key point is knowing when to invoke the skill and following the idiomatic patterns it provides for authentication, database operations, and endpoint design. By using this skill, I can avoid common mistakes and write more secure, performant FastAPI code.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments