Apprise: делаем уведомления в Telegram и на почту в DL-проектах
Введение
Когда мы обрабатываем большие данные или обучаем модели, мы хотим знать, а что с ними вообще происходит. Ранее мы рассказывали, как можно мониторить эти процессы с помощью tensorboard и clearml (про него было целых две статьи). Однако часто нам не хочется тратить время на постоянный скроллинг дашбордов. В этом случае на помощь приходят уведомления! Например, уведомление о том, что какой-то этап пайплайна завершился (или упал). А ещё — о том, что обученная на новых данных модель показывает плохие результаты.
Есть очень много библиотек, которые позволяют отправлять уведомления в тот или иной мессенджер, на почту или через смс, и сегодня мы познакомимся с одним из них.
Apprise — это библиотека, которая поможет отправить вам уведомление (почти) куда угодно! 😎
Предварительная настройка
Установка
Нужно выполнить одну команду — pip install apprise
.
Основной объект данной библиотеки — Apprise
.
ap_obj = apprise.Apprise()
Для начала нам нужно определиться, куда и кому мы будем отправлять уведомления. Apprise поддерживает разные способы отправки уведомлений: Discord, Email, Telegram, WhatsApp, Mattermost, Slack и еще более 100 сервисов.
Мы сегодня остановимся на двух популярных способах — Telegram и Email (Gmail).
Предварительная настройка Gmail
💡 Отметим: пользователи с выключенной двухфакторной аутентификацией эти пункты могут пропустить.
Чтобы использовать уведомления через Gmail, нужно создать пароль приложения:
- Заходим в гугл-аккаунт;
- Переходим по ссылке;
- Вводим название приложения — оно может быть любым, но лучше выбирать осмысленное название, чтобы не запутаться 🙂;
- Нажимаем «Создать» и копируем полученный пароль.
Предварительная настройка Telegram
Уведомления в Telegram может отправлять только бот, которого нужно предварительно создать.
Что мы для этого делаем?
- Заходим в Telegram;
- Ищем бота https://t.me/BotFather;
- Вводим
/start
; - Вводим
/newbot
; - Вводим название бота;
- Получаем ссылку на бота и токен.
Чтобы бот начал отправлять вам сообщения, нужно инициировать диалог с ним. Это можно сделать, отправив ему любое сообщение.
💡 Также далее нам понадобится ваш внутренний ID. Узнать его можно через бота https://t.me/RawDataBot. Если написать ему /start
— он пришлёт json, где на позиции json["message"]["from"]["id"
] будет находится ваш ID.
Для добавления сервиса отправки уведомлений нужно сначала создать строку с параметрами и настройкой сервера.
Для Gmail она будет выглядеть таким образом: password_gmail
. Это пароль приложения из пункта «Предварительная настройка Gmai». Он выглядит примерно так — aaaa bbbb cccc ddd
:
gmail_string = f"mailto://{user_gmail}:{password_gmail}@gmail.com/to=target@ex.com/target2@ex.com"
Сначала идёт информация о том, что мы используем электронную почту mailto://
, далее — передаём логин, пароль и получателей сообщений, перечисленных через /
, как в примере выше: /to=target@ex.com/target2@ex.com
(можно отправлять сообщения в том числе на почту, которая использовалась для создания приложения в Google).
Аналогично для Telegram — маркер tgram://
, токен и ID получателей, перечисленные через /
.
tg_string = f"tgram://{tg_token}/{id_1}/{id_2}"
Затем полученные строки нужно добавить в Apprise
с помощью функции ap_obj.add
.
ap_obj.add(gmail_string)
ap_obj.add(tg_string)
Теги
Одна из самых крутых фичей Apprise
— система тегов.
💡 Теги — строки для гибкой настройки, кому и куда нужно будет отправлять уведомления.
Предположим, что у нас есть три группы пользователей — разработчики (dev), лиды (lead) и девопсы (devops). Лиды чаще читают электронную почту, а разработчики и девопсы считают этот способ устаревшим. Следовательно, мы хотим использовать разные сервисы отправки уведомлений для каждой группы.
В таком случае мы создаём 3 строки с разными группами пользователей:
lead_group_s = f"mailto://{user_gmail}:{password_gmail}@gmail.com/to=lead1@g.ru/lead2@g.ru"
dev_group_s = f"tgram://{tg_token}/{dev1_id}/{dev2_id}"
devops_group_s = f"tgram://{tg_token}/{devops1_id}/{devops2_id}"
Далее мы добавляем их в Apprise
с указанием тегов (одной строке можно назначить больше одного тега и наоборот):
ap_obj.add(lead_group_s, tag=['lead'])
ap_obj.add(dev_group_s, tag=['dev'])
ap_obj.add(devops_group_s, tag=['devops'])
Теперь при отправке уведомлений можно будет выбрать, каким пользователям и куда придёт то или иное сообщение!
Отправка сообщений
Отправка сообщений происходит просто: единственный обязательный аргумент здесь — текст уведомления (body_text).
ap_obj.notify(
body=body_text,
)
Это сообщение отправится абсолютно всем, поскольку мы не указали теги. Но если мы, например, хотим отправить сообщения всем девопсам и разрабам, то сделаем это так:
ap_obj.notify(
body="Прод упал из-за кота",
tags=['devops', 'dev']
)
Дополнительно можно добавить заголовок сообщения (в Telegram это будет отображаться просто как жирный шрифт над телом сообщения):
ap_obj.notify(
body="Прод упал из-за кота",
title='ВСЕ ОЧЕНЬ ПЛОХО!',
tags=['devops', 'dev']
)
Иногда нам хочется добавить к сообщению какой-либо файл. Для этого мы используем AppriseAttachment
. В объект нужно передать пути до нужных файлов:
ap_obj.notify(
body="Прод упал из-за кота",
title='ВСЕ ОЧЕНЬ ПЛОХО!',
attach=AppriseAttachment(paths=['кот.jpeg', 'log.txt']),
tags=['devops', 'dev']
)
Финальный пример
В этом примере мы покажем, как всё выглядит в собранном виде. Давайте рассмотрим некий абстрактный пайплайн. После его завершения уведомление отправится всем сотрудникам. В случае, если Accuracy
будет менее
💡 Отметим: мы настоятельно не рекомендуем хранить пароли и токены в открытом виде. Лучше это делать, как минимум, используя переменные окружения.
Код для config.py, где мы создаём переменные для юзернеймов, паролей и токенов, а также списки id и email’ов:
user_gmail = 'username'
password_gmail = 'ffrr dddd ssss qqqq'
tg_token = "1111111111:AAAaa1aaAaa1aaaa_aaaaa1aaaa1aaaaaaa"
developers_emails = ["dev1@example.com", "dev2@example.com"]
managers_telegram_ids = ["1234", "112333"]
Код для main-файла, в котором мы реализуем основную логику:
import apprise
from apprise import NotifyType, AppriseAttachment, NotifyFormat
from config import user_gmail, password_gmail, tg_token, developers_emails, managers_telegram_ids, accuracy_threshold
from pipeline import run_pipeline
apobj = apprise.Apprise()
gmail_string_for_developers = f"mailto://{user_gmail}:{password_gmail}@gmail.com/to={'/'.join(developers_emails)}"
apobj.add(gmail_string_for_developers, tag='developers')
apobj.add(f"tgram://{tg_token}/{'/'.join(managers_telegram_ids)}", tag=["managers"])
result_of_pipeline = run_pipeline()
apobj.notify(
body='Пайплайн завершен',
title='Статус пайплайна', notify_type=NotifyType.INFO,
body_format=NotifyFormat.TEXT,
tag='all'
)
if result_of_pipeline["Accuracy"] < accuracy_threshold:
apobj.notify(
body='Слишком низкая точность модели!',
title='Качество модели низкое', notify_type=NotifyType.WARNING,
body_format=NotifyFormat.TEXT,
tag='managers'
)
if result_of_pipeline["list_of_error_files"]:
apobj.notify(
body='Ошибка - смотри лог!',
title='Статус пайплайна', notify_type=NotifyType.FAILURE,
attach=AppriseAttachment(paths=['error.log']),
body_format=NotifyFormat.TEXT,
tag='developers'
)
Заключение
Сегодня мы рассмотрели лишь часть возможностей Apprise
. На самом деле их, конечно, гораздо больше. В заключение перечислим ещё некоторые бонусы (и оставим ссылочки на полезные ресурсы для знакомства с ними):
- 100+ способов отправки уведомлений;
- Отправка через CLI;
- Создание своих плагинов;
- Типы уведомлений;
- Кастомизация уведомлений.);
- Конфигурация через файл.
Мы видим, что Apprise предоставляет широкие возможности для отправки и настройки уведомлений. В этой статье мы коснулись его основных аспектов, но вы всегда можете углубиться в документацию и найти ещё больше интересных кейсов для применения 😊