This is a base project for FastAPI-based APIs implementing clean architecture patterns for maintainable and testable code.
Feel free to use it as a starting point for your own projects.
This project follows the Clean Architecture pattern, with the following layers:
- Domain Layer: Core business logic and entities.
- Application Layer: Use cases and application services.
- Infrastructure Layer: External dependencies and integrations.
The project is structured around modules (vertical slices), with each module having its own directory containing all the necessary layers.
It also implements other patterns and practices, such as:
- Builder Pattern for entity creation.
- Dependency Injection (via Lagom).
- Data Transfer Objects (DTOs) for request and response payloads.
- Value Objects for data validation.
- Result Pattern for handling operation outcomes.
- Repository Pattern for data access.
- Collections for enhanced filtering and sorting.
- Instrumentation for logging and monitoring use cases.
- OData V4 Query for filtering and sorting data.
- Correlation ID for request tracing.
These are some of the main technologies used in this project:
- FastAPI - Web framework for building APIs.
- SQLActive - ActiveRecord pattern for database operations.
- SQLite - Database (via aiosqlite for async operations).
- Lagom - Dependency injection container.
- Pydantic - Data validation and settings management.
- Orjson - Fast JSON serialization.
- Uvloop - High-performance event loop.
- Structlog - Structured logging.
- Validators - Data validation.
- OData V4 Query - OData query parsing.
- ASGI Correlation ID - Requests correlation with unique IDs.
- Ruff - Linter and code formatter.
- Pytest - Testing framework.
.
βββ .env.example # Environment variables template
βββ api.http # HTTP requests for testing
βββ COMMITS.md # Git commit guidelines
βββ pyproject.toml # Project configuration and dependencies
βββ README.md # Project documentation
βββ ruff.toml # Ruff linter configuration
βββ uv.lock # UV dependency lock file
βββ LICENSE.md # Project license
βββ src/ # Source code
β βββ main.py # FastAPI application entry point
β βββ config.py # Application configuration
β βββ health.py # Health check logic
β βββ logger.py # Logging configuration
β βββ middlewares/ # Application middlewares
β β βββ access_log_middleware.py # Access logging middleware
β βββ modules/ # Feature modules (domain-driven)
β β βββ resources/ # Resources feature module
β β βββ application/ # Application layer (use cases)
β β β βββ use_cases/ # Use case implementations
β β β βββ create_resource.py
β β β βββ delete_resource.py
β β β βββ get_resource.py
β β β βββ list_resources.py
β β β βββ update_resource.py
β β βββ domain/ # Domain layer
β β β βββ entities.py # Domain entities
β β β βββ error_codes.py # Domain-specific error codes
β β β βββ exceptions.py # Domain-specific exceptions
β β β βββ value_objects.py # Value objects
β β β βββ collections.py # Domain collections
β β β βββ interfaces/ # Repository interfaces
β β β βββ repositories.py
β β βββ infrastructure/ # Infrastructure layer
β β β βββ instrumentation/ # Use case instrumentation/decorators
β β β β βββ use_cases/
β β β β βββ create_resource.py
β β β β βββ delete_resource.py
β β β β βββ get_resource.py
β β β β βββ list_resources.py
β β β β βββ update_resource.py
β β β βββ persistence/ # Persistence implementations
β β β βββ models/ # Database models
β β β β βββ mock.py # Mock models for testing
β β β β βββ sqlite.py # SQLite database models
β β β βββ repositories/ # Repository implementations
β β β βββ mock.py # Mock repository for testing
β β β βββ sqlite.py # SQLite repository implementation
β β βββ presentation/ # Presentation layer (API)
β β β βββ api.py # Resource API endpoints
β β β βββ dtos.py # Data transfer objects
β β βββ di.py # Dependency injection configuration
β βββ shared/ # Shared utilities and common code
β βββ application/ # Shared application layer
β β βββ interfaces/ # Shared interfaces
β β βββ base.py # Base interfaces
β β βββ instrumentation.py # Instrumentation interfaces
β βββ domain/ # Shared domain layer
β β βββ entity.py # Entity base class
β β βββ error_codes.py # Shared error codes
β β βββ exceptions.py # Shared exception classes
β β βββ value_object.py # Value object base class
β β βββ helpers/ # Domain helpers
β β βββ odata_helper.py # OData query helper
β βββ infrastructure/ # Shared infrastructure
β β βββ db.py # Database connection utilities
β β βββ persistence/ # Shared persistence
β β βββ models/ # Shared models
β β βββ repositories/ # Shared repositories
β βββ presentation/ # Shared presentation layer
β β βββ api.py # Shared API routes (e.g., health check)
β β βββ dtos.py # Base DTO classes
β β βββ responses.py # Response utilities
β βββ utils/ # Shared utility functions
β βββ uuid_tools.py # UUID utility functions
βββ tests/ # Tests directory
β βββ conftest.py # Pytest global fixtures
β βββ resources/ # Resource module tests
β β βββ application/ # Application layer tests
β β β βββ test_create_resource.py
β β β βββ test_delete_resource.py
β β β βββ test_get_resource.py
β β β βββ test_list_resources.py
β β β βββ test_update_resource.py
β β βββ domain/ # Domain layer tests
β β β βββ conftest.py
β β β βββ test_collections.py
β β βββ infrastructure/ # Infrastructure layer tests
β β β βββ persistence/ # Persistence layer tests
β β β βββ repositories/ # Repository tests
β β β βββ test_sqlite_resource_repository.py
β β βββ presentation/ # Presentation layer tests
β β βββ test_create_resource.py
β β βββ test_delete_resource.py
β β βββ test_get_resource.py
β β βββ test_list_resources.py
β β βββ test_update_resource.py
β βββ shared/ # Shared tests
β βββ presentation/ # Shared presentation tests
β βββ api/ # API tests
β βββ test_health.py # Health endpoint tests
- Python 3.10+
- uv
- Clone the repository
- Create and activate a virtual environment:
uv venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate
- Install dependencies:
uv sync
Run the application with:
uv run main.pyThe API will be available at http://127.0.0.1:$PORT/. Replace $PORT with the
port number you configured in the .env file (see the configuration section below).
Copy the .env.example file to .env and update the settings as needed.
cp .env.example .envExample .env file:
ENV=dev
PORT=8000
DEBUG=True
DATABASE_URL=sqlite+aiosqlite:///./test.db
MAX_RECORDS_PER_PAGE=100
LOGS_PATH=./.logs/app.log- Development: SQLite database.
- Connection: Configured via
DATABASE_URLsetting. - Migrations: Automatic table creation on startup.
- Swagger UI:
http://127.0.0.1:$PORT/docs - ReDoc:
http://127.0.0.1:$PORT/redoc
Replace $PORT with the port number you configured in the .env file.
Run tests with pytest:
uv run -m pytestRun linting with ruff:
uv run -m ruff check .GET /health- Application health status.GET /ping- Same as/health.
- Resource endpoints are available under the
/resourcesprefix.
This project structure provides:
- Testability: Easy to unit test business logic.
- Maintainability: Clear separation of concerns.
- Flexibility: Easy to swap implementations (e.g., database providers).
- Independence: Domain logic independent of frameworks.
- Check the commits guidelines.
- Follow the existing architecture patterns.
- Add tests for new functionality.
- Use type hints throughout.
- Run linting with
ruffbefore committing.
This project is licensed under the MIT License.