andrmiw9 / sof_stats

Сервис парсинга ответов со Stack Overflow (PROD-ready)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

sof_stats

Описание

Сервис sof_stats предоставляет endpoint /search для отправки запроса на поиск ответов по переданному тегу (тегам). Сервис обрабатывает запрос и получает первые 100 релевантных ответов c с сайта StackOverflow, собирая по ним статистику. После этого статистика возвращается отправителю запроса. Проект представлен в готовой к PRODUCTION версии.

Инструкция по развертыванию

Поскольку требуется запуск одной командой, мною написаны bash скрипты для развертывания. Алгоритм действий:

  1. Cкачать docker образ (sof_stats.tar) и run_from_image.sh скрипт Ссылка на Google Drive
  2. Поместить оба файла в одну папку
  3. Запустить run_from_image.sh скрипт

Альтернативный вариант:

  1. Скачать проект с GitHub
  2. Запустить build_and_run.sh (требуется Docker BuildKit для кэша, можно убрать в Dockerfile)
Команда для ручного запуска контейнера:
docker run -d \
-p 7006:7006 \
-p 80:80 \
-p 443:433 \
--dns 8.8.8.8 \
--restart=always \
--name sof_stats_0 \
sof_stats:1.002.001
где 1.002.001 - версия проекта, а 7006 - порт указанный в dockerfile и конфиге.

Файловая система и настройка

В папке configs лежат 2 конфига - один для тестов на Windows (config_win.toml), один для PROD запуска (config_war.toml). В корне проекта лежит Dockerfile и скрипт для пересобрания образа и запуска контейнера (build_and_run.sh). В папке tests шаблоны для написания тестов с готовыми фикстурами. Файл version используется для версионирования.

По-хорошему должен быть volume с конфигом и ещё один для логов, но тогда передать контейнер будет ещё проблемней.

Если вы хотите изменить порт работы приложения, то сделать это надо в 2-ух местах: в конфиге и в dockerfile (и так же в build_and_run.sh, если вы его используете)

Ответы

Если происходит какая-либо ошибка, то возвращается соотв-ий статус запроса (не 200 OK) и сообщение об ошибке в формате JSON. Пример возврата при ошибке:

{
  "detail": "Code 429, StackOverflow error: too many requests from this IP, more requests available in 83506 seconds"
}

Пример возврата без ошибок:

{
  "rust": {
    "total": 27,
    "answered": 16
  },
  "rusqlite": {
    "total": 1,
    "answered": 0
  }
}

Если по какому-то из тегов приходит пустой или плохой ответ, то он пропускается, ошибка в запросе не выдается - если есть другие теги, которые сработали нормально

HTTP API

Страница Swagger динамической документации (при локальном запуске): http://127.0.0.1:7006/docs (ip и port задаются в конфиге)

Endpoint-ы (ручки):

/diag - возвращает несколько полей статистики: имя сервиса, версию, время работы.

/search - осуществляет поиск по StackOverflow и подсчет статистики ответа, если все ок.

/config - работает только в среде TEST (env_mode в конфиге). Возвращает экземпляр использующихся настроек.

Заметки:

  • Если /search передали 2 тега, то результаты их статистики по тегам обьединяются
  • 5 пункт задания - сколько раз на вопрос был дан ответ. Предполагаю, что имеется в виду is_answered.
  • Мой сервис поддерживает русский язык, но вот StackOverflow не поддерживает русские теги, насколько я понял.
  • Если один из тегов не буквы-цифры, то выкидывается ошибка. Альтернатива - выкинуть тег и искать по всем остальным тегам, если они нормальные, но из-за формата ответа я не знаю как передать сообщение о неправильном теге => тот, кто запрашивал, даже не узнает, что в теге была ошибка.
  • Если в переменных окружения (среды) есть HTTP_PROXY, то для запросов будет использоваться она.
  • Если в переменных окружения (среды) есть SOF_STATS_CONFIG (внутри контейнера), то этот путь будет использоваться для получения конфига
  • Вверху run_sof_stats.py есть список TODO
  • Для ограничения в 1000 запросов я использовал httpx.limits. Однако при превышении лимита просто вызывается исключение httpx.PoolTimeout (то есть реквесты ожидают освобождения места какое-то время - таймаут). Так как этого оказалось
    недостаточно я ввел также asyncio.BoundedSemaphore(1000) (1000 - задается в конфиге переменной max_requests)
  • Максимальный тест доступный в Postman - 100 клиентов одновременно, он прошел. На 1000 не протестировано. Сам семафор протестирован, просто на меньших значениях.
  • Для ускорения ответа используется либа orjson взамен стандартной json. (~ в 5 раз быстрее для моего приложения)

About

Сервис парсинга ответов со Stack Overflow (PROD-ready)


Languages

Language:Python 91.2%Language:Dockerfile 5.1%Language:Shell 3.8%