У каждого из нас есть однообразные задачи, которые мы выполняем изо дня в день, из недели в неделю. Составление отчетов, в большинстве случаев, является одной из таких задач. Вы запрашиваете данные, визуализируете их, а затем отправляете своему боссу. Но что вы скажете на то, чтобы автоматизировать весь этот скучный процесс и потратить свое драгоценное время для других вещей, вместо того, чтобы делать все это вручную?
Подготовка к работе
1. Установите библиотеки
Мы будем использовать google-cloud-bigquery для получения данных из Google BigQuery. matplotlib, numpy и pandas помогут нам с визуализацией данных. python-telegram-bot будет отправлять изображения с визуализацией в чат Telegram.
pip3 install google-cloud-bigquery matplotlib numpy pandas python-telegram-bot
2. Включите Google BigQuery API
Для начала нужно включить API Google BigQuery.
Перейдите в Google Developers Console и создайте новый проект (или выберите существующий).
В панели управления проектом выберите “Обзор API”, нажмите “Включить API и сервисы” и найдите BigQuery API.
![](https://cdn-images-1.medium.com/max/800/1*L-1tAU905-5SO-cQz9giIQ.png)
Нажмите “Включить”, чтобы включить данный API.
![](https://cdn-images-1.medium.com/max/800/1*nrq8lk3lR-BXzvSr1AnEgA.png)
3. Создайте ключ сервисного аккаунта
Если мы хотим использовать такие облачные сервисы Google, как Google BigQuery, нам нужен ключ сервисного аккаунта.
Перейдите в Google Developers Console, нажмите “Обзор API”, затем перейдите во вкладку “Учетные данные”, нажмите “Создать учетные данные” и “Ключ сервисного аккаунта”.
Во вкладке “Сервисный аккаунт” нажмите “Новый сервисный аккаунт” и введите имя в поле “Название сервисного аккаунта”.
Из выпадающего списка во вкладке “Роль” выберите вариант Проект-Владелец. Далее нажмите “Создать”.
![](https://cdn-images-1.medium.com/max/800/1*Y2yJZZCasDbtQ1ia7icaDA.png)
На ваш компьютер будет автоматически загружен .json файл. Назовите его creds.json
.
В терминале для GOOGLE_APPLICATION_CREDENTIALS
пропишите путь к нашему creds.json
файлу.
export GOOGLE_APPLICATION_CREDENTIALS='[PATH_TO_CREDS.JSON]'
Все готово, пора приступать к написанию нашего приложения.
Написание приложения
Мы собираемся написать приложение, которое будет запрашивать данные из BigQuery (в данном примере мы предполагаем, что данные хранятся там). Далее мы визуализируем данные и сохраним их в виде изображения. На последнем этапе изображение будет отправлено через чат в Telegram.
В этой статье мы воспользуемся данными из bigquery-public-data.stackoverflow
и установим количество ежедневных публикаций для нашего отчета.
Последовательность действий нашей программы довольно проста:
Запрашиваем данные из таблицы-> Визуализируем данные-> Сохраняем визуализированные данные в виде изображения -> Отправляем изображение
1. Query к BigQuery
Сначала импортируем библиотеку.
from google.cloud import bigquery
Затем создадим функцию query_to_bigquery
, которая будет использовать query
в качестве параметра.
def query_to_bigquery(query):
client = bigquery.Client()
query_job = client.query(query)
result = query_job.result()
dataframe = result.to_dataframe()
return dataframe
Эта функция вернет данные в виде датафрейма.
2. Визуализируем данные
Мы будем использовать matplotlib для визуализации данных.
import matplotlib.pyplot as plt
Нам нужно пять параметров: x
— данные по оси х, x_label
— имя метки по оси x, y
— данные по оси y, y_label
— имя метки по оси y и title
— заголовок визуализации.
def visualize_bar_chart(x, x_label, y, y_label, title):
plt.title(title)
plt.xlabel(x_label)
plt.ylabel(y_label)
index = np.arange(len(x))
plt.xticks(index, x, fontsize=5, rotation=30)
plt.bar(index, y)
return plt
3. Сохраняем изображение
Давайте воспользуемся вышеприведенными функциями, чтобы создать визуализацию, а затем сохранить ее в виде изображения.
Как я упоминал ранее, мы хотим отправлять определенное число постов ежедневно. Для начала напишите запрос.
query = """
SELECT DATE(creation_date) date, COUNT(*) total_posts
FROM `bigquery-public-data.stackoverflow.post_history`
GROUP BY 1
HAVING date > DATE_SUB('2018-12-02', INTERVAL 14 DAY)
ORDER BY 1
"""
Обратите внимание, что в приведенном выше запросе HAVING date > DATE_SUB('2018-12-02', INTERVAL 14 DAY)
означает, что мы хотим собрать данные за две недели, начиная со 2 декабря 2018 года.
Мы используем эту дату, потому что 2018-12-02
— это последние данные, записанные в bigquery-public-data.stackoverflow.post_history
. В других случаях вы можете использовать CURRENT_DATE()
, чтобы получить новейшие данные.
Вызовите функцию query_to_bigquery
для получения данных.
dataframe = query_to_bigquery(query)
Возьмите столбец date
в качестве данных по оси x, и столбец total_posts
в качестве данных по оси y.
x = dataframe['date'].tolist()
y = dataframe['total_posts'].tolist()
Визуализируйте данные с помощью функции visualize_bar_chart
, а затем сохраните их в виде изображения.
plt = visualize_bar_chart(x=x, x_label='Date', y=y, y_label='Total Posts', title='Daily Posts')
plt.savefig('viz.png')
Оберните этот код в функцию get_and_save_image
.
def get_and_save_image():
query = """
SELECT DATE(creation_date) date, COUNT(*) total_posts
FROM `bigquery-public-data.stackoverflow.post_history`
GROUP BY 1
HAVING date > DATE_SUB('2018-12-02', INTERVAL 14 DAY)
ORDER BY 1
"""
dataframe = query_to_bigquery(query)
x = dataframe['date'].tolist()
y = dataframe['total_posts'].tolist()
plt = visualize_bar_chart(x=x, x_label='Date', y=y, y_label='Total Posts', title='Daily Posts')
plt.savefig('viz.png')
4. Отправляем изображение
Чтобы убедиться, что изображение попадет к тому, кому нужно, нам необходимо знать параметр chat_id
.
Найдите в Telegram бот userinfobot и нажмите “Start”. Бот пришлет информацию о пользователе, где номер в поле Id
— это и есть chat_id
.
Создайте функцию send_image
. Сначала данная функция вызовет функцию get_and_save_image
, чтобы получить и сохранить визуализацию, а затем отправит ее человеку, чей chat_id объявлен в переменной chat_id
.
def send_image(bot, update):
get_and_save_image()
chat_id = 'CHAT_ID_RECEIVER'
bot.send_photo(chat_id=chat_id, photo=open('viz.png','rb'))
5. Основное приложение
Наконец, создайте функцию main
для запуска нашего приложения. Не забудьте изменить YOUR_TOKEN
для токена вашего бота.
Запомните: это приложение будет автоматически отправлять изображения в указанное вами время.
Например, мы установили время на 9:00 ежедневно.
def main(): updater = Updater('YOUR_TOKEN') updater.job_queue.run_daily(send_image, time=datetime.datetime.strptime('9:00AM', '%I:%M%p').time(), days=(0,1,2,3,4,5,6)) updater.start_polling() updater.idle() if __name__ == '__main__': main()
В итоге ваш код должен выглядеть так:
from google.cloud import bigquery
from telegram.ext import Updater
import matplotlib.pyplot as plt
import numpy as np
import datetime
def query_to_bigquery(query):
client = bigquery.Client()
query_job = client.query(query)
result = query_job.result()
dataframe = result.to_dataframe()
return dataframe
def visualize_bar_chart(x, x_label, y, y_label, title):
plt.title(title)
plt.xlabel(x_label)
plt.ylabel(y_label)
index = np.arange(len(x))
plt.xticks(index, x, fontsize=5, rotation=30)
plt.bar(index, y)
return plt
def get_and_save_image():
query = """
SELECT DATE(creation_date) date, COUNT(*) total_posts
FROM `bigquery-public-data.stackoverflow.post_history`
GROUP BY 1
HAVING date > DATE_SUB('2018-12-02', INTERVAL 14 DAY)
ORDER BY 1
"""
dataframe = query_to_bigquery(query)
x = dataframe['date'].tolist()
y = dataframe['total_posts'].tolist()
plt = visualize_bar_chart(x=x, x_label='Date', y=y, y_label='Total Posts', title='Daily Posts')
plt.savefig('viz.png')
def send_image(bot, update):
get_and_save_image()
chat_id = 'CHAT_ID_RECEIVER'
bot.send_photo(chat_id=chat_id, photo=open('viz.png', 'rb'))
def main():
updater = Updater('YOUR_TOKEN')
updater.job_queue.run_daily(send_image, time=datetime.datetime.strptime('9:00AM', '%I:%M%p').time(), days=(0,1,2,3,4,5,6))
updater.start_polling()
updater.idle()
if __name__ == '__main__':
main()
Сохраните файл и назовите его main.py
.
Запустите приложение, введя в терминале команду:
python3 main.py
Замечательно! Теперь у вас есть бот, автоматически генерирующий отчеты, созданный с помощью 50 строчек кода. Довольно круто, не правда ли?
Зайдите сюда, чтобы проверить бот. Введите команду /send
, чтобы увидеть пример визуализации изображения.
На изображении ниже продемонстрирован пример визуализации, которую будет отправлять бот. Теперь вы можете расслабиться и ничего не делать, потому что бот будет выполнять всю работу за вас 🙂
![](https://cdn-images-1.medium.com/max/800/1*fG34xiHEQXck40BgDeeeog.jpeg)
Вы можете посетить мой GitHub, чтобы получить готовый код.
Перевод статьи Dzaky Widya Putra: How to build a bot to automate your mindless tasks using Python and Google BigQuery