home / skills / physics91 / claude-vibe / fastapi-reviewer

fastapi-reviewer skill

/skills/fastapi-reviewer

This skill reviews FastAPI projects for API design, Pydantic usage, async patterns, and security to improve robustness and reliability.

npx playbooks add skill physics91/claude-vibe --skill fastapi-reviewer

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
6.9 KB
---
name: fastapi-reviewer
description: |
  WHEN: FastAPI project review, Pydantic models, async endpoints, dependency injection
  WHAT: Pydantic validation + Dependency injection + Async patterns + OpenAPI docs + Security
  WHEN NOT: Django → django-reviewer, Flask → flask-reviewer, General Python → python-reviewer
---

# FastAPI Reviewer Skill

## Purpose
Reviews FastAPI projects for API design, Pydantic usage, async patterns, and security.

## When to Use
- FastAPI project code review
- Pydantic model review
- API endpoint design review
- Async/await pattern check
- Dependency injection review

## Project Detection
- `fastapi` in requirements.txt/pyproject.toml
- `from fastapi import` imports
- `main.py` with FastAPI() app
- `routers/` directory structure

## Workflow

### Step 1: Analyze Project
```
**FastAPI**: 0.100+
**Pydantic**: v2
**Database**: SQLAlchemy/Tortoise/Prisma
**Auth**: OAuth2/JWT
**Docs**: OpenAPI auto-generated
```

### Step 2: Select Review Areas
**AskUserQuestion:**
```
"Which areas to review?"
Options:
- Full FastAPI review (recommended)
- Pydantic models and validation
- Dependency injection patterns
- Async/await usage
- Security and authentication
multiSelect: true
```

## Detection Rules

### Pydantic Models
| Check | Recommendation | Severity |
|-------|----------------|----------|
| dict instead of model | Use Pydantic BaseModel | MEDIUM |
| Missing Field validation | Add Field constraints | MEDIUM |
| No Config class | Add model_config | LOW |
| Mutable default in Field | Use default_factory | HIGH |

```python
# BAD: Plain dict response
@app.get("/user")
async def get_user() -> dict:
    return {"name": "John", "age": 30}

# GOOD: Pydantic model
class UserResponse(BaseModel):
    name: str = Field(..., min_length=1, max_length=100)
    age: int = Field(..., ge=0, le=150)

    model_config = ConfigDict(from_attributes=True)

@app.get("/user")
async def get_user() -> UserResponse:
    return UserResponse(name="John", age=30)

# BAD: Mutable default
class Config(BaseModel):
    items: list[str] = []  # Shared across instances!

# GOOD: default_factory
class Config(BaseModel):
    items: list[str] = Field(default_factory=list)
```

### Dependency Injection
| Check | Recommendation | Severity |
|-------|----------------|----------|
| Repeated code in endpoints | Extract to Depends() | MEDIUM |
| Global state access | Use dependency injection | HIGH |
| No cleanup in deps | Use yield for cleanup | MEDIUM |
| Hardcoded dependencies | Use Depends for testability | MEDIUM |

```python
# BAD: Repeated DB session code
@app.get("/users")
async def get_users():
    db = SessionLocal()
    try:
        return db.query(User).all()
    finally:
        db.close()

# GOOD: Dependency injection
async def get_db() -> AsyncGenerator[AsyncSession, None]:
    async with async_session() as session:
        yield session

@app.get("/users")
async def get_users(db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(User))
    return result.scalars().all()
```

### Async Patterns
| Check | Recommendation | Severity |
|-------|----------------|----------|
| sync def for I/O | Use async def | HIGH |
| Blocking call in async | Use run_in_executor | CRITICAL |
| No async DB driver | Use asyncpg/aiosqlite | HIGH |
| sync file I/O | Use aiofiles | MEDIUM |

```python
# BAD: Blocking call in async
@app.get("/data")
async def get_data():
    response = requests.get(url)  # Blocks event loop!
    return response.json()

# GOOD: Async HTTP client
@app.get("/data")
async def get_data():
    async with httpx.AsyncClient() as client:
        response = await client.get(url)
        return response.json()

# BAD: Sync file read
@app.get("/file")
async def read_file():
    with open("data.txt") as f:
        return f.read()

# GOOD: Async file read
@app.get("/file")
async def read_file():
    async with aiofiles.open("data.txt") as f:
        return await f.read()
```

### API Design
| Check | Recommendation | Severity |
|-------|----------------|----------|
| No response_model | Add response_model param | MEDIUM |
| Missing status codes | Add responses param | LOW |
| No tags | Add tags for grouping | LOW |
| Inconsistent naming | Use RESTful conventions | MEDIUM |

