Проект состоит из двух частей:
-
API-приложение:
- Реализует RESTful API с двумя эндпоинтами:
GET /api/repos/top100
— возвращает топ 100 публичных репозиториев из PostgreSQL, отсортированных по количеству звезд (с возможностью сортировки по другим полям).GET /api/repos/{owner}/{repo}/activity
— возвращает активность репозитория по коммитам за указанный промежуток времени.
- Окружение приложения настроено через
docker-compose
(см. секцию ниже). - Используемые технологии: Python 3.11, FastAPI, asyncpg, PostgreSQL.
- Запросы к базе данных написаны на чистом SQL.
- Реализует RESTful API с двумя эндпоинтами:
-
Парсер данных:
- Парсит данные с GitHub и сохраняет их в PostgreSQL:
- Топ 100 репозиториев по количеству звезд.
- Информацию об активности коммитов для каждого репозитория.
- Разработан с учетом запуска в Яндекс.Облаке (например, через cloud function) с прокинутыми переменными окружения для подключения к базе данных.
- Парсит данные с GitHub и сохраняет их в PostgreSQL:
-
API-приложение:
- Эндпоинты:
/api/repos/top100
— поддерживает сортировку по полямstars
,forks
,open_issues
,watchers
./api/repos/{owner}/{repo}/activity
— поддерживает выборку активности по диапазону дат (since
иuntil
).
- Архитектура с Dependency Injection для переиспользования кода.
- Эндпоинты:
-
Парсер:
- Обновляет топ 100 репозиториев:
- Каждый день парсер сравнивает данные текущих репозиториев в базе с результатами запроса к GitHub API.
- Сохраняются изменения, включая новую позицию в рейтинге, количество звезд, форков и другие метрики.
- Обновляет активность по коммитам:
- Для каждого репозитория проверяется последняя дата активности в базе.
- Если данных нет, парсер загружает коммиты за последние 30 дней. Если данные есть, загружаются только новые изменения.
- Обновляет топ 100 репозиториев:
Интервал в один день выбран для балансировки между актуальностью данных и нагрузкой на GitHub API. Частые запросы могут:
- Привести к превышению лимитов GitHub API (5000 запросов в час для аутентифицированных пользователей).
- Создать ненужную нагрузку на базу данных и сам сервис.
Одного обновления в сутки достаточно, чтобы:
- Поддерживать актуальность данных для большинства случаев использования.
- Уменьшить нагрузку на инфраструктуру.
-
Создайте файл
.env
на основе.env_example
и укажите реальные параметры подключения к PostgreSQL:POSTGRES_USER=admin POSTGRES_PASSWORD=admin POSTGRES_DB=test_db POSTGRES_URL=db POSTGRES_PORT=5432
Или передайте в переменные окружения данные параметры
-
Соберите контейнеры:
docker-compose build
-
Запустите приложение:
docker-compose up
-
Приложение будет доступно по адресу http://localhost:8080.
-
Получить топ 100 репозиториев:
curl -X GET "http://localhost:8080/api/repos/top100?sort_by=stars"
-
Получить активность репозитория:
curl -X GET "http://localhost:8080/api/repos/example-owner/example-repo/activity?since=2024-11-01&until=2024-12-01"
- Установите зависимости для парсера(requirements.txt)
- Передайте параметры подключения к базе данных через переменные окружения(они аналогичны тем, что выше).
Также, можно добавить данные для подключения к Github
export $(grep -v '^#' .env | xargs)
GITLAB_BASE_URL дефолтится кGITLAB_BASE_URL=https://api.github.com GITLAB_TOKEN=**your_personal_access_token**
https://api.github.com
, TOKEN можно не передавать - Для запуска парсера создайте отдельный скрипт или функцию в облаке (например, Яндекс.Облако), которая запускает файл
parser/main.py
.python3 -m parser.main
-
Запустите полную инфраструктуру, включая API, парсер и базу:
docker-compose -f docker-compose-dev.yaml up --build
-
Парсер настроен на запуск по расписанию через cron, но его также можно запустить вручную:
docker exec -it <parser-container-id> python /app/parser/main.py
- Для локальной разработки необходимо создать таблицы, определенные в
create_tables.sql
(молюсь чтобы они были такие же) -
CREATE TABLE IF NOT EXISTS top100 ( repo TEXT NOT NULL, owner TEXT NOT NULL, position_cur INT NOT NULL, position_prev INT NOT NULL, stars INT NOT NULL, watchers INT NOT NULL, forks INT NOT NULL, open_issues INT NOT NULL, language TEXT, PRIMARY KEY (repo, owner) ); CREATE TABLE IF NOT EXISTS activity ( date DATE NOT NULL, commits INT NOT NULL, authors TEXT[] NOT NULL, repo TEXT NOT NULL, owner TEXT NOT NULL, PRIMARY KEY (date, repo, owner) );
-
Отказ от Terraform/CLI Яндекс.Облака:
- Не хватило времени на изучение CLI или Terraform для работы с Яндекс.Облаком.
- Также невозможно стартовать бесплатный аккаунт без юридического лица.
- Для тестирования и отладки парсер настроен в контейнере с cron.
-
Инструкция для облака:
- Парсер можно развернуть в Яндекс.Облаке через cloud function, прокинув переменные окружения для подключения к БД.
- Скрипт парсера сам запускает обновление данных.
Приложение готово к запуску и тестированию.