Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mementomorri/micro_octo_handler
Микросевисное приложение обработки сообщений на основе архитектуры REST.
https://github.com/mementomorri/micro_octo_handler
fastapi fastapi-users jwt microservice python rest sqlite
Last synced: 8 days ago
JSON representation
Микросевисное приложение обработки сообщений на основе архитектуры REST.
- Host: GitHub
- URL: https://github.com/mementomorri/micro_octo_handler
- Owner: mementomorri
- License: gpl-3.0
- Created: 2024-03-19T20:00:33.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2024-04-03T12:49:13.000Z (8 months ago)
- Last Synced: 2024-04-03T13:54:07.309Z (8 months ago)
- Topics: fastapi, fastapi-users, jwt, microservice, python, rest, sqlite
- Language: Python
- Homepage:
- Size: 2.09 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# micro_octo_handler
Микросевисное приложение обработки сообщений на основе архитектуры REST.
## Дословная формулировка т/з
Реализовать приложение, принимающее запросы на обработку через REST.
Сообщения обрабатываются двумя провайдерами:
- бесплатным
- и платным,
путем общения через REST.
По бесплатному провайдеру есть ограничение: он может принять какое-то количество запросов, затем блокирует обращения на определённый промежуток времени.
Возможно получить отказ в обслуживании формированием рабочего запроса на бесплатный сервис, однако правильнее обрабатывать количество отправленных запросов в сервис и сравнивать с доступным количеством.
При блокировке запросы следует отправлять в платный сервис. При доступности бесплатного сервиса следует переключиться на бесплатный, минимизируя использование платного провайдера.
При разработке иметь в виду, что приложение может работать на нескольких изолированных подах без использования общей памяти.
Необходимо наличие тестов.## Интуиция
1. Поскольку подразумивается, что приложение может быть разделено на несколько подов, то имеет смысл реализовать микросервисную архитектуру. Приложение будет разделено на три микросервиса:
- бесплатный провайдер;
- платный провайдер;
- аутентификация пользователей.
2. По-умолчанию буду направлять клиента на бесплатный провайдер, если пороговое значение запросов превышено, то клиент будет перенаправлен на платный провайдер. Для имитации работы платного провайдера условно ограничу его использование по ключевому аттрибуту JWT токене.
3. Необходимо каким-то образом идентифицировать пользователя, поэтому добавлю идентификаю пользователя по стратегии JWT хранимых в куки файлах и изолирую пользователя от платного провайдера, если у него нет права доступа.
4. Наличие БД не является необходимым, поскольку по заданию не уточняется нужно ли хранить информацию об обработанных сообщениях и нужно ли её кэшировать. Обработка сообщений в провайдерах будет имитироваться через обработку переданной строки сообщения.## Реализация
Реализовано два провайдера обработки сообщений `free_provider` для бесплатной обработки сообщений и `paid_provider` для платной соответственно. Также добавлен микросервис для аутентификации пользователей и обработки информации связанной с ними `user_microservice`. Перед обработкой сообщения пользователь направляется на микросервис аутентификации, получает JWT токен и получает доступ к провайдеру обработки сообщений. При поверхностном тестировании обработка сообщений и переключение между провайдерами работает корректно. Проверить это можно в ручную собрав `venv` через соответствующие файлы зависимостей в папке `requierements` или через сборку контейнера используя `Dockerfile` в соответствующих папках провайдеров и микросервиса аутентификации пользователей.## Сборка и запуск
### Контейнеры
Можно сэимитировать разделение микросервисов на поды собрав каждый в отдельный докер контейнер. В папках `src/user_microservice`, `src/free_provider` и `src/paid_provider` имеются инструкции Dockerfile для сборки контейнера. Их можно собрать с помощью команд в комментариях к Dockerfile, а именно:
- `src/user_microservice/Dockerfile` - собираем и запускаем командой: ```docker build . --tag users_microservice && docker run -p 8000:8000 users_microservice```;
- `src/free_provider` - собираем и запускаем командой: ```docker build . --tag free_provider && docker run -p 2197:2197 free_provider```;
- `src/user_microservice/Dockerfile` - собираем и запускаем командой: ```docker build . --tag paid_provider && docker run -p 2198:2198 paid_provider```.Каждый микросервис будет имееть соответствущий адес:
- http://0.0.0.0:8000 для микросервиса пользователей;
- http://0.0.0.0:2197 для бесплатного провайдера;
- http://0.0.0.0:2198 для платного провайдера.Также можно заглянуть в сгенерированную документацию в разделе `/docs` каждого микросервиса.
### venv
1. Для быстрой сборки и запуска приложения в режиме отладки можно воспользоваться скриптом `build_and_deploy.sh`.
2. Либо собрать зависимости в ручную через файл зависимостей `dev.txt` из папки `requierements`, инициализировать виртуальную среду командой:
```shell
cd requirements; python -m venv venv; source venv/bin/activate; pip install -r dev.txt
```
и запустить сервисы через `uvicorn` из каждой папки, например `uvicorn microservice:app --reload --port=8000`
## Ручное тестирование
Сымитируем поведение пользователя взаимодействующего в нашим приложением через API. Сначала пользователю необходимо зарегистрироваться, при регистрации укажем выиышленную почту и пароль для пользователя:
![Скриншот 1 - Регистрация](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_1.png)
После регистрации наш тестовый пользователь bob получит ответ в виде статус кода 201 и в ответ получит добавленные о нем данные.
![Скриншот 2 - Ответ на регистрацию](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_3.png)
Далее пользователю необходимо залогиниться, укажем электронную почту и пароль введенные при регистрации.
![Скриншот 3 - Авторизация](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_4.png)
Если всё прошло успешно, пользователь получит статус код 204.
![Скриншот 4 - Ответ на авторизацию](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_5.png)
И JWT токен в виде куки.
![Скриншот 5 - JWT токен в куки](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_6.png)
Теперь пользователь хочет воспользоваться бесплатным провайдером обработки сообщений, перейдем на адрес с бесплатным провайдером, введем значение токена и обрабатываемое сообщение.
![Скриншот 6 - Обработка бесплатным провайдером](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_7.png)
В ответ пользователь получит статус код 200 и результат обработки запроса. В тестовом варианте это просто перевернутая строка.
![Скриншот 7 - Результат обработки бесплатным провайдером](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_8.png)
Теперь сыметируем ситуацию, когда пользователь отправил ещё 9 сообщений и лимит бесплатных сообщений для него закончился `"free_messages_left": 0`.
![Скриншот 8 - Результат обработки бесплатным провайдером](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_9.png)
Теперь наш пользователь, не имея доступа к платному провайдеру, хочет обработать ещё одно сообщение, обращается к бесплатному провайдеру и получает такой ответ со статус кодом 403.
![Скриншот 9 - Обработки в отсутствии бесплатных сообщений](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_11.png)
Представим, что наш пользователь приобрел платную подписку и теперь его поле `paid_access` имеет значение `true`, снова обратившись к бесплатному провайдеру он увидит сообщение.
![Скриншот 10 - Получение платной подписки](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_14.png)
Теперь сымитируем ситуацию, когда пользователь зарегистрировался днём ранее и исчерпал запас песплатных сообщений, обращайте внимание на дату в поле `refresh_at` - 25.03 и тукущую дату - 26.03.
![Скриншот 11 - обновление бесплатных сообщений](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_15.png)
Пользователь хочет обратиться к бесплатному провайдеру и видит успешный результат.
![Скриншот 12 - Обработка счетчика бесплатных сообщений](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_16.png)
Если взглянуть в данные о пользователе, то видно, что дата следующей выдачи бесплатных сообщение и количество бесплатных сообщение обновилось.
![Скриншот 12 - Обновление поля бесплатных сообщений](https://github.com/mementomorri/micro_octo_handler/blob/main/screenshots/Screenshot_17.png)