┌─────────────────────────┐ ┌──────────────────────────────┐ ┌─► External Message Broker │ │ WEB ◄───┐ │ └─────┬───────────────────┘ └───────────────────────────┬──┘ │ │ │ │ │ │ ┌─────▼─────────┐ ──── ┌──▼──┐ │ │ │ Eventconsumer ├──────────────────────►/ \◄────────────┤ API │ │ │ └─────┬─────────┘ / \ └───┬─┘ │ │ │ / \ │ │ │ │ / Bootstrap\ │ │ │ │ \ / │ │ │ │ \ / │ │ │ │ ┌───────────────────────── / │ │ │ │ │ \────/ │ │ │ │ │ │ │ │ │ │ ┌────────────────────────────────────────┘ │ │ │ │ │ │ │ ---│-------│-------│------------------------------------------- │ │ - │ │ │ - │ │ - │ │ │ ┌────────────┐ - │ │ - │ │ │ │ ---------- │ - │ │ - ┌▼───────▼───────▼┐ ├────────────┤ ┌──────────────┐ - │ │ - │ Messagebus ├────►│ Handlers ├────►│ unit_of_work │ - │ │ - └─────────────────┘ ├────────────┤ └───────┬──────┘ - │ │ - │ ---------- │ │ - │ │ - └────────────┘ │ - │ │ - Services │ - │ │ -----------------------------------------------------│--------- │ │ │ │ │ ┌────────────────────┘ │ │ │ │ │ --------------------------------│------------------------------ │ │ - │ - │ │ - ┌────────────────┐ ┌────────▼────────┐ ┌───────────────┐ - │ └──────┤ Eventpublisher │ │ Repositories │ │ Notifications├─────┘ - └────────────────┘ └─────┬───────┬───┘ └───────────────┘ - - │ │ - - Adaptorstions │ │ - -----------------------------│-------│------------------------- │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ │ │ │ │ │ Domain area ◄──────────┘ └────────► EdgeDB │ │ │ │ │ └─────────────┘ └─────────────┘
- FastAPI: A fast asynchronous web framework for Python.
- EdgeDB: A database with expressive query syntax.
- Redis Pub/Sub: Publisher-Subscribers mechanism in Redis.
- Pytest: A powerful framework for writing and running tests.
- Docker: Containerization for convenient deployment.
- Mastery of DDD and clean architecture patterns.
- The architecture allowed for easy replacement of Flask with FastAPI and Postgres + SQLAlchemy with EdgeDB.
- Ease of testing and integration due to the separation of the application into layers.
- Template project structure suitable for creating your own projects.
- Approaches from the textbook introduce a significant amount of boilerplate code, which might not be rational for small tasks.
- Potential integration issues.
- The need to learn message delivery systems (Kafka, RabbitMQ).
I've encountered an issue with testing parallel transactions that I can't resolve on my own. The original testing code uses the threading module: Original Test Code tests/integration/test_uow.py - original As I use an asynchronous framework, I've modified it: Asynchronous Test Code tests/integration/test_uow.py - asynchrony During testing, I encounter the exception edgedb.errors.TransactionSerializationError: could not serialize access due to concurrent update Tests are only stopped by a keyboard interrupt (KeyboardInterrupt). I suspect my problem stems from the fact that I'm just starting to learn what asynchronous code is. Maybe I'm not opening and closing the asynchronous transaction context manager correctly:: Async Unit of Work context manager src/allocation/services/unit_of_work.py If anyone could assist, I'd be grateful. Feel free to reach out via comments, Telegram, or Twitter. |
---|
Enhancement of design skills. Application of patterns in other projects. Experience in integrating new libraries and applications.
Commands are provided for both Ubuntu and Windows systems
Ubuntu
- Clone the project:
git clone https://github.com/Gen121/Fastapi-EdgeDB-DDD.git
cd Fastapi-EdgeDB-DDD
- Install dependencies:
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
pip install -e src/
- Create a .env file:
cp env.example .env
This command copies the contents of the env.example file into a new .env file in the root directory, next to the src directory.
- Run the Make command:
make all
During the execution, several Docker containers will be built, and after the launch, testing will be performed.
make test
# or, to run individual test types
make unit
make integration
make e2e
# or, if you have a local virtualenv
make up
pytest tests/unit
pytest tests/integration
pytest tests/e2e
Windows
- Clone the project:
git clone https://github.com/Gen121/Fastapi-EdgeDB-DDD.git
cd Fastapi-EdgeDB-DDD
- Install dependencies:
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
pip install -e src\
- Create a .env file:
copy env.example .env
This command copies the contents of the env.example file into a new .env file in the root directory, next to the src directory.
- Run the .bat script to build and start the container:
run_app.bat call :all
During the execution, several Docker containers will be built, and after the launch, testing will be performed.
run_app.bat call :test
# or, to run individual test types
run_app.bat call :unit-tests
run_app.bat call :integration-tests
run_app.bat call:e2e-tests
# or, if you have a local virtualenv
run_app.bat call :up
pytest tests/unit
pytest tests/integration
pytest tests/e2e
# .env.example
# Disabling .pyc file creation and output buffering
PYTHONDONTWRITEBYTECODE=1
PYTHONUNBUFFERED=1
APP_NAME="edgedb"
NETWORK_NAME="local_dbs_network"
# EdgeDB
DB_USER_NAME="edgedb"
DB_NAME="edgedb"
DB_TEST_NAME="edgedb"
DB_ROOT_PASSWORD="edgedb"
DB_HOSTNAME="edgedb"
DB_PORT=5656
## Volume names for database data and schemas
DB_VOLUME_DATA_NAME="${DB_CONTAINER_NAME}_data"
DB_VOLUME_SCHEMA_NAME="${DB_CONTAINER_NAME}_schema"
DB_CONTAINER_NAME="${APP_NAME}"
# API-server
API_HOST="localhost"
API_PORT=5005
# Redis
REDIS_HOST="redis"
REDIS_PORT=6379
# Email sending host
EMAIL_HOST="mailhog"
[на русском]
- FastAPI: Быстрый асинхронный веб-фреймворк для Python.
- EdgeDB: База данных с выразительным синтаксисом запросов.
- Redis Pub/Sub: Механизм Publisher - Subscribers в Redis.
- Pytest: Мощный фреймворк для написания и запуска тестов.
- Docker: Контейнеризация для удобного развертывания.
- Освоение паттернов DDD и чистой архитектуры.
- Архитектура позволила легко заменить Flask на FastAPI, а связку Postgres + SQLAlchemy на EdgeDB.
- Легкость тестирования и интеграции благодаря разделению приложения на слои.
- Шаблонная структура проекта и подходит для создания своих проектов.
- Подходы из учебника задают высокую константу кода в виде бойлерплейта, что может быть не рациональным для небольших задач.
- Возможные проблемы интеграции.
- Необходимость изучить системы доставки сообщений(Kafka, RabbitMQ)
Улучшение навыков проектирования. Применение паттернов в других проектах. Опыт интеграции новых библиотек и приложений.
Представлены команды для ос Ubuntu и Windows
Ubuntu
- Клонируйте проект:
git clone https://github.com/Gen121/Fastapi-EdgeDB-DDD.git
cd Fastapi-EdgeDB-DDD
- Установите зависимости:
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
pip install -e src/
- Создайте файл .env:
cp env.example .env
Эта команда копирует содержимое файла env.example в новый файл .env в корневой директории, по соседству c каталогом src
- Запустите команду Make:
make all
В процессе запуска будет собрано несколько контейнеров Docker и после запуска выполнено тестирование
make test
# or, to run individual test types
make unit
make integration
make e2e
# or, if you have a local virtualenv
make up
pytest tests/unit
pytest tests/integration
pytest tests/e2e
Windows
- Клонируйте проект:
git clone https://github.com/Gen121/Fastapi-EdgeDB-DDD.git
cd Fastapi-EdgeDB-DDD
- Установите зависимости: Создание и активация виртуальной среды:
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
pip install -e src\
- Создайте файл .env:
copy env.example .env
Эта команда копирует содержимое файла env.example в новый файл .env в корневой директории, по соседству c каталогом src
- Запустите сценарий сборки и запуска контейнера:
run_app.bat call :all
В процессе будет собрано несколько контейнеров Docker, после их запуска выполнено тестирование сервиса
run_app.bat call :test
# или для запуска отдельных типов тестов
run_app.bat call :unit-tests
run_app.bat call :integration-tests
run_app.bat call:e2e-tests
# или, если у вас есть virtualenv
run_app.bat call :up
pytest tests/unit
pytest tests/integration
pytest tests/e2e
# .env.example
# Отключение создания .pyc файлов и буферизации вывода
PYTHONDONTWRITEBYTECODE=1
PYTHONUNBUFFERED=1
APP_NAME="edgedb"
NETWORK_NAME="local_dbs_network"
# EdgeDB
DB_USER_NAME="edgedb"
DB_NAME="edgedb"
DB_TEST_NAME="edgedb"
DB_ROOT_PASSWORD="edgedb"
DB_HOSTNAME="edgedb"
DB_PORT=5656
## Имена томов для данных и схем БД
DB_VOLUME_DATA_NAME="${DB_CONTAINER_NAME}_data"
DB_VOLUME_SCHEMA_NAME="${DB_CONTAINER_NAME}_schema"
DB_CONTAINER_NAME="${APP_NAME}"
# API-сервер
API_HOST="localhost"
API_PORT=5005
# Redis
REDIS_HOST="redis"
REDIS_PORT=6379
# Хост отправки электронной почты
EMAIL_HOST="mailhog"