Wéi een einfache Berichter un e Roboter delegéiert. Schreift e Bot a Python a Google BigQuery

Wéi een einfache Berichter un e Roboter delegéiert. Schreift e Bot a Python a Google BigQuery

Hutt Dir Aufgaben déi Dag fir Dag, Woch fir Woch widderhuelen? Zum Beispill, Berichter schreiwen. Dir fuerdert Daten, analyséiert se, visualiséiert se (maacht Grafike, Charts), a schéckt se dann un Äre Patron. Awer wat wann dat alles automatiséiert wier?

An dësem Tutorial wäerte mir e Bot fir Telegram erstellen deen hëlleft Berichterstattung ze automatiséieren. An déi coolst Saach ass datt de ganze Programm aus nëmmen 50 Zeilen Code besteet! Wann Dir e Bot fir Telegram fir d'éischte Kéier erstellt, da sollt Dir och dësen liesen posten.

Skillbox recommandéiert: Praktesch Cours Python Entwéckler vun Null.

Mir erënneren Iech: fir all Habr Lieser - eng Remise vun 10 Rubel wann Dir Iech an all Skillbox Cours aschreift mat dem Habr Promo Code.

Géi erof

Installatioun vun Bibliothéiken

Mir wäerte benotzen google-cloud-bigquery fir Daten vu Google BigQuery ze kréien. matplotlib, domm и pandas hëlleft Iech Är Donnéeën ze visualiséieren. python-telegram-bot wäert déi fäerdeg Donnéeën op Telegram schécken.

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

Google BigQuery API verbannen

Wa mir de Service benotze wëllen, musse mir d'Google BigQuery API verbannen. Fir dëst ze maachen gi mir op Google Developer Console a erstellt en neie Projet (oder wielt en bestehenden).

An der Kontrollpanel, wielt ENABLE APIS AND SERVICES a kuckt no BigQuery API.

Wéi een einfache Berichter un e Roboter delegéiert. Schreift e Bot a Python a Google BigQuery

Wielt Aktivéiert fir d'API ze verbannen.

Wéi een einfache Berichter un e Roboter delegéiert. Schreift e Bot a Python a Google BigQuery

Schafen eng Kont Schlëssel

Loosst eis erëm goen Google Developer Console, wielt d'Umeldungsinformatioun Tab, Erstellt Umeldungsinformatiounen a Servicekontoschlëssel.

Dann - Neie Service Kont, a gitt den Numm am Service Kont Numm Terrain.

Vun der Roll drop-down Lëscht, wielt Projet> Besëtzer, dann Erstellt.

Wéi een einfache Berichter un e Roboter delegéiert. Schreift e Bot a Python a Google BigQuery

D'Datei déi automatesch erofgeluede gëtt heescht creds.json.

Setzt GOOGLE_APPLICATION_CREDENTIALS, spezifizéiert de Wee op creds.json am Terminal.

export GOOGLE_APPLICATION_CREDENTIALS='[PATH_TO_CREDS.JSON]'

Wann alles gutt gaang ass, ass et Zäit de Programm ze schreiwen.

Schafen eng Applikatioun

Fir den Tutorial benotze mir Daten aus bigquery-public-data.stackoverflow, fir eise Bericht wäerte mir d'Zuel vun deegleche Publikatiounen auswielen.

Alles ass ganz einfach.

Query den Dësch -> Visualiséieren d'Donnéeën -> Späichert d'Visualiséierung -> Schéckt d'Bild

Loosst eis eng Funktioun erstellen fir all thread ze definéieren.

Ufro un BigQuery

Als éischt importéiere mir d'Bibliothéik.

vun google.cloud importéieren bigquery

Mir kreéieren eng Funktioun genannt query_to_bigquery, wou de Parameter Ufro ass.

def query_to_bigquery(query):
    client = bigquery.Client()
    query_job = client.query(query)
    result = query_job.result()
    dataframe = result.to_dataframe()
    return dataframe

Dës Funktioun gëtt d'Ufro als Dateframe zréck.

Visualiséieren Daten

Fir dëse Problem ze léisen, wielt matplotlib.

import matplotlib.pyplot als plt

Mir brauche fënnef Parameteren, wou x d'X-Achsdaten ass, x_label ass den Titel fir d'Achs, y ass d'Y-Achsdaten, y_label ass den Titel fir d'Achs, an den Titel ass den Titel vun der ganzer Visualiséierung.

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

Späichert d'Bild

Loosst eis elo zwou Funktiounen benotzen fir eng Visualiséierung ze kreéieren an ze späicheren.

Mir schécken d'Zuel vun de Posts déi all Dag publizéiert ginn. Éischt schreiwen mir eng Demande.

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

D'Ufro hëlleft Daten fir zwou Wochen ze sammelen ab dem 2. Dezember 2018.

Mir benotzen dësen Datum well 2018-12-02 déi lescht Donnéeën op bigquery-public-data.stackoverflow.post_history opgeholl sinn, an anere Fäll kënnt Dir CURRENT_DATE benotzen () fir déi neisten Donnéeën ze kréien.

Rufft d'query_to_bigquery Funktioun un fir d'Donnéeën ze kréien.

dataframe = query_to_bigquery(query)

Da benotze mir d'Datumdatenkolonne fir d'x-Achs, an d'total_posts Kolonn fir d'Y-Achs.

x = dataframe['date'].tolist()
y = dataframe['total_posts'].tolist()

Mir visualiséieren et mat der visualize_bar_chart Funktioun a späicheren et als Bild.

plt = visualize_bar_chart(x=x, x_label='Datum', y=y, y_label='Total Posts', title='Daily Posts')
plt.savefig('viz.png')

Mir packen dëse Code an enger Funktioun mam Numm 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')

Schéckt e Bild

Fir e Bericht un den Empfänger ze schécken, musst Dir de Chat_id Parameter kennen.

Mir benotzen Benotzerinfobot an Typ /start. De Bot reagéiert mat der néideger Informatioun, chat_id ass am ID Feld enthale.

Loosst eis elo d'Send_image Funktioun erstellen. Et wäert d'get_and_save_image Funktioun benotzen fir d'Bild ze recuperéieren an ze späicheren. An da schécken mir alles un de richtege Kontakt.

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

Haaptprogramm

Endlech erstellen mir eng aner Funktioun, Main, fir d'Applikatioun ze starten. Vergiesst net YOUR_TOKEN fir de Bot z'änneren.

Denkt drun: Dëse Programm schéckt d'Bild automatesch zur Zäit déi Dir uginn hutt. Zum Beispill wäerte mir all Dag um néng moies e Rapport schécken.

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

Als Resultat wäert eis Applikatioun esou ausgesinn:

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

Späichert d'Datei a rufft se main.py.

Mir starten d'Applikatioun andeems Dir de Kommando am Terminal gitt:

python3 main.py

Alles ass prett. Elo hu mir e Roboter deen aus 50 Zeilen Code besteet, deen Berichter generéiert ouni eis Interventioun.

Loosst eis de Bot iwwerpréiwen vun heiandeems Dir de Kommando / send auswielt.

Wéi een einfache Berichter un e Roboter delegéiert. Schreift e Bot a Python a Google BigQuery

Dir kënnt de fäerdege Code kréien op meng GitHub.

Skillbox recommandéiert:

Source: will.com

Setzt e Commentaire