如何将简单的报告委托给机器人。 用Python和Google BigQuery编写机器人



您是否有某周每天重复执行的任务? 例如,编写报告。 您需要数据,进行分析,可视化(制作图形,图表),然后将其发送给老板。 但是,如果所有这些都是自动化的怎么办?

在本教程中,我们将为Telegram创建一个机器人,以帮助实现自动报告。 最酷的是,整个程序仅包含50行代码! 如果您是第一次为Telegram创建机器人,那么您应该在此处阅读这篇文章

Skillbox建议: 从零开始的 动手课程Python开发人员

我们提醒您: 对于所有“哈勃”读者来说,使用“哈勃”促销代码注册任何Skillbox课程时均可享受10,000卢布的折扣。

下车


安装库

我们将使用google-cloud-bigquery从Google BigQuery检索数据。 matplotlibnumpypandas将有助于可视化数据。 python-telegram-bot将完成的数据发送到Telegram。

pip3安装google-cloud-bigquery matplotlib numpy熊猫python-telegram-bot

连接Google BigQuery API

如果要使用该服务,则需要连接Google BigQuery API。 为此,请转到Google Developers Console并创建一个新项目(或选择一个现有项目)。

在控制台中,选择“启用API和服务”,然后查找BigQuery API。



选择启用以连接API。



创建一个帐户密钥

我们再次进入Google Developers Console ,选择“凭据”,“创建凭据”和“服务帐户密钥”标签。

然后-新服务帐户,然后在服务帐户名称字段中输入名称。

从“角色”下拉列表中,选择“项目”>“所有者”,然后选择“创建”。



将自动加载的文件称为creds.json。

我们公开了GOOGLE_APPLICATION_CREDENTIALS,指示了终端中creds.json的路径。

导出GOOGLE_APPLICATION_CREDENTIALS ='[PATH_TO_CREDS.JSON]'

如果一切顺利,是时候开始编写程序了。

应用程式建立


对于本教程,我们将使用来自bigquery-public-data.stackoverflow的数据,对于我们的报告,我们将选择每日出版物的数量。

一切都很简单。

查询表->可视化数据->保存可视化->发送图像

让我们创建一个函数来定义每个线程。

查询到BigQuery

首先,导入库。

从google.cloud导入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轴上的数据,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 """ 

该查询有助于收集从2018年12月2日开始的两周的数据。

我们使用此日期,因为2018-12-02是bigquery-public-data.stackoverflow.post_history中记录的最新数据,在其他情况下,您可以使用CURRENT_DATE()获取最新数据。

调用query_to_bigquery函数以获取数据。

数据框= query_to_bigquery(查询)

然后将date列用作x轴,将total_posts列用作y轴。

x =数据框['date']。tolist()
y =数据框['total_posts']。tolist()

我们使用visualize_bar_chart函数进行可视化并将其另存为图像。

plt = visualize_bar_chart(x = x,x_label =“日期”,y = y,y_label =“总帖子”,标题=“每日帖子”)
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命令从这里检查机器人。



您可以在我的GitHub中获得完成的代码。

Skillbox建议:

Source: https://habr.com/ru/post/zh-CN443702/


All Articles