Com delegar informes senzills a un robot. Escriure un bot a Python i Google BigQuery

Com delegar informes senzills a un robot. Escriure un bot a Python i Google BigQuery

Tens tasques que es repeteixen dia rere dia, setmana rere setmana? Per exemple, escriure informes. Sol·liciteu dades, les analitzeu, les visualitzeu (feu gràfics, gràfics) i després les envieu al vostre cap. Però, i si tot això estigués automatitzat?

En aquest tutorial crearem un bot per a Telegram que ajudarà a automatitzar els informes. I el millor és que tot el programa constarà de només 50 línies de codi! Si esteu creant un bot per a Telegram per primera vegada, també hauríeu de llegir aquest publicar.

Skillbox recomana: Curs pràctic Desenvolupador Python des de zero.

Recordem: per a tots els lectors de "Habr": un descompte de 10 rubles en inscriure's a qualsevol curs de Skillbox amb el codi promocional "Habr".

Començant

Instal·lació de biblioteques

L’utilitzarem google-cloud-bigquery per obtenir dades de Google BigQuery. matplotlib, NumPy и pandes t'ajudarà a visualitzar les teves dades. python-telegram-bot enviarà les dades acabades a Telegram.

pip3 instal·lar google-cloud-bigquery matplotlib numpy pandas python-telegram-bot

S'està connectant l'API de Google BigQuery

Si volem utilitzar el servei, hem de connectar l'API de Google BigQuery. Per fer-ho anem a Consola de desenvolupadors de Google i creeu un projecte nou (o seleccioneu-ne un existent).

Al tauler de control, seleccioneu ACTIVA API I SERVEIS i cerqueu l'API de BigQuery.

Com delegar informes senzills a un robot. Escriure un bot a Python i Google BigQuery

Seleccioneu Habilita per connectar l'API.

Com delegar informes senzills a un robot. Escriure un bot a Python i Google BigQuery

Creeu una clau de compte

Anem-hi de nou Consola de desenvolupadors de Google, seleccioneu la pestanya Credencials, Crea credencials i Clau de compte de servei.

A continuació, - Compte de servei nou i introduïu el nom al camp Nom del compte de servei.

A la llista desplegable Rol, seleccioneu Projecte > Propietari i, a continuació, Crea.

Com delegar informes senzills a un robot. Escriure un bot a Python i Google BigQuery

El fitxer que es baixarà automàticament s'anomena creds.json.

Estableix GOOGLE_APPLICATION_CREDENTIALS, especificant el camí a creds.json al terminal.

exporta GOOGLE_APPLICATION_CREDENTIALS='[PATH_TO_CREDS.JSON]'

Si tot ha anat bé, és hora de començar a escriure el programa.

Creació d'una aplicació

Per al tutorial utilitzarem dades de bigquery-public-data.stackoverflow, per al nostre informe seleccionarem el nombre de publicacions diàries.

És força senzill.

Consulta la taula -> Visualitza les dades -> Desa la visualització -> Envia la imatge

Creem una funció per definir cada fil.

Consulta a BigQuery

Primer importem la biblioteca.

des de google.cloud importar bigquery

Creem una funció anomenada query_to_bigquery, on el paràmetre és query.

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

Aquesta funció retornarà la sol·licitud com a marc de dades.

Visualització de dades

Per resoldre aquest problema, trieu matplotlib.

importa matplotlib.pyplot com a plt

Necessitem cinc paràmetres, on x són les dades de l'eix x, x_label és el títol de l'eix, y són les dades de l'eix y, y_label és el títol de l'eix i title és el títol de tota la visualització.

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

Desa la imatge

Ara fem servir dues funcions per crear una visualització i desar-la.

Enviarem el nombre de publicacions diàries. Primer escrivim una petició.

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

La consulta ajuda a recopilar dades durant dues setmanes a partir del 2 de desembre de 2018.

Utilitzem aquesta data perquè 2018-12-02 són les últimes dades registrades a bigquery-public-data.stackoverflow.post_history; en altres casos, podeu utilitzar CURRENT_DATE() per obtenir les dades més noves.

Truqueu a la funció query_to_bigquery per obtenir les dades.

marc de dades = query_to_bigquery (consulta)

A continuació, utilitzem la columna de dades de data per a l'eix X i la columna total_posts per a l'eix Y.

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

El visualitzem mitjançant la funció visualize_bar_chart i el desem com a imatge.

plt = visualize_bar_chart(x=x, x_label='Data', y=y, y_label='Publicacions totals', title='Publicacions diàries')
plt.savefig('viz.png')

Emboliquem aquest codi en una funció anomenada 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')

Envia una imatge

Per enviar un informe al destinatari, heu de conèixer el paràmetre chat_id.

Fem servir userinfobot i escriviu /start. El bot respon amb la informació necessària, chat_id es troba al camp id.

Ara creem la funció send_image. Utilitzarà la funció get_and_save_image per recuperar i desar la imatge. I després ho enviem tot al contacte correcte.

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

Programa principal

Finalment, creem una altra funció, principal, per llançar l'aplicació. No oblideu canviar YOUR_TOKEN per al bot.

Recordeu: aquest programa enviarà la imatge automàticament a l'hora que especifiqueu. Per exemple, enviarem un informe a les nou del matí cada dia.

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

Com a resultat, la nostra aplicació tindrà aquest aspecte:

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

Deseu el fitxer i anomeneu-lo main.py.

Llencem l'aplicació introduint l'ordre al terminal:

python3 main.py

Tot a punt. Ara tenim un robot format per 50 línies de codi que genera informes sense la nostra intervenció.

Comprovem el bot per tantseleccionant l'ordre /send.

Com delegar informes senzills a un robot. Escriure un bot a Python i Google BigQuery

Podeu obtenir el codi acabat a el meu GitHub.

Skillbox recomana:

Font: www.habr.com

Afegeix comentari