1. Подготовка и запуск проекта (быстрый старт)
- Клонируем проект из репозитория.
- Устанавливаем зависимости через pip
pip install -r requirments.txt
или poetrypoetry install
. - Настраиваем
.env
файл с переменными окружения. Данный файл используется только для разработки и тестирования приложения. Публиковать в репозитории его не стоит, а в качестве шаблона можно публиковать файл под названием.example.env
. Публикация данного файла в репозитории обуславливается упрощением проверки ТЗ. Данный файл не используется для настройки переменных окружения при разворачивании Docker контейнеров. Пояснение полей файла с переменными окружения описано далее.
DB_HOST
- Хост БД, по умолчанию указан localhost.
DB_PORT
- Порт БД, по умолчанию PostgreSQL слушает порт 5432.
DB_USER
- Пользователь БД, который осуществляет управление и внесение изменений в базу от лица приложения, по умолчанию postgres.
DB_NAME
- Имя БД в которой хранятся данные для работы с приложением.
DB_PASS
- Пароль пользователя БД.
PASS_SALT
- Соль для пароля при регистрации пользователей приложения. Пароли в БД хранятся в хешированном виде. В приложении используется простой механизм соления паролей: одна соль на все пароли.
JWT_SECRET_KEY
- Ключ для соления JWT токенов. Одна на все токены.
JWT_ALGORITHM
- Алгоритм шифровки токена отпускаемого пользователю.
JWT_ACCESS_TOKEN_EXPIRE_MINUTES
- Время актуальности токена в минутах. При истечении срока, токен становится неактуальным и при его предъявлении доступ к ручке будет не доступен.
- Настройка приложения на данном этапе завершена. Перейдем к запуску.
- Выполним подготовку миграции моделей в БД. Для этих целей в проекте используется
alembic
. Находясь в корне проекта, выполним команду в терминалеalembic revision --autogenerate -m "first_migration"
. Флаг со значением-m "first_migration"
можно опустить, поскольку является только названием миграции. После выполнения данной команды вsrc/app/migrations/versions
появится файл с миграцией, а в БД появится таблица с версиями миграций. - Выполним миграцию моделей в БД. Находясь в корне проекта, выполним команду в терминале
alembic upgrade head
. После выполнения данной команды, в БД появится таблица:users
. - Запускаем приложение. Сделать это можно 2-мя способами: с помощью команды в терминале (находимся в корне проекта)
uvicorn src.app.main:app --reload
, либо запустивmain.py
"IDEшным" способом. - Переходим на
http://127.0.0.1:8000/docs#
и тестируем ручки из документации Swagger.
Механизма хранения токенов не предусмотрено, поэтому для корректной работы следует использовать функционал Swagger. Авторизация проходит через соответствующую кнопку Authorize
. Механизм аутентификации и авторизации происходит по протоколу Oauth2.0 с использованием встроенного в fastapi OAuth2PasswordBearer
. Механизма logout не предусмотрено (за исключением встроенным в Swagger), поэтому ждем пока токен протухнет или логинимся под другим пользователем.
Механизмы хеширования паролей и создание JWT токенов самые простые. Токен хранит в себе 2 поля: sub
- id пользователя из БД, exp
- время экспирации токена.
2. Описание и структура проекта
Дерево структуры проекта:
cft-project
├── .venv
├── src
│ ├── app
│ │ ├── migrations
│ │ │ ├── versions
│ │ │ ├── env.py
│ │ │ └── script.by.mako
│ │ ├── models
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ └── users.py
│ │ ├── routers
│ │ │ ├── auth.py
│ │ │ └── user.py
│ │ ├── utils
│ │ │ ├── auth.py
│ │ │ └── database.py
│ │ ├── schemas
│ │ │ ├── tokens.py
│ │ │ └── users.py
│ │ └── main.py
│ └── tests
│ └── routers
│ ├── auth.py
│ └── user.py
├── .dockerignore
├── .env
├── .gitignore
├── alembic.ini
├── docker-compose.yml
├── Dockerfile
├── README.markdown
├── poetry.lock
├── pyproject.toml
└── requirments.txt
Данная структура проекта предполагает простое расширение функционала в случае необходимости.
2.1. alembic и миграции
Директория src/app/migrations
является инициализируемой директорией alembic
, файл env.py
служит для настройки подключения к БД (для alembic
) и указания моделей sqlalchemy
необходимых для создания миграций. В файле имеются строчки:
from src.app.models.base import Base
from src.app.models.users import User
Данные импорты служат указанием моделей необходимых для миграции. Модель Base
используется для получения метадаты, а модель User
используется для включения таблицы в миграцию. При возможном расширении количества моделей, стоит внести импорты в данный файл, в противном случае, модель не будет включена в миграцию. Параметры для подключения к БД подтягиваются из переменных окружения.
Директория src/app/migrations/versions
хранит в себе файлы для прогона миграций.
Файл alembic.ini
в корне проекта является конфигурационным файлом, в нем уже настроена директория для необходимых скриптов, шаблон для именования миграций в виде предварительной временной метки осуществления записи миграции, URL для подключения к БД, указана хука использующая black
для рефакторинга миграции.
2.2. Модели sqlalchemy
Директория src/app/models
служит для работы по созданию и описанию моделей sqlalchemy
. В текущем проекте имеется 2 модели: базовая (описана в файле base.py
), от которой наследуются все остальные и модель User
(описана в файле users.py
). В структуре данного проекта предпологается именование файлов и таблиц в множественном числе от названия модели. Модели описаны в декларативном стиле с использованием Mapped
и при необходимости mapped_column()
для аннотации типов и установки дополнительных параметров и/или ограничений. Рекомендуется переопределение метода __repr__()
для упрощения отладки при разработке приложения. Вынесение параметра id
в базовую модель не предусмотрено и не рекомендуется для других параметров, хоть это и уменьшает объём кода, это может привести к путанице, а явное в 99.9% случаев лучше неявного.
Данная структура упрощает расширение моделей. Описание новой модели следует проводить в текущей рабочей директории с использованием правил и рекомендаций выше. Для дальнейшего использования модели рекомендуется сделать импорт в файл __init__.py
, это очень сильно упростит создание связей relationship()
, маппинг на другие модели следует проводить с указанием имени класса заключенного в кавычки. При данном подходе удаётся избежать циклических импортов без использования TYPE_CHECKING
(p.s. по крайней мере при текущей версии sqlalchemy). Не забывам про импорт новых моделей в файл env.py
из предыдущего пункта о миграциях.
2.3. Схемы pydantic
Директория src/app/schemas
служит для работы по созданию и описанию схем pydantic
. В текущем проекте имеется 2 семейства схем: описанные в файлах tokens.py
и users.py
. Каждое семейство рекомендуется описывать в отдельном файле. Именование файла происходит от множественного числа названия сущности, которую описывают данные схемы. Схемы описанные в файлах служат для получения данных от клиента, прохождения валидации полученных данных, обработки данных и их последующий возврат клиенту.
При расширении схем следует использовать правила и рекомендации описанные выше.
2.4. Роутеры fastapi
Директория src/app/routers
служит для работы по созданию и описанию роутеров fastapi
. В данном проекте имеется 2 роутера: первый для работы с аутентификацией и авторизацией пользователя, второй для работы с операциями над сущностью User
. В данном проекте файлы роутеров именуются в единственном числе от названия сущности роутера. Все ручки описываемые в проекте рекомендуется описывать в роутерах. Файл main.py
хоть и предоставляет такую возможность, но его следует использовать для более глобальных целей, к примеру для установки ограничений на количество запросов к сервису. Импорт роутеров в main.py
осуществляется с использованием алиасов as
. Это позволяет использовать единую конструкцию именования переменных роутеров. Для любого роутера название переменной будет router
и только в main.py
следует разграничить названия. Каждый роутер имеет свой тег и префикс к маршруту.
При расширении роутеров следует использовать правила и рекомендации описанные выше.
2.5. Вспомогательные скрипты и зависимости (Dependencies)
Директория src/app/utils
служит для работы по созданию и описанию вспомогательных функций для работы приложения, а так же зависимостей (Depends) для ручек. В данной директории файлы именуются в соответствии со сферой в которой применяются функции, в ед. числе. В данной директории имеется 2 файла database.py
- служит для подключения к БД, методом получения асинхронной сессии, и auth.py
- в нём описаны функции для создания и обработки токенов и паролей, а так же необходимые зависимости для обработки данных в БД на тему аутентификации и авторизации. При большом количестве вспомогательных функций и зависимостей стоит распределить директорию на src/app/utils/dependencies
и src/app/utils/tools
.
При расширеннии аналогичных функций следует использовать правила описанные выше.
2.6. Тестирование с pytest
Директория src/test
служит для работы по тестированию. За тестирование ручек отвечает директория src/test/routers
, каждый файл отвечает за тестирование ручек данного роутера. Файлы именуются аналогично роутерам.
Следует учесть, что тестируются ручки находящиеся в директории src/app/routers
а они имеют подключение к БД на основе конфигурационного файла в корне проекта .env
, соответственно перед тестированием ручек необходимо изменить конфигурационный файл (если не хотим мучать "рабочую" базу).
При расширеннии тестов следует использовать правила описанные выше.
2.7. Контейнеризация с Docker и использование переменных окружения
Данное приложение подготовлено для контейнеризации в Docker.
Файл Dockerfile
описывает контейнер с приложением, работа осуществляется на основе образа python:3.13-slim
, далее с помощью pip устанавливается poetry, который в свою очередь устанавливает необходимые зависимости. Далее происходит копирование необходимых рабочих файлов и запуск приложения. Обратите внимание на то, что конфигурационный файл .env
не принимает никакого участия в настройке контейнера, поскольку это является нежелательной практикой. О конфиге для приложения ниже.
Файл docker-compose.yml
описывает "развертывание" приложения, помимо запуска контейнера с приложением так же будет развернута БД, с которой будет "сотрудничать" приложение. Именно в данном файле осуществляется настройка переменных окружения, используемое для работы приложения:
Секция db:environment:
POSTGRES_USER
- Пользователь БД аналогичный 1 пункту.
POSTGRES_PASSWORD
- Пароль пользователя БД аналогичный 1 пункту.
POSTGRES_DB
- Имя БД аналогичное 1 пункту.
Секция db:healthcheck:test:
Флаг-U
- Пользователь БД
Флаг -d
- Имя БД.
Секция app:environment:
DB_HOST
- Хост БД. Настройки не требует, подтягивается на основе db
.
DB_PORT
- Порт БД. Используется аналогичное db:ports:
.
DB_USER
- Пользователь БД. Аналогичное POSTGRES_USER
.
DB_NAME
- Имя БД. Аналогичное POSTGRES_DB
.
DB_PASS
- Пароль пользователя БД. Аналогичное POSTGRES_PASSWORD
.
PASS_SALT
- Соль для хеширования паролей. Алгоритм хеширования паролей простой, используется одна соль для хеширования всех паролей.
JWT_SECRET_KEY
- Ключ для кодирования токенов. Алгоритм кодирования простой, используется один ключ для кодирования всех токенов.
JWT_ALGORITHM
- Алгоритм кодирования токенов. Так же один для всех.
JWT_ACCESS_TOKEN_EXPIRE_MINUTES
- Время актуальности токена.
Для разворачивания контейнеров находясь в корне проекта необходимо выполнить в терминале docker-compose up -d
.
По завершению необходимо выполнить миграции docker exec cfttt-app-1 alembic revision --autogenerate -m "init in docker"
далее прогон docker exec cfttt-app-1 alembic upgrade head
. Приложение готово к работе, документация Swagger доступна на http://127.0.0.1/docs#/