Skip to content

Development Guide

Project Setup

Prerequisites

  • Python 3.8+
  • PostgreSQL or MySQL
  • Redis (for caching and message queue)
  • pip
  • virtualenv (recommended)

Environment Setup

  1. Create and activate a virtual environment:

    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    

  2. Install dependencies:

    pip install -r requirements.txt
    

  3. Set up environment variables:

    cp .env.example .env
    
    Edit the .env file with your configuration.

Database Setup

PostgreSQL:

createdb fastapi_boilerplate

MySQL:

mysql -u root -p
CREATE DATABASE fastapi_boilerplate;

  1. Configure database in .env:

    # For PostgreSQL
    DB_CONNECTION=postgresql
    DB_HOST=localhost
    DB_PORT=5432
    DB_DATABASE=fastapi_boilerplate
    DB_USERNAME=postgres
    DB_PASSWORD=postgres
    
    # For MySQL
    DB_CONNECTION=mysql+pymysql
    DB_HOST=localhost
    DB_PORT=3306
    DB_DATABASE=fastapi_boilerplate
    DB_USERNAME=root
    DB_PASSWORD=root
    

  2. Run migrations:

    alembic upgrade head
    

Redis Setup

macOS (Homebrew):

brew install redis
brew services start redis

Docker:

docker run -d -p 6379:6379 redis:latest

Linux:

sudo apt-get install redis-server
sudo systemctl start redis

Verify Redis is running:

redis-cli ping
# Should return: PONG

Development Workflow

Running the Development Server

python main.py
The server will be available at http://localhost:8000

Authentication

Register a New User

The registration endpoint automatically logs in the user and returns an authorization token:

curl -X POST http://localhost:8000/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "Test@12345",
    "full_name": "John Doe"
  }'

Response includes: - id: User ID - email: User email - full_name: User full name - is_active: Active status - is_superuser: Superuser status - created_at: Creation timestamp - updated_at: Update timestamp

Note: After registration, use the /api/v1/auth/login endpoint to get an authorization token.

Login

curl -X POST http://localhost:8000/api/v1/auth/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=user@example.com&password=Test@12345"

Response includes: - access_token: JWT token for API authentication - token_type: "bearer" - user: Complete user information

Using Authentication Tokens

⚠️ IMPORTANT: All API endpoints require authentication EXCEPT login and register.

All protected endpoints require the Authorization header:

curl -X GET http://localhost:8000/api/v1/users/me \
  -H "Authorization: Bearer <access_token>"

