что такое logging в aiogram
Урок 3. Машина состояний и то самое логгирование
Урок проводится с использованием aiogram версии 1.2
Сегодня мы научимся использовать:
Традиционно код урока доступен на GitHub
Создаем состояния
Так как мы сейчас будем разбирать машину состояний, эти самые состояния необходимо сначала создать. Сперва в голову приходит использование енумов, однако я предпочел воспользоваться встроенным классом Helper, который подходит для данной задачи даже лучше.
Итак, запишем в файл utils.py наш демонстрационный класс с состояниями:
Ещё не забываем добавить в config.py токен своего бота и мы готовы писать логику!
Указываем хранилище состояний и включаем логгирование
К привычным с прошлых уроков импортам у нас добавляется ещё парочка, а именно:
И тут же применяем их:
На первой строчке мы указали хранилище состояний в оперативной памяти, так как потеря этих состояний нам не страшна (да и этот вариант больше всего подходит для демонстрационных целей, так как не требует настройки). Однако если у вас от состояний что-то зависит, рекомендуется ипользовать более надеждное хранилище. На данный момент можно подключить Redis и RethinkDB.
Обрабатываем входящие сообщения
Итак, по традиции добавляем обработчики команд start и help :
А так же «ловим» все сообщения, отправленные при «нулевом» состоянии:
Переходим к главной теме нашего урока: состояниям
Эти самые состояния нужно как-то устанавливать, поэтому сделаем так:
Не забываем, что хэндлеры обрабатываются в порядке их расположения в коде, поэтому описанная выше функция должна идти раньше приведенных ниже обработчиков.
Теперь отрабатываем входящие сообщения при выбранном состоянии
Теперь добавим такой хэндлер:
Библиотека сама понимает, когда мы передаем список состояний, а когда только одно состояние и под капотом обрабатывает их по-разному, но нам нет смысла об этом задумываться. В этом плане мы в плюсе, так как можем сделать вот так:
Ну и последний на сегодня хэндлер:
Он принимает в себя сообщения при всех состояниях из возможных в этом уроке, однако так как состояния с первого по четвертый ловятся хэндлерами выше, в этот попадают только нулевое и пятое.
Для красоты ещё стоит закрывать соединение с хранилищем состояний, для этого объявляем функцию:
Знакомство с aiogram¶
Установка¶
Для начала давайте создадим каталог для бота, организуем там virtual environment (далее venv) и установим библиотеку aiogram.
Проверим, что установлен Python версии 3.7 (если вы знаете, что установлен 3.8 и выше, можете пропустить этот кусок):
В этой главе используется aiogram версии 2.9.2, но перед началом работы рекомендую заглянуть в канал релизов библиотеки и проверить наличие более новой версии. Подойдёт любая более новая, начинающаяся с цифры 2, поскольку в будущем ожидается релиз aiogram 3.0 с заметными изменениями и без обратной совместимости.
Чтобы избежать неприятностей, зафиксируемся на 2.9.2 и далее будем обновляться вручную.
Обратите внимание на префикс «venv» в терминале. Он указывает, что мы находимся в виртуальном окружении с именем «venv». Проверим, что внутри venv вызов команды python указывает на всё тот же Python 3.7:
Последней командой deactivate мы вышли из venv, чтобы он нам не мешал.
Первый бот¶
Давайте создадим файл bot.py с базовым шаблоном бота на aiogram:
Первое, на что нужно обратить внимание: aiogram — асинхронная библиотека, поэтому ваши функции тоже должны быть асинхронными, а перед вызовами методов API нужно ставить ключевое слово await, т.к. эти вызовы возвращают корутины.
Асинхронное программирование в Python
Не стоит пренебрегать официальной документацией!
Прекрасный туториал по asyncio доступен на сайте Python.
Если вы в прошлом работали с какой-то другой библиотекой для Telegram, например, pyTelegramBotAPI, то концепция хэндлеров (обработчиков событий) вам сразу станет понятна, разница лишь в том, что в aiogram хэндлерами управляет диспетчер.
Диспетчер регистрирует функции-обработчики, дополнительно ограничивая перечень вызывающих их событий через фильтры. После получения очередного апдейта (события от Telegram), диспетчер выберет нужную функцию обработки, подходящую по всем фильтрам, например, «обработка сообщений, являющихся изображениями, в чате с ID икс и с длиной подписи игрек». Если две функции имеют одинаковые по логике фильтры, то будет вызвана та, что зарегистрирована раньше.
Чтобы зарегистрировать функцию как обработчик сообщений, нужно сделать одно из двух действий:
1. Навесить на неё декоратор, как в примере выше. С различными типами декораторов мы познакомимся позднее. 2. Напрямую вызвать метод регистрации у диспетчера.
Рассмотрим следующий код:
Давайте запустим с ним бота:
Функция cmd_test2 не работает, т.к. диспетчер о ней не знает. Исправим эту ошибку и отдельно зарегистрируем функцию:
Снова запустим бота:
Обработка ошибок¶
Аналогично пишутся обработчики и на другие исключения. Таким образом, если одна и та же непредвиденная ситуация может возникнуть в различных хэндлерах, то можно вынести её обработку в отдельный хэндлер ошибок. Кода будет меньше, а оставшийся станет читабельнее.
Синтаксический сахар¶
Более того, для большинства типов сообщений есть вспомогательные методы вида «answer_
Всё хорошо, но если вдруг вы захотите поделиться с кем-то кодом, то придётся каждый раз помнить об удалении из исходников токена бота, иначе придётся его перевыпускать у @BotFather. Чтобы обезопасить себя, давайте перестанем указывать токен прямо в коде, а вынесем его как переменную окружения.
Замените следующие строчки из начала файла:
Запустите снова бота и убедитесь, что он работает. Получившийся код можно смело сохранять в PyCharm в File Templates.
На этом мы закончим знакомство с библиотекой, а в следующих главах рассмотрим другие «фишки» aiogram и Telegram Bot API.
aiogram-logging 0.0.1
pip install aiogram-logging Copy PIP instructions
Released: Mar 18, 2021
Simplifies sending logs from your bots to DB.
Navigation
Project links
Statistics
View statistics for this project via Libraries.io, or by using our public dataset on Google BigQuery
License: MIT License (MIT)
Requires: Python >=3.6
Maintainers
Classifiers
Project description
aiogram-logger
Simplifies sending logs from your bots to DB.
Quick start with InfluxDB + Grafana
Install package from pip
Prepare InlfuxDB and Grafana with this repo.
Import and create instances
Create StatMiddleware to logging every incoming message
Create dashboard by yourself or import from grafana-dashboard.json
Yeah, you can connect several bots for one InfluxDB
Project details
Project links
Statistics
View statistics for this project via Libraries.io, or by using our public dataset on Google BigQuery
License: MIT License (MIT)
Requires: Python >=3.6
Maintainers
Classifiers
Download files
Download the file for your platform. If you’re not sure which to choose, learn more about installing packages.
Урок 2. Медиа, разметка, эмоджи и щепотка логирования
В этом уроке мы научим нашего бота:
А также воспользуемся логированием, дабы посмотреть, что происходит под капотом.
Зачем хранить айди файлов, которые мы отправляем?
Ещё вам необходимо знать, что каждый бот видит разные айди у всех медиа файлов. По айди, который получил один бот, другой бот не сможет отправить ничего, а при попытке сделать это получит ошибку.
Наконец-то код!
Для начала создаем модель таблицы для нашей базы данных. Файл db_map.py:
Теперь загружаем в Телеграм файлы и сохраняем возвращаемые айди в базу данных. Для этого я написал небольшой скрипт, который доступен по ссылке. Если будете исполнять его на своём компьютере, можете обратить внимание на то самое логирование библиотеки aiogram.
Вот результат выполнения скрипта:
Создаем хэндлер команд /start и /help :
Затем добавляем обработчики всех остальных команд
О каждой по отдельности (за одно разберем эмоджи):
Отправка аудио + ответ на определенное сообщение:
Отправка фото с комментарием + эмоджи:
Отправка медиагруппы (где смешались кони, люди фото и видео):
Внимание! На момент публикации заметки при использовании релизной версии библиотеки невозможно отправить медиагруппу представленным выше способом из-за ошибки в коде. Недочёт исправлен в этом коммите. Версия 1.1, которая устанавливается через pip, уже несет в себе это исправление.
Отправка видеозаметки (видео в кружочке):
Отправка файла:
Преформатированный текст:
Так как разметка тут немного шалит, приложу ещё и скриншот кода с более понятной подсветкой синтаксиса: Тут мы отправляем преформатированный текст. Обычно такая разметка необходима при отправке блоков кода. По сути, это тот же моноширинный шрифт как и при использовании code (рассмотрим его ниже), однако pre работает для многострочных вставок и автоматически отделяется переносом строки до и после. В качестве примера отправим данную же функцию с её хэндлером. Получаем такой результат:
Ну и напоследок немного улучшим знания, полученные в предыдущем уроке и закрепим их на деле:
Оставим для нерадивого пользователя пару хэндлеров для нежданных сообщений:
Домашнее задание
В качестве домашнего задания предлагаю вам поэкспериментировать и выполнить следующие действия:
Шпаргалка по логированию на Python
Авторизуйтесь
Шпаргалка по логированию на Python
Если Вы хотя бы немного знакомы с программированием и пробовали запускать что-то «в продакшен», то вам наверняка станет больно от такого диалога:
— Вась, у нас там приложение слегло. Посмотри, что случилось?
— Эмм… А как я это сделаю.
Да, у Василия, судя по всему, не настроено логирование. И это ужасно, хотя бы по нескольким причинам:
Впрочем, последний пункт, наверно, лишний. Однако, одну вещь мы поняли наверняка:
Логирование — крайне важная штука в программировании.
Что такое logging?
Модуль logging в Python — это набор функций и классов, которые позволяют регистрировать события, происходящие во время работы кода. Этот модуль входит в стандартную библиотеку, поэтому для его использования достаточно написать лишь одну строку:
У функции basicConfig() 3 основных параметра:
Давайте рассмотрим каждый из параметров более подробно.
Уровни логирования на Python
Наверно, всем очевидно, что события, которые генерирует наш код кардинально могут отличаться между собой по степени важности. Одно дело отлавливать критические ошибки ( FatalError ), а другое — информационные сообщения (например, момент логина пользователя на сайте).
Соответственно, чтобы не засорять логи лишней информацией, в basicConfig() Вы можете указать минимальный уровень фиксируемых событий.
По умолчанию фиксируются только предупреждения ( WARNINGS ) и события с более высоким приоритетом: ошибки ( ERRORS ) и критические ошибки ( CRITICALS ).
Если Вы хотите посмотреть все сообщения, необходимо передать соответствующий уровень ошибок:
А далее, чтобы записать информационное сообщение (или вывести его в консоль, об этом поговорим чуть позже), достаточно написать такой код:
И так далее. Теперь давайте обсудим, куда наши сообщения попадают.
Отображение лога и запись в файл
Другими словами, если Вы просто выполните такой код:
То сообщение WOW придёт Вам в консоль. Понятно, что в консоли никому эти сообщения не нужны. Как же тогда направить запись лога в файл? Очень просто:
Ок, с записью в файл и выбором уровня логирования все более-менее понятно. А как настроить свой шаблон? Разберёмся.
Кстати, мы собрали для Вас сублимированную шпаргалку по логированию на Python в виде карточек. У нас ещё много полезностей, не пожалеете 🙂
Форматирование лога
Итак, последнее, с чем нам нужно разобраться — форматирование лога. Эта опция позволяет Вам дополнять лог полезной информацией — датой, названием файла с ошибкой, номером строки, названием метода и так далее.
Например, если внутри basicConfig указать:
То вывод ошибки будет выглядеть так:
Вы можете сами выбирать, какую информацию включить в лог, а какую оставить. По умолчанию формат такой:
Важно помнить, что все параметры logging.basicConfig должны передаваться до первого вызова функций логирования.
Эпилог
Вместо заключения просто оставим здесь рабочий кусочек кода, который можно использовать 🙂
Если хотите разобраться с параметрами более подробно, Вам поможет официальная документация (очень неплохая, кстати).