雑コラBOTを作ろう③: Azure Functionsで画像をダウンロードしてBlob Storageに保存する

Queue Storageに格納されたメッセージをトリガーに関数を開始し、メッセージ内のURLで画像をダウンロードしてBlob Storageに保存します。

関数の作成とバインドの設定

Azure Functionsの関数をPythonで作成します。

関数のテンプレートの「実験的な言語のサポート」を有効化し、一覧から「Queue trigger」を選択してPythonで作成を開始します。

関数の作成ペインで関数名とトリガーバインドを設定します。

キューは前回作成した関数の出力バインドと同じものを指定にします。

関数が作成されたら、出力バインドを設定します。

関数の「統合」メニューで「+新しい出力」をクリックし、「Azure BLOB ストレージ」のバインドを選択します。

「Azure BLOB ストレージ output」の設定で画像を出力するストレージアカウントとパスを設定し、保存をクリックします。

出力パスには「{blobpath}」のバインディング式を設定しており、前回設定したキューメッセージ(JSON)の「blobpath」キーの値がパスに代入されるようにしています。

Pythonバージョンの変更

関数のPythonバージョンをデフォルトの2.7系から3.6系に変更します。

Python3インストールに関しては こちらの記事 を参照ください。

スクリプト

スクリプトは以下のように作成しました。

coding: utf-8

1. ライブラリの読み込み

import os, json
import imghdr
import urllib.parse
import urllib.request

print("Function Start. ID:" + os.environ["INVOCATIONID"])

def handler():

2. キューメッセージ読み込み

with open(os.environ["inputMessage"], "r") as f:
input_msg = json.load(f)

3. コンテンツのダウンロード

print("Downloading input image")
dlurl = inputmsg["img_url"]
req = urllib.request.Request(dl_url)
with urllib.request.urlopen(req) as res:
img_bytes = res.read()

4. 画像フォーマット判定

print("Checking input image format")
imgformat = imghdr.what(None, h=imgbytes)

if img_format in ["jpeg", "png", "bmp", "gif"]:
if img_format == "jpeg":
img_format = "jpg"

5. Blob Storageに画像を保存

with open(os.environ["outputBlob"], "wb") as fw:
fw.write(img_bytes)
return

if _name == "main_":
handler()

スクリプトの説明

1. ライブラリの読み込み

処理に必要なライブラリを読み込みます。

2. キューメッセージ読み込み

Queue Storageに格納されたメッセージを読み込みます。
Python関数ではファイルから読み込む形でキューメッセージを受け取ります。

3. コンテンツのダウンロード

Slackに投稿されたURLからコンテンツをダウンロードします。

4. 画像フォーマット判定

ダウンロードしたコンテンツのフォーマットを判定します。
前段の関数ではURLの有無を確認するのみで、フォーマット判定を行っていないため、ここで判別を行います
画像フォーマットは後に使うFace APIに合わせ、JPEG、PNG、BMP、GIFのみ処理を続行するようにしています。

5. Blob Storageに画像を保存

ダウンロードした画像をBlob Storage に保存します。
Python関数では、環境変数で指定されるパスにファイルとして保存することでBlob Storageにファイルを書き出すことができます。

実行結果

Slackのチャンネルに画像のURLを投稿すると、投稿時刻とほぼ同時に関数のログが表示され、Queue Storageとトリガーにより関数が開始されていることが確認できました。

Blob Storageをみると、投稿したURLの画像と同じ画像が出力バインドで指定したパスに保存されており、画像のアップロードも正常に行えていることが確認できました。

まとめ

今回は、Queue StorageによるAzure FunctionsのPython関数のトリガーとBlob Storageの出力バインドを設定し、画像のダウンロードと保存までできました。

雑コラBotとしては、これに画像加工を行い、保存した画像をSlackに返送すれば一連の仕組みが完成しますが、次回は少し寄り道をして、Azure Functionsの実行履歴をTable Storageに保存する仕組みを追加します。

この記事を書いた人

azure-recipe-user