Як дэлегаваць простыя справаздачы робату. Пішам бота на Python і Google BigQuery

Як дэлегаваць простыя справаздачы робату. Пішам бота на Python і Google BigQuery

Ці ёсць у вас задачы, якія паўтараюцца дзень пры дні, з тыдня ў тыдзень? Напрыклад, напісанне справаздач. Вы запытваеце дадзеныя, праводзіце аналіз, візуалізуеце (робіце графікі, дыяграмы), а затым адпраўляеце начальніку. Але што, калі ўсё гэта аўтаматызаваць?

У гэтым тутарыяле мы створым робата для Telegram, які дапаможа аўтаматызаваць справаздачнасць. А самае класнае - уся праграма будзе складацца ўсяго з 50 радкоў кода! Калі вы ствараеце робата для Telegram упершыню, то варта прачытаць яшчэ вось гэты пост.

Skillbox рэкамендуе: Практычны курс Python-распрацоўшчык з нуля.

Нагадваем: для ўсіх чытачоў "Хабра" - зніжка 10 000 рублёў пры запісе на любы курс Skillbox па промакодзе "Хабр".

Прыступаем

Усталёўваны бібліятэкі

Мы будзем выкарыстоўваць google-cloud-bigquery для атрымання дадзеных з Google BigQuery. matplotlib, здранцвенне и панд дапамогуць візуалізаваць дадзеныя. python-telegram-bot адправіць гатовыя дадзеныя ў Telegram.

pip3 install google-cloud-bigquery matplotlib numpy pandas python-telegram-bot

Падключаем Google BigQuery API

Калі мы жадаем выкарыстаць сэрвіс, трэба падлучыць Google BigQuery API. Для гэтага ідзем у Google Developers Console і ствараем новы праект (ці ж выбіраемы існы).

У кантрольнай панэлі выбіраемы ENABLE APIS AND SERVICES і шукаем BigQuery API.

Як дэлегаваць простыя справаздачы робату. Пішам бота на Python і Google BigQuery

Выбіраемы Enable для падлучэння API.

Як дэлегаваць простыя справаздачы робату. Пішам бота на Python і Google BigQuery

Ствараем ключ акаўнта

Зноў адпраўляемся ў Google Developers Console, выбіраемы ўкладку Credentials, Create credentials і Service account key.

Затым - New service account, і ў поле Service account name уводны імя.

З выпадальнага спісу Role выбіраемы Project > Owner, затым Create.

Як дэлегаваць простыя справаздачы робату. Пішам бота на Python і Google BigQuery

Файл, які будзе аўтаматычна загружацца, завем creds.json.

Выстаўляем GOOGLE_APPLICATION_CREDENTIALS, паказаўшы шлях да creds.json у тэрмінале.

export GOOGLE_APPLICATION_CREDENTIALS='[PATH_TO_CREDS.JSON]'

Калі ўсё прайшло добра, самы час пачаць пісаць праграму.

Стварэнне прыкладання

Для тутарыялу мы будзем выкарыстоўваць дадзеныя з bigquery-public-data.stackoverflow, для нашай справаздачы абяром колькасць штодзённых публікацый.

Усё дастаткова проста.

Query the table -> Visualize the data -> Save the visualization -> Send the image

Давайце створым адну функцыю для вызначэння кожнага патоку.

Query to 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

Гэтая функцыя верне запыт у выглядзе фрэйма дадзеных.

Візуалізуем дадзеныя

Для рашэння гэтай задачы выбіраемы matplotlib.

імпартаваць matplotlib.pyplot як plt

Нам трэба пяць параметраў, дзе x – дадзеныя па восі х, x_label – назва для восі, y – дадзеныя восі y, y_label – назва для восі і 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

Захоўваем малюнак

Цяпер давайце скарыстаемся дзвюма функцыямі, каб стварыць візуалізацыю і захаваць яе.

Будзем адпраўляць лік штодня публікуемых пастоў. Спачатку пішам запыт.

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
        """

Запыт дапамагае сабраць дадзеныя за два тыдні, пачынаючы з 2 снежня 2018 года.

Мы выкарыстоўваем гэтую дату, таму што 2018/12/02 - апошнія дадзеныя, запісаныя ў bigquery-public-data.stackoverflow.post_history, у іншых выпадках вы можаце выкарыстоўваць CURRENT_DATE () для атрымання самых новых дадзеных.

Выклікаем функцыю query_to_bigquery для атрымання дадзеных.

dataframe = query_to_bigquery(query)

Затым выкарыстоўваем калонку дадзеных date для восі х, а калонку total_posts для восі у.

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')

Адпраўляем малюнак

Для таго, каб даслаць справаздачу адрасату, трэба ведаць параметр chat_id.

Выкарыстоўваны userinfobot і набіраем /start. Бот адказвае патрэбнай інфармацыяй, chat_id утрымоўваецца ў поле id.

Цяпер ствараем функцыю send_image. Яна будзе задзейнічаць функцыю get_and_save_image для атрымання і захавання выявы. А затым ужо адпраўляем усё правільнаму кантакту.

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'))

Галоўная праграма

Нарэшце, ствараем яшчэ адну функцыю, main, для запуску дадатку. Не забывайце змяніць YOUR_TOKEN для робата.

Запомніце: гэтая праграма адправіць выява аўтаматычна ў паказаны вам час. Да прыкладу, мы будзем дасылаць справаздачу а дзевятай раніцы штодня.

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.

Як дэлегаваць простыя справаздачы робату. Пішам бота на Python і Google BigQuery

Гатовы код вы можаце атрымаць у маім GitHub.

Skillbox рэкамендуе:

Крыніца: habr.com

Дадаць каментар