Skip to main content

Yet another Python wrapper for Shikimori API

Project description

Shikithon Logo

Shikithon

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

Publish Shikithon package to PyPI

Состояние библиотеки: завершена основная разработка

На данный момент, библиотека находится в статусе поддержки (новые функции будут добавляться только по необходимости)

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

Описание

Данный враппер предоставляет базовую абстракцию, которая позволяет удобнее работать с методами 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_chisato, lycoris_ranobe = await shikimori.multiple_requests([
    shikimori.animes.get_all(search="Бензопила"),
    shikimori.characters.search("Тисато Нисикиги"),
    shikimori.ranobes.get_all(search="Ликорис"),
])
print(chainsaw)
print(lycoris_chisato[:1])
print(lycoris_ranobe)

await shikimori.close()

# [Anime(id=44511, name='Chainsaw Man', russian='Человек-бензопила', ...]
# [Character(id=204621, name='Chisato Nishikigi', 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 = ShikimoriAPI(config, logging=False)

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

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

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

Теперь ваш файл конфигурации готов!

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

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

В таком случае, вы должны только передать строку с app_name для дальнейшей работы, как в примере выше.

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

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

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

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

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

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

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

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

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

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

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

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

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shikithon-2.1.0.tar.gz (52.4 kB view hashes)

Uploaded Source

Built Distribution

shikithon-2.1.0-py3-none-any.whl (89.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page