Protected Endpoints (Require Token): - All /api/v1/users/* endpoints - All /api/v1/files/* endpoints - All /api/v1/broadcasting/* endpoints

Public Endpoints (No Token Required): - POST /api/v1/auth/register - POST /api/v1/auth/login

Without a valid token, you'll receive:

{
  "detail": "Not authenticated"
}

Password Requirements

  • Minimum 8 characters
  • Maximum 512 characters (bcrypt limitation handled automatically)
  • At least one uppercase letter
  • At least one lowercase letter
  • At least one digit

API Documentation

  • Swagger UI: http://localhost:8000/docs
  • ReDoc: http://localhost:8000/redoc

Database Migrations

Creating a new migration

alembic revision --autogenerate -m "description"

Applying migrations

alembic upgrade head

Rolling back migrations

alembic downgrade -1  # Roll back one migration

Redis Caching

The boilerplate includes a Laravel-like caching interface:

from app.core.cache import cache

# Store value
cache().put("key", "value", ttl=3600)

# Get value
value = cache().get("key", default=None)

# Cache-aside pattern (recommended)
user = cache().remember(
    f"user:{user_id}",
    ttl=300,
    callback=lambda: User.get(db, id=user_id)
)

# Invalidate cache
cache().forget("key")

See Redis Usage Guide for more examples.

Background Tasks (Celery)

Start Celery Worker:

# Development (with auto-reload)
celery -A app.core.celery_app worker --loglevel=info --reload

# Production
celery -A app.core.celery_app worker --loglevel=info

Monitor with Flower:

celery -A app.core.celery_app flower
# Access at http://localhost:5555

Create Background Tasks:

from app.core.celery_app import celery_app

@celery_app.task(name="send_email")
def send_email_task(email: str, subject: str):
    # Your task logic here
    pass

# Call the task
send_email_task.delay("user@example.com", "Hello")

Testing

Running tests

pytest

Running tests with coverage

pytest --cov=app

Code Structure

Adding New Features

  1. Create a new model in app/models/
  2. Create corresponding schemas in app/schemas/
  3. Create API controllers in app/api/v1/controllers/
  4. Add the new router to app/api/v1/api.py
  5. Create database migration if needed

Best Practices

  1. Use type hints for all function parameters and return values
  2. Write docstrings for all functions and classes
  3. Follow PEP 8 style guide
  4. Write tests for new features
  5. Use Pydantic models for request/response validation
  6. Keep business logic in models or services
  7. Use dependency injection for database sessions and other dependencies

Error Handling

  • Use FastAPI's built-in HTTPException for error responses
  • Create custom exception classes in app/core/exceptions.py for specific error cases
  • Use Pydantic validation for request data
  • Implement proper error logging
  • Security: Don't expose sensitive information in error messages
  • Use app/core/error_handler.py for secure error handling

Security Best Practices

  1. Secrets Management
  2. Never commit .env files
  3. Generate secure random keys for production
  4. Use environment variables for all secrets
  5. Rotate secrets regularly

  6. Input Validation

  7. Always validate user input
  8. Use Pydantic schemas for request validation
  9. Sanitize file paths and filenames
  10. Validate file types and sizes

  11. Authentication & Authorization

  12. Use strong password requirements
  13. Implement proper JWT token validation
  14. Check user permissions before operations
  15. Use policies and gates for authorization

  16. File Operations

  17. Validate file paths to prevent path traversal
  18. Check file types and sizes
  19. Sanitize filenames
  20. Use app/core/file_security.py utilities

  21. Command Execution

  22. Never execute user input as commands
  23. Use whitelists for allowed commands
  24. Avoid shell=True in subprocess calls
  25. Validate command parameters

  26. Error Handling

  27. Don't expose stack traces in production
  28. Use generic error messages
  29. Log errors securely
  30. Include request IDs for tracking

  31. Rate Limiting

  32. Use Redis for distributed rate limiting
  33. Set appropriate limits per endpoint
  34. Implement stricter limits for auth endpoints

  35. Security Headers

  36. Always include security headers
  37. Configure CSP properly
  38. Use HSTS in production with HTTPS

  39. CORS Configuration

  40. Never use wildcard (*) in production
  41. Specify exact origins
  42. Don't allow credentials with wildcard

  43. Dependencies

    • Regularly update dependencies
    • Scan for known vulnerabilities
    • Use pip-audit or safety to check packages

Security Testing

# Check for known vulnerabilities
pip install safety
safety check

# Or use pip-audit
pip install pip-audit
pip-audit

# Run security linter
pip install bandit
bandit -r app/

See Security Guide for comprehensive security information.

Security

  • Always use HTTPS in production
  • Implement proper authentication and authorization
  • Use environment variables for sensitive data
  • Implement rate limiting for API endpoints
  • Use secure password hashing
  • Implement proper CORS configuration

Deployment

Production Setup

  1. Set up a production database
  2. Configure environment variables for production
  3. Set up a reverse proxy (Nginx/Apache)
  4. Use a process manager (Gunicorn/Uvicorn)
  5. Set up SSL certificates
  6. Configure proper logging

Docker Deployment

  1. Build the Docker image:

    docker build -t fastapi_boilerplate .
    

  2. Run the container:

    docker run -p 8000:8000 fastapi_boilerplate
    

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests
  5. Submit a pull request

Troubleshooting

Common Issues

  1. Database connection errors
  2. Check database credentials in .env
  3. Ensure PostgreSQL/MySQL is running
  4. Verify database exists
  5. For MySQL with MAMP, check DB_UNIX_SOCKET path

  6. Redis connection errors

  7. Ensure Redis is running: redis-cli ping
  8. Check Redis configuration in .env
  9. Verify Redis port (default: 6379)

  10. Celery worker not processing tasks

  11. Ensure Redis is running
  12. Check Celery worker is started
  13. Verify tasks are imported in celery_app.py
  14. Check Celery logs for errors

  15. Migration errors

  16. Check for conflicting migrations
  17. Verify database schema matches models

  18. Authentication issues

  19. Check JWT configuration
  20. Verify token expiration
  21. Check user credentials

Getting Help

  • Check the documentation
  • Search existing issues
  • Create a new issue with detailed information
  • Join the community chat