видео: https://disk.yandex.ru/i/tpOuwVU73Pvcew
- фреймворк FastAPI для создания API
- SQLAlchemy и ORM для работы с PostgresSQL, подключение реализовано с помощью асинхронного контекстного менеджера
- Motor для работы с MongoDB, подключение также через асинхронный контекстный менеджер
- весь код протестирован на pytest
Как говорилось в основном README, на бэкенде используется слоистая архитектура.
- Слой представления. В этом слое мы подготавливаем данные для представления на различных платформах, в нашем случае это будут тг бот и мини-приложение
- Слой сервиса. Подготовка данных для сохранения и дальнейшей обработки. Реализует инкапсуляцию бизнес-операций.
- Слой работы с данными. Мы абстрагируем работу с данными, что позволяет бизнес-логике не зависеть от конкретной реализации слоя работы с данными.
- api. В этой папке первая основная версия апи (v1), которая общается с продакшн базой данных. Каждый сервис, используемый в хендлерах прокидывается, как dependency injection (ну почти), для валидации данных используется Pydantic схемы
- app. Реализация кастомного FastAPI приложение, где подключается CORS и все роутеры
- auth. Функции для работы с JWT аутенфикацией: создание аксес и рефреш токенов, проверка, что запрос пришел из телеграм
- database. Асинхронные коннекторы для работы с базами данных MongoDB и PostgresSQL
- models. Делится на две части: DTO и ORM
- DTO - data transfer object. Просто наборы pydantic моделей для разных задач, которыми обмениваются слои при общении.
- ORM - ORM схемы для работы с PostgresSQL
- repository. Слой репозитория. В интерфейсе определен лишь session_getter - по умолчанию это коннектор к продакшн базе, но в тестах мы можем это подменить на другой, чтобы инкапсулировать тесты.
- service. Слой сервиса.
В другом разделе README есть туториал, как их запустить, но тут я просто расскажу, что там есть:
- Тесты на хендлеры. Используется асинхронный клиент из httpx вместе с веб-сервером uvicorn. Для тестов написан клон API, так как было бы очень плохой идеей делать основной API так, чтобы влиять на то, с какой базой данных будет производиться работа.
- Тесты на репозиторий и сервис. Они в целом очень похожи, но в целом это обычные интеграционные тесты, которые работают с тестовой базой данных
- Всего в проекте 190 тестов, и все проходят. Сейчас осталось протестировать только ручки на хендлеры и ручки, которые будут менять свойства ресторана
- понять, нужно ли допиливать jwt или все работает, как надо
- дописать хендлеры, которые будут по одному апдейтить свойства ресторана + тесты на них
- в целом в остальном тут все готово уже и можно
пить пиводелать лабу по матану2
Обзор на API и тесты можно чекнуть по ссылке на видеоотчет!
Готова вся архитектура, однако по этой части не успеваем больше всего, из-за линейности тг ботов и как следствие необходимости прописывания каждого действия
Пока нет связки с бэком по запросам и стоят затычки. Также не готов процесс добавления ресторанов. Сейчас реализуется "наследование свойств ресторанов" при добавлении нового. Также нужно реализовать возможность редактировать рестораны, если совсем не будем успевать, опустим этот момент в пользу добавления новых, так как там интереснее функционал с точки зрения реализации. Также пока есть лишь интеграционные тесты на Storage
https://drive.google.com/file/d/1rwgaNOuEW5syddDfTwZbfoIIPtpVnQXR/view?usp=sharing
Самая сложная часть по функционалу - MainPage готова на 99% с точки зрения верстки и функционала
Более подробно смотрите в доке фронта
Пока что фронт не связан с бкэом, в функциях для обращений к бэку стоят затычки. Также необходимо допилить profile page и restaurant page - это достаточно быстро, так как архитектура уже выстроена, а также на данных страницах мало интерактивности. Из того, что осталось реализовать на MainPage - функциональность модального окна: рекомендации при вводе адреса, интеграция с Api Tg для получения координат пользователя. Также нужно хендлить ситуацию когда пользователь зашел в первый раз и у нас нет его последнего адреса: планируется примерно определять его город (например по ip) и показывать рестораны оттуда. Также пока не была протестирована интеграция с ТГ. Также хочу поработать с lazy loading фото
Фронт в приоритете над ботом из недоделанного, так как вносит значительно больший вклад в продукт
https://drive.google.com/file/d/1r4y8qIkG9Zp2Os1F-bQVB7kBvQ41LW9e/view?usp=sharing
Notes для видео:
- Лаги на видео на стороне записи (если нужно можем вживую подойти показать)
- Задержка загрузки - искусственная, для демонстрации экрана загрузки, по факту быстрее
- 0.47 - показано, что стейты сейвятся при возвращении на страницу
- 0.53 - тест кнопки скролла наверх
- 1.13 - при обновлении адреса загружаются новые рестораны и к ним сразу применяются уже выбранные категории (то, что рестораны новые можно определить по координатам)
- 1.24 - сейм, загружаются новые ресты (на практике будет по поисковой строке)
- 1.38 - так много свободного пространства из-за мобильной клавиатуры, показаны кнопки для определения своего адреса и ввода адреса для ручного поиска
Подняли монгу, постгресс и редис. Добавили тестовую базу данных в постгрес для интеграционных тестов. Настроили Redis через .conf
Добавить аутентификацию в MongoDB, сейчас работает без нее, что unsafe
Подняли и отладили
Нам необходимо перейти на HTTPS так как это требование Telegram к мини-приложениям
Создайте в корне проекта .env файл, согласно .env-example
Также создайте по образцу .env файл в директории databases и backend
Создайте приватный и публичный ключ для JWT аутенфикации:
cd backend
mkdir certs
cd certs
openssl genrsa -out jwt-private.pem 2048
openssl rsa -in jwt-private.pem -outform PEM -pubout -out jwt-public.pem
Теперь можно запустить докер компоуз с нашими контейнерами
docker-compose up
ссылка на Swagger: http://localhost:8000/docs
ссылка на MiniApp: http://localhost:3000/
На тг бота можно посмотреть на видео, так как мы не можем шерить токен))
Запустите базы данных
cd databases
docker-compose up
cd ../backend/ # если были в папке databases
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pytest -v
cd ../bot/
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pytest -v
Мы разрабатываем мини-приложение ТГ для удобной агрегации ресторанов рядом с пользователем. Весь интерфейс будет завязан на телеграм боте
- Получить ближайшие рестораны к пользователю по введенному адресу
- Возможность выбирать любимые рестораны/категории
- Агрегированная информация о ресторане из несколкьих источников
- Система рекомендаций от бота
- Добавить/удалить/редактировать свой ресторан через бота
- Возможность 'наследования' свойств ресторанов для быстрого добавления новых заведений
- Coming soon: Эффективное продвижение для бизнеса за счет отслеживания поведения пользоавтелей
Вся вериификация асболютно невидима для пользователя и осущесвляется единожды при входе в приложение, до заверешения сессии
Вид страницы:
-
Для нового пользователя
При входе на главную страницу сервис предложит вам выбрать адрес, в то время как будут показаны рестораны которые примерно близки к вашему текущему местоположению
-
Для старого пользователя
Ваш последний адрес будет сохранен и при следующем входе в приложение, будет отображена страница с ближайшими к нему ресторанами
На данной странице доступны выбор категорий и адреса, поиск и переход на страницы пользователя и ресторана Данная страница всегда кэшируется при переходе на другие, поэтому выбранные категеории, введенные поисковые запросы и.т.п сохраняются, также при возврате на страницу сохраняется положение пользоавтеля на ней
Выбранные категории сохраняются и применяются при поиске
Поиск осуществляется не по точным, а по наибольшим совпадениям, что позоляет искать рестораны максимально удобно для пользоавтеля
На данной странице будут продемонстрированы фотографии ресторана, его описание, ссылки на его сайт и на него в других источниках, также там будут показаны рейтинг ресторана на каждом из них, с количеством людей оставивших отзыв и агрегированный рейтинг на основе этих показателей.
Для каждого заведения будет показан список категорий к кооторому он принадлежит
Также для каждого ресторана в развертывающемся окошке будет доступно меню
У пользователя будет возможность добавить ресторан в избранное или убрать его оттуда
При наличии возможности, мы бы хотели ввести выкладку по отзывам со всех источников используя Api какой-либо LLM
Данная страница предназначена для управления всеми фишками мини-приложения
На ней можно будет добавить / удалить любимые категории / рестораны, сбросить предпочтения и.т.п
Дальнейший список функций будет расширяться
P.s выбор адреса в очень сыром виде))
Cooming soon...
Same...
-
Фронтенд:
- React
- Vite
- telegram-apps/telegram-ui (для интеграции с интерфейсом тг)
-
Бэкенд:
- python FastAPI (для создания API)
- SQLAlchemy (для данных пользователей)
- Celery (фоновые задачи)
- Redis (для распределения нагрузки на БД и бэк при записи польз. логов)
- aiobotocor (асинхронная S3 для изображений)
-
Базы данных:
- PostgreSQL (Основная БД)
- MongoDB (для меню ресторанов и их описания)
Внутри PostgreSQL будем использоавть pg_trim для быстрого поиска по похожим назавниям и postgis для быстрого поиска по ближайшим ресторанам
-
Контейнеризация через Docker
-
python-telegram-bot для телеграм-бота
-
Api Яндекс карт для работы с географическими данными
Используем микросервисную архитектуру: под фронтенд, бот, бэкенд, все базы данных и утилиты будут созданы контейнеры в Docker.
Бэкенд будет реализован через слоистую архитектуру.
Делим бэкенд приложения на 3 слоя:
- Слой представления. В этом слое мы будем подготавливаем данные для представления на различных платформах, в нашем случае это будут тг бот и мини-приложение в телеграм
- Слой сервиса (бизнес-логики). Подготовка данных для сохранения и дальнейшей обработки. Реализует инкапсуляцию бизнес-операций.
- Слой работы с данными. Мы абстрагируем работу с данными, что позволяет бизнес-логике не зависеть от конкретной реализации слоя работы с данными, например, можем легко поменять реляционную БД на нереляционную.
Мы используем паттерн репозиторий, создавая абстрактный репозиторий для разных целей: один абстрактный для работы с меню ресторана, другой для хранилища фотографий, третий для данных ресторанов и пользователей.
Для каждого мы будем импелементировать реализацию: для меню будет MongoDB, для фоток S3 (через aiobotocor), для табличек PostreSQL.
Также создаем абстрактный сервис для каждой цели, который будет проводить операции с соответствующим ему абстрактным репозиторием.
В слое представления будут версии для удобного версионирования получившегося API.
Связывать это все будет NGINX, который мы тоже поднимем как отдельный контейнер.
- Даниэль Минкин (фронтенд + бд), @MinkinDD - автор идеи, писать ему
- Олег Швецов (бэкенд), @olezha223