Skip to main content

monokeys

Клиент «Ключей» — маленьких умных функций, которые зовутся одним вызовом. Внутри только стандартная библиотека: зависимостей нет, один файл.

pip install monokeys
from monokeys import Keys

k = Keys()                                    # настраивать нечего

print(k.alive.text("@durov"))
# жив · channel · Pavel Durov · 10 998 851 subscribers

print(k.answer.text("погода в Хайфе"))
# Хайфе: 28.9°C, ветер 2.6 м/с, влажность 58% · источник: weather

Ни регистрации, ни ключа доступа, ни лимита: клиент сам берёт публичный ключ, а он бессрочный и без счётчика.

alive — жив ли канал Telegram

Без аккаунта, без Bot API, без токена: читается публичная превью-страница t.me, та самая, по которой мессенджеры рисуют картинку ссылки.

k.alive("@durov")                  # весь ответ объектом
k.alive.members_count("@durov")    # 11005185 — только число, уже числом
k.alive.kind("ru_python")          # group
k.alive.verified("@BotFather")     # True

Понимает любую форму ссылки: @durov, t.me/durov, t.me/durov/123, t.me/s/durov, t.me/+AbCdEf…, t.me/joinchat/…, DUROV.

Поля ответа: is_alive, kind (channel / group / bot / user), title, description, members_count, members_label, online_count, verified, is_private, needs_request, restricted, has_preview, avatar_url, deep_link, action, username, url, error.

Тонкость, из-за которой наивная проверка врёт: на удалённый канал Telegram отвечает 200 и рисует заглушку. Живой от мёртвого отличается разметкой, а не кодом ответа.

answer — ответ из многих источников разом

k.answer.text("кто такой Павел Дуров")
# Па́вел Вале́рьевич Ду́ров — российский и эмиратский предприниматель… · источник: wiki

k.answer.text("погода в Хайфе")     # Хайфе: 28.9°C, ветер 2.6 м/с · источник: weather
k.answer.text("курс доллара к шекелю")  # 1 USD = 2.9728 ILS (ЕЦБ) · источник: rates
k.answer("Хайфа", sources="osm,wiki")   # только карта и Википедия

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

Тринадцать источников, ни одного платного ключа: Википедия, Викиданные, Викисловарь, DuckDuckGo, OpenStreetMap, Open-Meteo, курсы ЕЦБ, Crossref, arXiv, Open Library, PyPI, npm, GitHub.

Чего тут нет намеренно: моделей — все бесплатные упираются в лимит, а их ответ нечем проверить; и выдачи поисковиков — её нельзя брать по их правилам, а IP у сервера один на все продукты.

Спросить именно тот источник, который нужен

Каждый источник — отдельный метод. Одно и то же слово, разные ответы:

k.answer.weather("Хайфа")   # Хайфа: 27.7°C, ветер 6.5 м/с, влажность 65%
k.answer.osm("Хайфа")       # Хайфа, נפת חיפה, Хайфский округ, Израиль
k.answer.wiki("Хайфа")      # Ха́йфа — третий по величине город Израиля…
k.answer.wikidata("Хайфа")  # Хайфа — город на севере Израиля
k.answer.rates("доллар к шекелю")   # 1 USD = 2.9728 ILS (ЕЦБ)
k.answer.github("telegram")         # DrKLO/Telegram ★29798

То же самое ссылкой: ?only=weather или ?sources=weather.

Просить поле источника — это и значит спросить сам источник: слова «погода» в вопросе может не быть, а погоду вы всё равно хотите.

Три способа позвать любой ключ

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

Аргументы

Keys(...) — подключение

Аргумент По умолчанию Что делает
token KEYS_API_KEY, иначе публичный ключ с сервера ключ доступа; передаётся только заголовком
base https://monoblock.casa/keys адрес сервера
timeout 20.0 сколько ждать ответа, секунд
retries 1 повторов при обрыве связи (отказ сервера не повторяется)
user_agent monokeys/<версия> как представляться серверу
k = Keys(timeout=5, retries=2)

k.<ключ>(...) — вызов

Аргумент По умолчанию Что делает
value — главное значение: ссылка или @username
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)              # не ждать дольше трёх секунд

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

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

Ответ

Answer — это словарь, который умеет отвечать и как объект:

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

Опечатка не молчит:

res.tittle
# AttributeError: в ответе нет поля 'tittle'; есть: username, url, is_alive, ...

k.alive.members_cout("@durov")
# AttributeError: у ключа 'alive' нет поля 'members_cout'; есть: is_alive, kind, ...

Ошибки

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

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

from monokeys import Keys, AccessDenied, Unavailable

try:
    res = k.alive("@durov")
except AccessDenied:
    print("ключ доступа не подошёл")
except Unavailable:
    print("сейчас занято, попробую позже")

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

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

k.names()          # ['alive', 'answer']
k.несуществующий   # AttributeError со списком существующих

Ключ доступа

Заводить не нужно — публичный работает у всех и без счётчика. Свой нужен только тем, кому нужен собственный рубильник; его выдаёт владелец сервиса, и он тоже бессрочный. Положите в .env:

KEYS_API_KEY=kx_...

Отозвать свой ключ, если он утёк:

curl -X POST -H "Authorization: Bearer kx_..." https://monoblock.casa/keys/token/revoke

Если ставить пакет не хочется

Тот же самый файл можно просто скачать — из него и собран пакет:

curl https://monoblock.casa/keys/sdk/python > monokeys.py

А можно вообще без клиента — ключ это обычная ссылка:

https://monoblock.casa/keys/alive/@durov  ->  жив · channel · Pavel Durov · …

Документация целиком: https://monoblock.casa/keys/client

Исходники: https://github.com/monorez3/keys

Metadata

Release files for monokeys 0.2.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for monokeys 0.2.5
File Size Uploaded
monokeys-0.2.5.tar.gz 9.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for monokeys 0.2.5
File Interpreter ABI Platform
monokeys-0.2.5-py3-none-any.whl Python 3 none any Details

Total release size: 19.5 kB

Release files / monokeys-0.2.5.tar.gz

Download URL monokeys-0.2.5.tar.gz
Size 9.2 kB
Tags Source
SHA-256 checksum
How to use checksums
c2343faee35647009ffd1155a9764fdaf23799d853a8f4d34648e47de98d7fd4
BLAKE2b-256 checksum
How to use checksums
c87f2fc923b0d3d0b53fa2c9772c8501b0fa7bd33dc6808fef944d089cd08f5b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release files / monokeys-0.2.5-py3-none-any.whl

Download URL monokeys-0.2.5-py3-none-any.whl
Size 10.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
47d7c4ebe1006f75dc9672ada4c0661c34d98bc999b807d78d529e97ca9e50e1
BLAKE2b-256 checksum
How to use checksums
f01c748aab54efc6c67e0ba55f85cddf6a69f1d8b71d845cd08dfc0258ebce45
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release history Release notifications | RSS feed

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

This release

0.2.5 This release

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page