Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FastAPI Modular Boilerplate

A FastAPI project structured as a Modular Monolith following Clean Architecture and Domain-Driven Design (DDD) principles.

Features

  • Clean Architecture: Separation of concerns with clear layer boundaries
  • Domain-Driven Design: Business logic is at the center of the application
  • Modular Monolith: Each feature is isolated in its own module
  • Multi-Database Support: Easily switch between PostgreSQL and MySQL
  • Type Hints: Full type annotations for better developer experience
  • Dependency Injection: Using FastAPI's built-in dependency injection system
  • Exception Handling: Centralized error handling
  • Repository Pattern: Database access is abstracted away
  • SQLAlchemy ORM: Object-Relational Mapping for database interactions
  • Pydantic Models: Request and response validation
  • Docker Support: Run the application in containers
  • CLI Tools: Command-line tools for database management
  • Enhanced Logging: Structured logging with Loguru

Project Structure

project/
│
├── app/
│   ├── core/                        # Core shared code (cross-cutting concerns)
│   │   ├── database.py               # SQLAlchemy database engine and session
│   │   ├── database_factory.py       # Factory for different database types
│   │   ├── db_utils.py               # Database utility functions
│   │   ├── settings.py               # App settings using Pydantic BaseSettings
│   │   ├── exceptions.py             # Custom exceptions (global error handlers)
│   │   ├── security.py               # For auth/security shared code
│   │   ├── logging.py                # Logging configuration with Loguru
│   │   ├── utils.py                  # General utility functions
│   │   └── base.py                   # SQLAlchemy declarative base
│   │
│   ├── modules/                      # Feature Modules (DDD style)
│   │   ├── items/                    # Example Feature Module
│   │   │   ├── controllers/          # FastAPI routers (presentation layer)
│   │   │   │   └── item_controller.py
│   │   │   ├── services/             # Application/Business logic layer
│   │   │   │   └── item_service.py
│   │   │   ├── repositories/         # Data access layer
│   │   │   │   └── item_repository.py
│   │   │   ├── entities/             # Domain models (SQLAlchemy ORM)
│   │   │   │   └── item_entity.py
│   │   │   ├── dtos/                 # Request/Response Schemas (Pydantic)
│   │   │   │   └── item_dto.py
│   │   │   └── __init__.py
│   │
│   ├── routers.py                    # Automatically discover and include all routers
│   ├── cli.py                        # Command-line interface tools
│   └── main.py                       # FastAPI app instance and startup logic
│
├── data/                            # SQLite database files
├── env_samples/                     # Sample environment files for different databases
├── logs/                            # Application logs
├── migrations/                      # Alembic database migrations
├── static/                          # Static files
├── run.py                           # Script to run the application
├── Dockerfile                       # Docker configuration
├── docker-compose.yml               # Docker Compose configuration
├── requirements.txt                 # Project dependencies
└── README.md                        # Project documentation

Getting Started

Prerequisites

  • Python 3.11+
  • pip (Python package manager)

Installation

  1. Clone the repository
  2. Install dependencies:
pip install -r requirements.txt

Running the Application

Using the run.py script

The simplest way to run the application is using the provided run.py script, which allows you to specify the database driver and other settings:

# Run with PostgreSQL (default)
python run.py

# Run with MySQL
python run.py --db-driver mysql --db-user root --db-password password --db-name app_db

# Run without database support
python run.py --no-db

# Enable auto-reload and debug mode
python run.py --reload --debug

When running with --no-db, the application will:

  • Skip all database initialization
  • Disable database-dependent modules and endpoints
  • Return 503 Service Unavailable for database-dependent endpoints
  • Provide a /api/db-status endpoint to inform about disabled database functionality

This mode is useful for:

  • Running only non-database dependent features
  • Testing the application without a database
  • Developing and testing the API interface without database setup

Using environment files

You can also use the provided environment sample files:

# Copy the desired sample file
cp env_samples/sqlite.env .env

# Run the application
uvicorn app.main:app --reload

Using Docker

# Build and run with Docker Compose
docker-compose up -d

The API will be available at http://localhost:8000

API Documentation

Database Management

Database Configuration

The application now has optional database support, which is disabled by default:

  • Database support is available but disabled by default (DATABASE_ENABLED=False in settings)
  • No tables are created automatically on application startup
  • No migrations are needed or supported
  • Supports PostgreSQL and MySQL databases

To enable database support:

  1. Set DATABASE_ENABLED=True in your .env file or in app/core/settings.py
  2. Make sure you have installed the required database dependencies from requirements.txt
  3. Configure your database connection settings (host, port, user, password, database name)
  4. Manually create tables using the provided utility functions when needed

Manual Table Management

You can create, drop, or reset database tables using the db_utils module:

from app.core.db_utils import create_tables, drop_tables, reset_database

# Create all tables defined in your SQLAlchemy models
create_tables()

# Drop all tables (WARNING: This will delete all your data)
drop_tables()

# Reset database (drop all tables and recreate them)
reset_database()

Switching Databases Programmatically

You can switch between PostgreSQL and MySQL databases programmatically:

from app.core.db_utils import switch_to_postgres, switch_to_mysql

# Switch to PostgreSQL
switch_to_postgres(
    db_name="my_database",
    user="postgres",
    password="postgres",
    host="localhost",
    port="5432"
)

# Switch to MySQL
switch_to_mysql(
    db_name="my_database",
    user="root",
    password="password",
    host="localhost",
    port="3306"
)

Key Concepts

Clean Architecture

The project is structured with concentric layers:

  • Entities: Domain models representing business objects
  • Repositories: Data access abstraction
  • Services: Business logic
  • Controllers: HTTP interface

Modular Structure

Each feature module is self-contained with its own:

  • Controllers (API endpoints)
  • Services (business logic)
  • Repositories (data access)
  • Entities (domain models)
  • DTOs (data transfer objects)

This allows for:

  • Independent development
  • Clear boundaries
  • Easy reasoning about the codebase
  • Better separation of concerns

Dependency Injection

FastAPI's dependency injection system is used extensively:

  • Database sessions
  • Services
  • Repositories
  • Security utilities

Error Handling

Centralized error handling with custom exceptions:

  • AppException (base exception)
  • NotFoundException
  • BadRequestException
  • ConflictException
  • UnauthorizedException
  • ForbiddenException

License

This project is licensed under the MIT License.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages