This system is a scaffold for developing web applications using FastAPI. It is designed with maintainability and scalability in mind by implementing an architecture inspired by the principles of Onion Architecture. The system decouples the core business logic from external dependencies, ensuring flexibility and ease of modification. The application includes integration with SQLAlchemy for database handling, Alembic for migrations, and support for containerized development with Docker. Additionally, it provides tools for testing, generating documentation, and managing database schemas.
- Docker desktop, or Docker engine and docker-compose
** Also, you should install python and python modules in requirements.txt and requirements.dev.txt for development.
# Start
bin/app.sh up --build -d
# Migration
bin/app.sh exec app alembic upgrade head
# Load seed data
bin/app.sh exec app python app/load_seeds.py
# Stop
bin/app.sh down
# Delete DB
docker volume rm fast-api-web-app-scaffold_fawapp_postgresdbThe architecture of this source code follows the concept illustrated in the diagram below. This architecture is loosely based on the principles of Onion Architecture, which ensures maintainability and scalability of the code. By isolating the Domain layer as the independent core, we achieve:
- Independence: The business logic and entities are not influenced by external systems or frameworks, making the core reusable and testable.
- Flexibility: The Application, Interfaces, and Infrastructure layers can be modified or swapped without affecting the core logic.
- Scalability: Clear boundaries between layers support easier integration of new features and technologies in specific areas while keeping the overall system robust.
- Maintainability: Changes in UI, APIs, or database structures are decoupled from the business logic, minimizing the impact on other parts of the system.
** Direct dependencies from Interfaces or Infrastructure to Domain are also possible but are omitted here.
+--------------------+
| Domain | <- Business Logic & Entities
| (Independent Core)|
+--------------------+
^
|
+--------------------+
| Application | <- Use Case Implementation
+--------------------+
^ ^
| |
+------------------+ +--------------------+
| Interfaces | | Infrastructure |
| (UI, API, etc.) | | (DB, External APIs)|
+------------------+ +--------------------+
Generated by pydeps.
pydeps ./app --rmprefix app. --reverse --max-bacon 3 --only app --max-module-depth=3 -o app_only.svgIf you want to check dependencies from each architecture layer to external libraries, execute the following command like:
** To simplify implementation, dependencies on sqlmodel, sqlalchemy, and pydantic are allowed
from the Domain and Application layer. The reason is that sqlmodel is a library that enables conversion
between pydantic models and SQLAlchemy models, allowing us to avoid defining almost identical data
classes in both the Domain and Infrastructure layers.
pydeps ./app --rmprefix app. --reverse --max-bacon 4 --cluster --max-module-depth=2 -o app_external.svgYou can run tests in isolated test DB environment.
- Start test DB on docker:
bin/test-db.sh - Run pytest on docker:
bin/test-app.sh run --rm test-app pytest --cov=app tests/ -vv - Stop test DB container:
bin/test-db.sh down
** The bin/test-db.sh script automatically stops the running container and removes the associated volume
each time it is executed.
This ensures test reproducibility by always starting from a clean environment.
Rest assured, this does not impact the development database container and volume in bin/app.sh in any way.
- Write/modify entity definitions using sqlmodel under app/domain/entities directory.
- Start DB container:
bin/app.sh up -d - Generate migration script:
bin/app.sh exec app alembic revision --autogenerate -m "comment like add some tables" - Migrate:
bin/app.sh exec app alembic upgrade head
Generated by tbls.
# You need to delete the existing doc directory before running the below command.
rm -rf doc/db
# Generate the document.
tbls doc# Generate schema document in xlsx format
tbls out -t xlsx -o schema.xlsx- API document: http://localhost/docs , http://localhost/redoc
- DB schema document: /doc/db/README.md