Skip to content
This repository has been archived by the owner on Sep 25, 2024. It is now read-only.

SecondThundeR/shikithon

Repository files navigation

Caution

Состояние библиотеки: прекращена поддержка библиотеки

В связи с моим полным переходом на веб-разработку и TypeScript вместо Python, поддерживать эту библиотеку больше нет возможности. Если что-то необходимо исправить -> Just make a fork

Shikithon Logo

Shikithon

Очередной враппер для Shikimori API, написанный на Python

Publish Shikithon package to PyPI

Tip

Начиная с версии 2.0.0, библиотека поддерживает асинхронные запросы, отдельные пути к ресурсам API и многое другое (Инструкция по миграции с версии 1.x.x)

Описание

Данный враппер предоставляет абстракцию, которая позволяет удобнее работать с методами API и их ответами

Для каждого эндпоинта API существует свой объект с методами, и все данные, возвращаемые API Shikimori, валидируются и парсятся в модели, со всеми необходимыми полями, а также дополнительными, которые могут вернуть некоторые методы API (Например /users/whoami и /users/:id/info возвращают разные поля). Это позволяет не задумываться об обработке очередного ответа от сервера и сосредоточиться над реализацией своей идеи

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

Note

Данная библиотека начинает свою поддержку с Python 3.8.10.

Установка

pip install shikithon

# или используя Poetry
poetry add shikithon

Пример использования

import asyncio

from typing import Dict

from json import loads

from shikithon import ShikimoriAPI, JSONStore

# При необходимости, можно также
# экспортировать енамы для использования в методах
from shikithon.enums import AnimeOrder, MangaKind, ...

# Можно установить данные конфигурации в коде
config = {
    "app_name": "...",
    "client_id": "...",
    "client_secret": "...",
    "auth_code": "...",
    # Необязательно
    "access_token": "...",
    "refresh_token": "..."
}

# Или же прочитать его из внешнего файла
with open("config.json", "r", encoding="utf-8") as config_file:
    config_2: Dict[str, str] = loads(config_file.read())

# Инициализируем API объект с необходимыми опциями
# В данном примере используется JSONStore и отключено логирование
api = ShikimoriAPI(app_name=config['app_name'], store=JSONStore())

async def main():
    # Используем объект без авторизации
    async with api:
        lycoris = await api.animes.get(50709)
        print(lycoris)
        # >> id=50709 name='Lycoris Recoil' russian='Ликорис Рикоил' ...

        # Важно отметить, что внутри нельзя вкладывать async with api.auth(...)

    # Используем объект с авторизацией
    # Вариант 1
    async with api.auth(
        client_id=config["client_id"],
        client_secret=config["client_secret"],
        auth_code=config["auth_code"],
    ):
        print(await api.users.current())
        # >> id=723052, nickname='SecondThundeR', ...

    # Вариант 2

    # Создаем новый объект API
    # (По умолчанию используется NullStore в качестве хранилища)
    api_2 = ShikimoriAPI(app_name="...")

    # В данном случае app_name в __init__ не будет перезаписан,
    # а токен будет обновлен при ошибке 401
    api_auth_maker = api_2.auth(
        app_name=config['app_name'],
        client_id=config['client_id'],
        client_secret=config['client_secret'],
        access_token=config['access_token'],
        refresh_token=config['refresh_token']
    )

    # Далее созданный объект можно использовать сколько угодно раз
    async with api_auth_maker:
        ...

asyncio.run(main())

Выполнение нескольких запросов одновременно с помощью метода multiple_requests:

# В этом примере используется распаковка, но можно также получать весь массив с данными ответов
# в одной переменнной (chainsaw, lycoris_anime, ... -> data = await ...)
from shikithon import ShikimoriAPI, JSONStore

config = ...

api = ShikimoriAPI(app_name=config['app_name'], store=JSONStore(), logging=False)

async def main():
    async with api:
        chainsaw, lycoris_chisato, lycoris_ranobe = await api.multiple_requests([
            api.animes.get_all(search="Бензопила"),
            api.characters.search("Тисато Нисикиги"),
            api.ranobes.get_all(search="Ликорис"),
        ])
        print(chainsaw)
        print(lycoris_chisato[:1])
        print(lycoris_ranobe)

# [AnimeInfo(id=44511, name='Chainsaw Man', russian='Человек-бензопила', ...]
# [CharacterInfo(id=204621, name='Chisato Nishikigi', russian='Тисато Нисикиги', ...]
# [RanobeInfo(id=151431, name='Lycoris Recoil: Ordinary Days', russian='Ликорис Рикоил: Повседневность', ...]

Также, если хочется узнать как использовать встроенные хранилища конфигов или хочется создать свой, посмотрите этот гайд

Пара уточнений по использованию

  • Возможно вам придется импортировать модели для ручной аннотации возвращаемых моделей в PyCharm (в нем немного некорретно работает наследование типа от функции)
  • При отсутствии каких-либо полей в данных конфигурации, библиотека выдает исключение
  • Если вы хотите использовать логгирование библиотеки, передайте флаг logging=True в объект API: api = ShikimoriAPI(app_name="...", logging=True)

Получение данных для конфигурации

Для начала вам необходимо создать новое OAuth-приложение здесь. После этого, сохраните app_name, client_id, client_secret, а так же redirect_uri, если вы его меняли

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

Список изменений

Все изменения перечислены на странице релизов

Помощь проекту

Хотите внести вклад или оставить репорт о баге? Великолепно!

Для таких случаев, стоит почитать CONTRIBUTING.md

Зависимости проекта

Данный проект использует семь библиотек:

Также, данный проект использует две библиотеки в качестве зависимостей для разработки:

Лицензия проекта

Данный проект имеет MIT лицензию. Ознакомиться с ее содержанием можно здесь

Проект использует логотип сайта Shikimori для логотипа в этом README.md. Все права принадлежат правообладателям и используются по принципу fair use

Благодарности

  • shiki4py - взяты некоторые идеи по рефакторингу и добавлению поддержки асинхронных запросов (Лицензия)