```python
# BAD: Minimal endpoint
@app.post("/user")
async def create(data: dict):
    return {"id": 1}

# GOOD: Full specification
@app.post(
    "/users",
    response_model=UserResponse,
    status_code=status.HTTP_201_CREATED,
    responses={
        409: {"model": ErrorResponse, "description": "User exists"},
    },
    tags=["users"],
    summary="Create a new user",
)
async def create_user(
    user: UserCreate,
    db: AsyncSession = Depends(get_db),
) -> UserResponse:
    """Create a new user with the provided details."""
    return await user_service.create(db, user)
```

### Security
| Check | Recommendation | Severity |
|-------|----------------|----------|
| No auth on endpoints | Add Depends(get_current_user) | CRITICAL |
| Secrets in code | Use environment variables | CRITICAL |
| No rate limiting | Add slowapi/fastapi-limiter | HIGH |
| Missing CORS config | Configure CORSMiddleware | HIGH |

```python
# Security setup
from fastapi.security import OAuth2PasswordBearer
from fastapi.middleware.cors import CORSMiddleware

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

async def get_current_user(
    token: str = Depends(oauth2_scheme),
    db: AsyncSession = Depends(get_db),
) -> User:
    user = await verify_token(token, db)
    if not user:
        raise HTTPException(status_code=401, detail="Invalid token")
    return user

# Protected endpoint
@app.get("/me")
async def get_me(user: User = Depends(get_current_user)):
    return user
```

## Response Template
```
## FastAPI Code Review Results

**Project**: [name]
**FastAPI**: 0.109 | **Pydantic**: v2 | **DB**: SQLAlchemy async

### Pydantic Models
| Status | File | Issue |
|--------|------|-------|
| HIGH | schemas.py:15 | Mutable default in Field |

### Dependency Injection
| Status | File | Issue |
|--------|------|-------|
| MEDIUM | routers/users.py | Repeated DB session code |

### Async Patterns
| Status | File | Issue |
|--------|------|-------|
| CRITICAL | services/external.py:34 | Blocking requests.get() call |

### Security
| Status | File | Issue |
|--------|------|-------|
| CRITICAL | main.py | No CORS configuration |

### Recommended Actions
1. [ ] Replace blocking HTTP calls with httpx async
2. [ ] Add CORS middleware configuration
3. [ ] Extract repeated code to dependencies
4. [ ] Add response_model to all endpoints
```

## Best Practices
1. **Pydantic v2**: Use model_config, Field validators
2. **Async Everything**: DB, HTTP, file I/O
3. **Dependencies**: Extract common logic
4. **Security**: OAuth2, CORS, rate limiting
5. **Documentation**: OpenAPI auto-docs with examples

## Integration
- `python-reviewer`: General Python patterns
- `security-scanner`: API security audit
- `api-documenter`: OpenAPI enhancement

Overview

This skill reviews FastAPI projects focusing on API design, Pydantic models, async patterns, dependency injection, OpenAPI docs, and security. It identifies risky patterns, recommends concrete fixes, and produces a prioritized action list for maintainers. Use it to get a targeted, code-level review and remediation plan for FastAPI services.

How this skill works

The reviewer scans project files and dependencies to detect FastAPI usage, Pydantic versions, async database drivers, and common directory layouts. It inspects models, endpoints, dependency functions, I/O usage, and security setup to classify issues by severity and suggest concrete fixes. Output includes categorized findings (Pydantic, DI, async, API design, security) and prioritized remediation steps.

When to use it

  • Performing a code review of a FastAPI project before release or audit
  • Validating Pydantic v2 models and field validation rules
  • Checking async/await usage and non-blocking patterns
  • Reviewing dependency injection and testability of endpoints
  • Auditing API design, OpenAPI docs, and security config

Best practices

  • Declare response_model and explicit status codes for endpoints
  • Use Pydantic BaseModel with model_config and Field validators (avoid plain dicts)
  • Prefer async DB drivers and async HTTP/file I/O; avoid blocking calls in async endpoints
  • Extract shared logic into Depends() and use yield for cleanup/testability
  • Store secrets in environment variables and enable CORS, rate limiting, and OAuth2/JWT where appropriate

Example use cases

  • Find and replace blocking requests.get calls with httpx.AsyncClient in async endpoints
  • Detect mutable defaults in Pydantic models and replace with default_factory
  • Identify repeated DB session creation and extract an async dependency using Depends(get_db)
  • Verify response_model usage and add detailed OpenAPI responses for error cases
  • Scan for missing auth on sensitive endpoints and recommend get_current_user dependency

FAQ

How does the skill detect a FastAPI project?

It looks for fastapi in dependency files, from fastapi imports, a FastAPI() app instance, and common router layouts.

Will it change my code automatically?

No. It produces findings and concrete recommendations you can apply manually or via automated refactors.