mirror of
https://github.com/alirezarezvani/ClaudeForge.git
synced 2026-07-03 10:23:15 -04:00
13 KiB
13 KiB
CLAUDE.md
This file provides guidance for Claude Code when working with this Python API project.
Overview
FastAPI-based RESTful API with PostgreSQL database, JWT authentication, and async SQLAlchemy. Small team (6 developers) following TDD practices with 90%+ test coverage requirement.
Project Structure
project-root/
├── app/
│ ├── api/
│ │ ├── v1/
│ │ │ ├── endpoints/ # API endpoints
│ │ │ │ ├── auth.py
│ │ │ │ ├── users.py
│ │ │ │ └── products.py
│ │ │ ├── dependencies.py # Shared dependencies
│ │ │ └── router.py # API router
│ │ └── __init__.py
│ ├── core/
│ │ ├── config.py # App configuration
│ │ ├── security.py # Auth utilities
│ │ └── database.py # DB connection
│ ├── models/
│ │ ├── user.py # SQLAlchemy models
│ │ └── product.py
│ ├── schemas/
│ │ ├── user.py # Pydantic schemas
│ │ └── product.py
│ ├── services/
│ │ ├── auth_service.py # Business logic
│ │ ├── user_service.py
│ │ └── product_service.py
│ ├── utils/
│ │ ├── logging.py # Logging utilities
│ │ └── validators.py
│ ├── middleware/
│ │ ├── logging.py # Logging middleware
│ │ └── rate_limit.py # Rate limiting
│ └── main.py # App entry point
├── tests/
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ ├── conftest.py # Pytest fixtures
│ └── test_main.py
├── alembic/
│ ├── versions/ # Migration files
│ └── env.py # Alembic config
├── .env.example
├── alembic.ini
├── pyproject.toml
├── requirements.txt
├── Dockerfile
└── docker-compose.yml
File Structure
- app/ - Main application package
- api/v1/ - API version 1 endpoints and routing
- endpoints/ - Path operation functions
- dependencies.py - Dependency injection (DB sessions, auth)
- core/ - Core utilities (config, security, database)
- models/ - SQLAlchemy ORM models
- schemas/ - Pydantic models for request/response validation
- services/ - Business logic layer (separate from HTTP)
- utils/ - Helper functions (logging, validation)
- middleware/ - FastAPI middleware components
- api/v1/ - API version 1 endpoints and routing
- tests/ - Test suite with pytest
- alembic/ - Database migrations
Architecture
Layer Pattern: FastAPI → Services → Models → Database
Flow:
HTTP Request → Router → Dependency Injection → Endpoint → Service → Model → Database
↓
Response (Pydantic schema)
Components:
- Endpoints: HTTP layer, request/response handling with Pydantic
- Services: Business logic, reusable across endpoints
- Models: Data access layer with async SQLAlchemy 2.0
- Schemas: Request/response validation with Pydantic
- Dependencies: Shared dependencies (DB session, current user)
Setup & Installation
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Set up environment variables
cp .env.example .env
# Edit .env with:
# - DATABASE_URL (PostgreSQL connection string)
# - SECRET_KEY (for JWT token signing)
# - ENVIRONMENT (development/staging/production)
# Start PostgreSQL (using Docker)
docker-compose up -d postgres
# Run database migrations
alembic upgrade head
# Seed database (if needed)
python -m app.scripts.seed
# Start development server
uvicorn app.main:app --reload
# Server runs at http://localhost:8000
# API docs at http://localhost:8000/docs (Swagger UI)
# Alternative docs at http://localhost:8000/redoc (ReDoc)
Core Principles
- Type Hints First: Use type hints for all function signatures (Python 3.10+)
- Test-Driven Development: Write tests before implementation
- API Design: Follow RESTful conventions and OpenAPI standards
- Error Handling: Comprehensive error handling with proper logging
- Code Quality: Black formatting, Ruff linting, 90%+ test coverage
Tech Stack
- Framework: FastAPI 0.104+
- Database: PostgreSQL 15 with async SQLAlchemy 2.0
- Authentication: JWT with python-jose
- Validation: Pydantic v2
- Testing: Pytest, Pytest-asyncio, HTTPX
- Deployment: Docker, Uvicorn, Gunicorn
- Logging: Structlog (JSON format)
- Code Quality: Black, Ruff, MyPy
Development Workflow
Development Process
- Create feature branch from
main:git checkout -b feature/name - Write tests first (TDD with pytest)
- Implement feature with type hints
- Run formatter, linter, and tests locally
- Create pull request with description
- Code review (minimum 1 approval required)
- Merge to main (auto-deploy to staging)
Code Style
- Use Black for formatting (line length: 100)
- Use Ruff for linting (replaces flake8, isort, etc.)
- Type hints on all functions and methods
- Docstrings for all public functions (Google style)
- Example:
def create_user(db: Session, user_in: UserCreate) -> User: """Create a new user in the database. Args: db: Database session user_in: User creation data Returns: Created user object Raises: ValueError: If email already exists """ # Implementation...
API Design Guidelines
FastAPI Path Operations
- Use FastAPI path operations (
@app.get,@app.post, etc.) - Version APIs:
/api/v1/users,/api/v2/users - Use Pydantic models for request/response validation
- Implement proper HTTP status codes:
200 OK- Successful GET/PUT/PATCH201 Created- Successful POST204 No Content- Successful DELETE400 Bad Request- Validation error401 Unauthorized- Authentication required403 Forbidden- Insufficient permissions404 Not Found- Resource not found422 Unprocessable Entity- Pydantic validation error500 Internal Server Error- Server error
Documentation
- Document with OpenAPI (auto-generated by FastAPI)
- Access Swagger UI at
/docs - Access ReDoc at
/redoc - Add descriptions to path operations:
@router.get("/users/{user_id}", response_model=UserResponse) async def get_user(user_id: int, db: Session = Depends(get_db)): """Retrieve a single user by ID.""" # Implementation...
Database Guidelines
Migrations with Alembic
- Use Alembic for migrations
- Never edit existing migrations - create new ones
- Auto-generate migrations:
alembic revision --autogenerate -m "description" - Review generated migrations before applying
- Test migrations on copy of production data
- Name migrations descriptively:
add_user_email_index
SQLAlchemy 2.0 Async Style
- Use async SQLAlchemy 2.0 style
- Example:
from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession 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()
Query Optimization
- Implement proper indexes for frequently queried columns
- Avoid N+1 queries - use
selectinloadorjoinedload - Use database transactions for multi-step operations
- Paginate large result sets (max 100 items per page)
Error Handling
FastAPI Exception Handlers
- Use FastAPI exception handlers
- Create custom exceptions:
class UserNotFoundException(HTTPException): def __init__(self, user_id: int): super().__init__( status_code=404, detail=f"User {user_id} not found" )
Error Response Format
Return consistent error format:
{
"detail": {
"code": "VALIDATION_ERROR",
"message": "User-friendly message",
"errors": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
}
Logging
- Log errors with structlog (JSON format)
- Include context (request ID, user ID, timestamp)
- Log levels: ERROR, WARNING, INFO, DEBUG
- Never log sensitive data (passwords, tokens)
- Never expose stack traces in production
Testing Requirements
Pytest Best Practices
- Use pytest for all tests
- Use pytest fixtures for test setup
- Mock external dependencies (httpx, boto3, etc.)
- Aim for 90%+ code coverage
- Test both success and error paths
Example Test
import pytest
from httpx import AsyncClient
from app.main import app
@pytest.mark.asyncio
async def test_create_user(client: AsyncClient):
"""Test user creation endpoint."""
response = await client.post(
"/api/v1/users",
json={"email": "test@example.com", "name": "Test User"}
)
assert response.status_code == 201
data = response.json()
assert data["email"] == "test@example.com"
assert "id" in data
@pytest.mark.asyncio
async def test_create_user_duplicate_email(client: AsyncClient):
"""Test user creation with duplicate email."""
# First creation
await client.post("/api/v1/users", json={"email": "test@example.com"})
# Duplicate should fail
response = await client.post("/api/v1/users", json={"email": "test@example.com"})
assert response.status_code == 400
Test Categories
# Run all tests
pytest
# Run specific test categories
pytest tests/unit/ # Unit tests only
pytest tests/integration/ # Integration tests only
pytest -m slow # Slow tests (marked with @pytest.mark.slow)
# Run with coverage
pytest --cov=app --cov-report=html
Security Practices
Input Validation
- Validate all input with Pydantic models
- Use Pydantic validators for complex validation
- Sanitize user input to prevent XSS
Database Security
- Use parameterized queries (SQLAlchemy handles this)
- Prevents SQL injection
- Never concatenate user input into queries
Authentication & Authorization
- Hash passwords with passlib + bcrypt
- Use JWT for stateless authentication
- Implement refresh token rotation
- Use environment variables for secrets
- Example:
from passlib.context import CryptContext pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") hashed_password = pwd_context.hash(plain_password)
Rate Limiting
- Implement rate limiting with slowapi
- Example: 100 requests per 15 minutes per IP
- Protect against brute force attacks
CORS
- Enable CORS properly with CORSMiddleware
- Whitelist allowed origins in production
- Don't use wildcard (
*) in production
Performance Optimization
Async/Await
- Use async/await for all I/O operations
- Use AsyncSession for database operations
- Use httpx.AsyncClient for external HTTP calls
Caching
- Implement caching for frequently accessed data
- Use Redis for caching (with aioredis)
- Cache expensive computations
- Set appropriate TTL (time-to-live)
Database Connection Pooling
- Configure SQLAlchemy connection pool
- Set appropriate pool size and overflow
Common Commands
# Development
uvicorn app.main:app --reload # Start dev server with hot reload
pytest # Run all tests
pytest --cov=app # Run tests with coverage
black . # Format code
ruff check . # Lint code
mypy app/ # Type checking
# Database
alembic upgrade head # Run all pending migrations
alembic downgrade -1 # Rollback last migration
alembic revision --autogenerate -m "description" # Create migration
alembic current # Show current migration
alembic history # Show migration history
# Production
gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker
# Docker
docker-compose up -d # Start all services
docker-compose logs -f app # View application logs
docker-compose down # Stop all services
API Documentation
After starting the server, access API documentation at:
- Swagger UI: http://localhost:8000/docs (interactive)
- ReDoc: http://localhost:8000/redoc (readable)
- OpenAPI JSON: http://localhost:8000/openapi.json (raw schema)
Environment Variables
Required environment variables (see .env.example):
# Application
ENVIRONMENT=development
SECRET_KEY=your-secret-key-here
DEBUG=True
# Database
DATABASE_URL=postgresql+asyncpg://user:password@localhost/dbname
# Authentication
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
# CORS
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173
Project Type: Python API (FastAPI) Team Size: Small (6 developers) Lines: ~225 (Python API template with native format)