← все ключи

Библиотека monokeys

Клиент одним файлом, без зависимостей. Ставить не обязательно: ключ работает и обычной ссылкой.

Поставить

pip install monokeys

Или тем же файлом, без установки: curl https://monoblock.casa/keys/sdk/python > monokeys.py

Ключ доступа

Ключ выдаёт владелец сервиса. Он бессрочный и без счётчика: сколько запросов сделать — ваше дело, никто их не считает. Единственное, что может случиться, — владелец отзовёт конкретный ключ, если тот начнёт вредить. Без ключа всё тоже работает, но как проба.

# .env
KEYS_API_KEY=kx_…

Три способа позвать

from monokeys import Keys

k = Keys()

k.alive("@durov")                  # весь ответ: объект с полями
k.alive.members_count("@durov")    # только одно поле, уже числом
k.alive.text("@durov")             # строка для человека

Аргументы подключения

аргументпо умолчаниючто делает
tokenKEYS_API_KEY, иначе публичныйключ доступа; передаётся только заголовком
baseадрес, откуда скачан клиентадрес сервера
timeout20.0сколько ждать ответа, секунд
retries1повторов при обрыве связи (отказ сервера не повторяется)
user_agentmonokeys/<версия>как представляться серверу
k = Keys(token="kx_…", base="https://monoblock.casa/keys", timeout=5, retries=2)

Аргументы вызова

аргументпо умолчаниючто делает
value—главное значение: ссылка для alive, вопрос для answer
only""вернуть только эти поля; несколько — через запятую
fmt"json"json — поля, text — строка для человека, bool — да/нет
timeoutкак у клиентапереопределить ожидание для одного вызова
**params—остальные параметры ключа по именам
k.alive("@durov", only="members_count")   # 11005185
k.alive("@durov", fmt="bool")             # 'true'
k.alive("@durov", timeout=3)              # не ждать дольше трёх секунд

Аргументы отдельных ключей

ключаргументчто делает
answersourcesкакие источники спрашивать; несколько — через запятую, пусто — ключ выберет сам
answerlangязык источника: ru или en
cryptovsв каких валютах показать цену, через запятую
timetoвторое место: во сколько это будет там
timeatчас по первому месту; пусто — прямо сейчас
weatherwhenсегодня, завтра, послезавтра или число дней вперёд
weatherdaysсколько дней прогноза вернуть, от 1 до 7
weatherunitsc — Цельсий, f — Фаренгейт
readlimitобрезать текст до стольких знаков; пусто — весь
k.answer('Хайфа', sources='osm,wikidata')   # оба ответа, а не один
k.crypto('bitcoin', vs='usd,ils')

k.time('Хайфа', to='Нью-Йорк', at='15:00')  # созвон в три — во сколько у них
k.weather('Берлин', when='завтра')          # и надо ли брать зонт

k.read('https://peps.python.org/pep-0008/').text    # статья без разметки
k.url('bit.ly/3xYz').url                            # куда ведёт на самом деле

k.alive('@durov', only='title,members_count')   # несколько полей сразу

Ключи можно исполнять у себя

Ключ — это код, а не услуга. Тот же самый код лежит в пакете: запрос уйдёт к источнику с вашей машины, нас в цепочке не будет. Быстрее, приватнее и не ломается, когда ломаемся мы.

from monokeys import Local

k = Local()                       # нашего сервера в цепочке нет
k.weather('Берлин').description   # 'пасмурно'
k.read('https://example.com/x').text
вызовчто делает
Local()все ключи, исполняемые здесь; ни адреса, ни ключа доступа
AsyncLocal()то же самое через await, для асинхронного кода
k.names()какие ключи есть
k.describe(имя)манифест ключа целиком

Работает без сети

Таймеры считаются у вас: обычный файл sqlite рядом с ботом. Ни ключа, ни запросов, ни ограничений — и наша доступность не становится правильностью вашего бота.

from monokeys import Timers

t = Timers('bans.db')                       # свой файл, без сети и ключа
t.set(f'unmute:{chat}:{user}', '30m', note='флуд')

async for сработал in t.stream():           # ждёт само
    await bot.restrict_chat_member(...)
вызовчто делает
Timers(path)хранилище таймеров в файле sqlite; сети и ключа не нужно
t.set(id, when, note)поставить; тот же id переставляет, а не задваивает
t.due()что созрело; отдаётся один раз
t.peek()то же, но не забирая
t.pending()кто ещё ждёт и сколько ему осталось
t.cancel(id)снять досрочно
t.stream()async for: ждёт само, цикл опроса писать не нужно
t.wait(id)дождаться одного конкретного

Что можно спросить у клиента

вызовчто вернёт
k.names()имена всех доступных ключей
k.fields("alive")какие поля возвращает ключ
k.alive.fields()то же самое, короче
k.catalog(refresh=True)полный каталог с описаниями, спросить заново
k.call("alive", "@durov")позвать ключ, имя которого известно только в рантайме

Ответ

Ответ — это словарь, который умеет отвечать и как объект. Опечатка в имени поля не молчит, а показывает список настоящих полей.

res = k.alive("@durov")
res.title == res["title"]   # одно и то же
bool(res)                    # True, если ключ ответил утвердительно

Ошибки

исключениекогда
AccessDeniedключ неизвестен, отозван или отправлен не по HTTPS
Unavailableсервер занят или источник не ответил — осмысленно повторить
KeysErrorвсё остальное: нет такого ключа, мусор на входе

У всех есть .status и .body. Первые две — потомки KeysError, ловятся одним except.

Методы не зашиты в клиент

Список ключей и их полей приходит с сервера, поэтому новый ключ доступен сразу, без обновления пакета.

Ещё 13 сервисов на Monoblock →