単純なレポートをロボットに委任する方法。 PythonとGoogle BigQueryでボットを書く





毎週、毎日繰り返されるタスクがありますか? たとえば、レポートの作成。 データを要求し、分析を行い、視覚化(グラフ、チャートを作成)して、それをボスに送信します。 しかし、これがすべて自動化されたらどうなるでしょうか?



このチュートリアルでは、レポートの自動化に役立つTelegramのボットを作成します。 そして、最もクールなことは、プログラム全体がわずか50行のコードで構成されることです! 初めてTelegramのボットを作成する場合は、こちらの投稿をご覧ください



Skillboxの推奨事項: ゼロからの 実践的な Python開発者



「Habr」の読者には、「Habr」プロモーションコードを使用してSkillboxコースに登録すると10,000ルーブルの割引があります。

降りる



ライブラリをインストールする



google-cloud-bigqueryを使用して、Google BigQueryからデータを取得します。 matplotlibnumpy 、およびpandasは、データを視覚化するのに役立ちます。 python-telegram-botは、完成したデータをTelegramに送信します。



pip3 google-cloud-bigquery matplotlib numpy pandas 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のデータを使用します。レポートでは、毎日の発行数を選択します。



すべてが非常に簡単です。



テーブルのクエリ->データの視覚化->視覚化の保存->画像の送信



各スレッドを定義する関数を1つ作成しましょう。



BigQueryへのクエリ



まず、ライブラリをインポートします。



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としてインポート



5つのパラメーターが必要です。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
      
      





画像を保存



次に、2つの関数を使用して視覚化を作成し、保存します。



毎日公開される投稿の数を送信します。 最初にリクエストを書きます。



 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日から2週間のデータを収集するのに役立ちます。



2018-12-02はbigquery-public-data.stackoverflow.post_historyに記録された最新のデータであるため、この日付を使用します。その他の場合は、CURRENT_DATE()を使用して最新のデータを取得できます。



query_to_bigquery関数を呼び出してデータを取得します。



データフレーム= query_to_bigquery(クエリ)



次に、x軸に日付列を使用し、y軸にtotal_posts列を使用します。



x =データフレーム['date']。tolist()

y =データフレーム['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を変更することを忘れないでください。



注意:このプログラムは、指定した時間に自動的に画像を送信します。 たとえば、毎日午前9時にレポートを送信します。



 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の推奨事項:






All Articles