Yet another Python wrapper for Shikimori API
Project description
Shikithon
Очередной враппер для Shikimori API, написанный на Python
Состояние библиотеки: завершена основная разработка
На данный момент, библиотека находится в статусе поддержки (новые функции будут добавляться только по необходимости)
Начиная с версии 2.0.0, библиотека поддерживает асинхронные запросы, отдельные пути к ресурсам API и многое другое
Описание
Данный враппер предоставляет базовую абстракцию, которая позволяет удобнее работать с методами API и их ответами.
Для каждого эндпоинта API существует свой объект с методами, которые благодаря библиотеке Pydantic, возвращают удобную модель данных.
Все данные, возвращаемые API Shikimori, валидируются и парсятся в модели, со всеми необходимыми полями, а также дополнительными, которые могут вернуть некоторые методы API (Например /users/whoami и /users/:id/info возвращают разные поля). Это позволяет не задумываться об обработке очередного ответа от сервера и сосредоточиться над реализацией своей идеи.
Также благодаря многочисленным проверкам при взамодействии с запросами, библиотека старается добиться максимально безопасной работы с API: все ошибки API, переданных параметров, данных и т.д. обратываются и логируются и возвращаются значения по умолчанию
Данная библиотека начинают свою поддержку с Python 3.8.10.
Установка
pip install shikithon
Пример использования
С использованием полного конфига:
import asyncio
from typing import Dict
from json import loads
from shikithon import ShikimoriAPI
# Можно установить данные конфигурации в коде
config = {
"app_name": "...",
"client_id": "...",
"client_secret": "...",
"redirect_uri": "...",
"scopes": "...",
"auth_code": "..."
}
# Или же прочитать его из внешнего файла
with open("config.json", "r", encoding="utf-8") as config_file:
config_2: Dict[str, str] = loads(config_file.read())
async def main():
# Инициализация объекта API
shikimori = ShikimoriAPI(config)
# Запуск сессии
await shikimori.open()
# Получение данных текущего пользователя через /users/whoami
user = await shikimori.users.current()
print(f"Current user is {user.nickname}")
# Получение достижений пользователя через /achievements
# и вывод первого достижения
user_achievements = await shikimori.achievements.get(user.id)
if user_achievements:
print(user_achievements[0])
# Закрытие сессии
await shikimori.close()
asyncio.run(main())
# >> Current user is SecondThundeR
# >> id=719972946
# >> neko_id='animelist'
# >> level=1
# >> progress=77
# >> user_id=723052
# >> created_at=datetime.datetime(...)
# >> updated_at=datetime.datetime(...)
# На самом деле достижение выводится как одна строка с данными.
# Для удобства она показана здесь раздельно
С использованием имени приложения:
import asyncio
from shikithon import ShikimoriAPI
# Можно установить имя приложения в коде
app_name = "..."
# Или же прочитать его из внешнего файла
with open("config.txt", "r", encoding="utf-8") as config_file:
app_name_2 = config_file.readline().strip()
async def main():
# Инициализация объекта API
async with ShikimoriAPI(app_name) as shikimori:
# Попытка получения данных текущего пользователя через /users/whoami
# При попытке доступа к защищенному методу, возвращает всегда None
user = await shikimori.users.current()
print(user)
# Получение достижений пользователя через /achievements
# и вывод первого достижения
# Можно получать достижения любого пользователя через ID
user_achievements = await shikimori.achievements.get(1)
if user_achievements:
print(user_achievements[0])
asyncio.run(main())
# >> None
# >> id=811883697
# >> neko_id='aa_megami_sama'
# >> level=0
# >> progress=31
# >> user_id=1
# >> created_at=datetime.datetime(...)
# >> updated_at=datetime.datetime(...)
# На самом деле достижение выводится как одна строка с данными.
# Для удобства она показана здесь раздельно
Выполнение нескольких запросов одновременно с помощью метода multiple_requests:
# В этом примере используется распаковка, но можно также получать весь массив с данными ответов
# в одной переменнной (chainsaw, lycoris_anime, ... -> data = await ...)
from shikithon import ShikimoriAPI
config = ...
shikimori = ShikimoriAPI(config)
await shikimori.open()
chainsaw, lycoris_anime, lycoris_ranobe = await shikimori.multiple_requests([
shikimori.animes.get_all(search="Бензопила"),
shikimori.animes.get_all(search="Ликорис"),
shikimori.ranobes.get_all(search="Ликорис")
])
print(chainsaw)
print(lycoris_anime)
print(lycoris_ranobe)
await shikimori.close()
# [Anime(id=44511, name='Chainsaw Man', russian='Человек-бензопила', ...]
# [Anime(id=50709, name='Lycoris Recoil', russian='Ликорис Рикоил', ...]
# [Ranobe(id=151431, name='Lycoris Recoil: Ordinary Days', russian='Ликорис Рикоил: Повседневность', ...]
# Также возможно использовать этот метод в "ограниченном режиме":
app_name = ...
async with ShikimoriAPI(app_name) as shikimori:
lycoris_ranobe = await shikimori.multiple_requests([
shikimori.ranobes.get_all(search="Ликорис")
])
print(lycoris_ranobe)
# [Ranobe(id=151431, name='Lycoris Recoil: Ordinary Days', russian='Ликорис Рикоил: Повседневность', ...]
Пара уточнений по использованию:
Возможно вам придется импортировать модели для ручной аннотации возвращаемых моделей в PyCharm (в нем немного некорретно работает наследование типа от функции)
Поле
scopes
является строкой и разделяется "+", если значений несколько.Пример:
user_rates+messages+comments+topics+...
При отсутствии каких-либо полей в данных конфигурации, библиотека выдает исключение
Если вы не хотите использовать логгирование библиотеки, передайте флаг logging=False в объект API.
Пример:
shikithon = await ShikimoriAPI(config, logging=False)
Получение данных для конфигурации
Для начала вам необходимо создать новое OAuth-приложение здесь
(После этого, сохраните app_name
, client_id
, client_secret
, а так же redirect_uri
)
Позже, на данной странице выберите свое приложение, необходимые разрешения
и получите код авторизации (После этого сохраните, scopes
и auth_code
)
Теперь ваш файл конфигурации готов!
На первой инициализации, библиотека создаст и сохранит собственный файл конфигурации для дальнейших запросов. Если токены станут недоступны, библиотека автоматически обновит токены и сохранненый файл конфигурации
Также возможно использование библиотеки в "ограниченном режиме", используя только имя приложения для доступа к публичным методам API.
В таком случае, вы должны только передать строку с app_name
для дальнейшей работы, как в примере выше.
Список изменений
Все изменения перечислены на странице релизов
Помощь проекту
Хотите внести вклад или оставить репорт о баге? Великолепно!
Для таких случаев, стоит почитать CONTRIBUTING.md
Зависимости проекта
Данный проект использует пять библиотек:
- aiohttp для асинхронных запросов к API (Лицензия)
- pydantic для валидации данных JSON и преобразования в модели (Лицензия)
- ratelimit для огранчений количества запросов к API (Лицензия)
- loguru для удобного логгирования (Лицензия)
- validators для проверки строк на наличие ссылки в ней (Лицензия)
В качестве зависимостей для разработки, проект использует четыре библиотеки:
- pylint для статической проверки кода (Лицензия)
- yapf для форматирования кода (Лицензия)
- isort для сортировки импортов (Лицензия)
- pre-commit для автоматизации проверки с использованием библиотек выше :) (Лицензия)
Лицензия проекта
Данный проект имеет MIT лицензию. Ознакомиться с ее содержанием можно здесь
Проект использует логотип сайта Shikimori для логотипа в этом README.md. Все права принадлежат правообладателям и используются по принципу fair use.
Благодарности
- shiki4py - взяты некоторые идеи по рефакторингу и добавлению поддержки асинхронных запросов (Лицензия)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for shikithon-2.0.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 12248b33b793e5aaf4d4421ebddbe83dc46ae03f5e6fb9c34678a73ae05e8d0f |
|
MD5 | c710f780403ffb89fda83f9633888448 |
|
BLAKE2b-256 | ee5623b004bb02851af6523098bc91ef50c478c389d6083c2e0cbb292c256781 |