Как внести свой вклад

Внесение своего вклада в этот проект ничем не отличается внесения в других open source проекты на GitHub’e, но есть несколько ключевых моментов, о которых стоит знать и помнить.

Все необходимые пакеты для разработки есть в requirements-dev.txt. Установить их можно с помощью следующей команды:

pip install -r requirements-dev.txt

Асинхронные зависимости (aiohttp, aiofiles) вынесены в опциональный экстра async. Для работы с асинхронным клиентом установите библиотеку так:

pip install yandex-music[async]

Основные типы вклада:

  • добавление новых полей к существующим моделям;

  • добавление новых моделей;

  • установка опциональности какого-то поля;

  • добавление нового метода в Client (новый запрос на API);

  • добавление нового метода-сокращения в модель;

  • добавление примера использование в папку examples.

Ваш вклад может быть более грандиозным. Так, например, можно написать интеграционные тесты для класса Client и всех методов-сокращений в моделях. Написать тесты для класса запросов. Написать генератор кода для быстрого добавления новых полей.

Pull Requests

PR’ы должны быть сделаны в main ветку. Определённого шаблона оформления нет. Если это закрывает какое-то issue, то стоит сослаться на него с ключевым словом “close”. Например, “close #123”. Обращайте внимание прошёл ли Ваш PR все проверки GitHub Actions (тесты, проверка стиля кода).

Тесты

Для тестирования используется pytest. На данный момент отсутствуют интеграционные тесты. Поэтому всё что сейчас требуется — это модульные тесты классов-обёрток и их дополнительных методов (если имеются), которые не являются сокращениями для методов клиента.

Тесты модели должны покрывать 5 основных вещей: конструктор, десериализацию только обязательных полей, десериализацию всех полей, сравнение объектов модели, десериализацию пустого словаря. По необходимости десериализацию списка объектов.

Примеры доступны в папке tests.

Документация

Для документации используется Sphinx. Документация ведется в google style. К каждому классу и методу должна быть написана документация на русском языке. Указаны типы каждого значения. По возможности описано предназначение поля. Если невозможно логически понять из названия или данных — ставим TODO. Обязательно отмечаем какие поля являются опциональными. Пишем заметки по известным значениям полей, чтобы из контекста догадываться о предназначении.

Если добавлен новый класс или функция, то не забудьте сгенерировать .rst файл выполнив команду make gen в папке docs и добавить его в GIT.

Чтобы собрать документацию выполните make html в папке docs. Для отчистки используйте make clean.

Форматирование кода (стиль написания)

В проекте используется ruff. Не забывайте перед публикацией отформатировать код и проверить его на работоспособность. Используются одинарные кавычки.

Запуск линтера:

ruff check .

Запуск форматера:

ruff format .

Создание новых моделей

Исходите из логики при помещении модели в определённый пакет. Одна модель — один файл (snake_case_class_name.py). Добавьте свою модель для короткого импорта в одну из секций __init__.py файла и пропишите название в __all__.

Обязательно следите за тем, какие поля присутствуют всегда, а какие нет. По возможности минимизируйте количество опциональных полей.

Не забывайте перечислить поля, по которым можно отличить один объект от другого в _id_attrs (метод __post_init__).

Экземпляр класса Client передаётся в каждую модель для возможности написания методов-сокращений. При наличии дополнительных методов у модели не забудьте создать асинхронную версию метода добавив в название суффикс _async.

Кроме этого, если у вашей модели есть метод, например, download_async(), то такому методу следует создать camel case псевдоним (downloadAsync()). Для создания псевдонимов существует генератор. Всё что вам надо сделать это поместить в конце файла с моделью маркер:

# camelCase псевдонимы

(пример)

После чего запустить генератор:

python generate_camel_case_aliases.py

Создание новых методов клиента

Начиная с версии 3.0.0 асинхронная версия клиента является первичной. Синхронная версия генерируется из асинхронной с помощью unasync.

Клиент разбит на миксины по доменным группам API (account, landing, tracks, search, playlists, radio, artists, albums, likes, queue, clips, concerts, credits, disclaimers, labels, metatags, music_history, pins, presaves, device_auth и др.). Асинхронные миксины находятся в yandex_music/_client_async/, синхронные — в yandex_music/_client/. Общие атрибуты и утилиты вынесены в yandex_music/_client_base.py (ClientBase).

Правила:

  • Новый метод добавляется в соответствующий миксин в yandex_music/_client_async/. Если для метода нет подходящего миксина — создайте новый.

  • После изменения асинхронной версии обязательно запустите генерацию синхронной:

    python generate_sync_version.py
    
  • Ни в коем случае не редактируйте файлы в yandex_music/_client/, а также yandex_music/client.py и yandex_music/utils/request.py руками — они генерируются из асинхронных версий.

Makefile

Используйте WSL если вы на Windows.

Для упрощения жизни в корне проекта существует Makefile.

Команда

make all

Выполнит за вас ruff и ruff format, сгенерирует синхронную версию клиента из асинхронной, сгенерирует camel case псевдонимы.