SummerEye part4 -BLOB Storage連携-

前回さっくりComputer Vision APIを利用できました。

今回は、ローカルでflaskプロジェクトにファイルアップロード機能を実装します。

そして保存先をAzure BLOB Storageに繋げてみます。

 

概要

BLOB StorageはAzure Storageの一つです。

他にFile Storage、Queue Storageがあり、扱いが得意なファイルが変わります。

画像などのバイナリファイルはBLOB Storageが得意とするところです。

 

ストレージアカウント作成

Azureポータルを開いて、

「新規作成 -> Storage -> Storage Account」を選択します。

適宜名前やサブスクリプションを埋めます。

 

作成が完了したら、Storage AccountのAccess Keysを確認しましょう。

 

コンテナ作成

ローカルのPythonに戻ってきます。

まだazureライブラリをpipでインストールしていない場合は、以下のコマンド。

pip install azure

 

ではコードに入ります。

ファイルを保存するとき、まずは容れ物であるコンテナを作成します。

 

コンテナ名のルール

コンテナー名は有効な DNS 名で、次の名前規則に準拠している必要があります。

  1. コンテナー名は英文字または数字で始まり、英文字、数字、ダッシュ (-) 文字のみを含めることができます。
  2. すべてのダッシュ (-) 文字は、その直前または直後に文字または数字が使用されている必要があります。連続するダッシュ文字は、コンテナー名では使用できません。
  3. コンテナー名の文字はすべて小文字である必要があります。
  4. コンテナー名の長さは、3 ~ 63 文字にする必要があります。

Python から Azure Blob Storage (オブジェクト ストレージ) を使用する方法 | Microsoft Docs

 

以下のコードでパブリックアクセス可能なコンテナを作成できます。

(create_containerに第二引数を渡さなければプライベートなコンテナになります)

from azure.storage.blob import BlockBlobService
from azure.storage.blob import PublicAccess

account_name = account_name
account_key = account_key
container_name = container_name

block_blob_service = BlockBlobService(account_name=account_name, account_key=account_key)
block_blob_service.create_container(container_name, public_access=PublicAccess.Container)

 

このスクリプトを実行した後にAzureポータルでStorage AccountのOverviewを確認すると、新しくコンテナが作成されていることがわかります。

 

 

BLOBをアップロード(ローカルファイル)

以下のようにファイルパスを指定してアップロードします。

file_pathはローカルのファイルパスを

from azure.storage.blob import ContentSettings

account_name = account_name
account_key = account_key
container_name = container_name
blob_name = blob_name
file_path = file_path

block_blob_service = BlockBlobService(account_name=account_name, account_key=account_key)
block_blob_service.create_blob_from_path(
    container_name,
    blob_name,
    file_path,
    content_settings=ContentSettings(content_type='image/png')
        )

 

コードを実行して、先ほど作ったコンテナの中を確認すると、BLOBがアップロードされています。

 

さらにBLOBをダブルクリックするとプロパティが確認できます。

 

表示されているURLにアクセスすると、ローカルのファイルがアップロードされているのが確認できます。

(コンテナをパブリックにしている必要があります)

 

なお、URLは以下の法則で保存されます。

http://<storage-account-name>.blob.core.windows.net/<contain‌​er-name>/<blob-name> 

 

このやり方の場合、ユーザがアップロードしたファイルを一旦Web App内に保存する必要があります。

create_blob_from_streamというのがあるらしい。

これなら一旦保存せずに直接BLOBにアップロードできそうなので次項で検討してみます。

 

BLOBをアップロード(ストリーム)

flaskでBLOBに直接 画像ファイルをアップロードします。

flaskのmain.pyをこんな感じにします。

(複数画像アップロードに対応しました)

from flask import Flask , render_template, request
from werkzeug import secure_filename
from azure.storage.blob import BlockBlobService, PublicAccess, ContentSettings

app = Flask(__name__)
IMAGE_DIR = './images/'
account_name = account_name
account_key = account_key
container_name = container_name

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/upload', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':

        upload_files = request.files.getlist('upload_files')
        block_blob_service = BlockBlobService(account_name=account_name, account_key=account_key)

        for upload_file in upload_files:
            block_blob_service.create_blob_from_stream(
                container_name,
                upload_file.filename,
                upload_file,
                    )
        return render_template('renamed.html')

if __name__ == '__main__':
    app.run()

 

index.htmlはこんな感じにフォームを作ります。

&lt;form method="post" action="/upload" enctype = "multipart/form-data"&gt;
    &lt;p class="image-select"&gt;画像を選択する&lt;/p&gt;
    &lt;input type="file" name="upload_files" multiple="multiple"&gt;
    &lt;input type="submit" value="送信"&gt;
&lt;/from&gt;

 

 

このflaskプロジェクトをWeb Appで動かせば、アップロードしたファイルをBLOB Storageに直接保存できそうです。

さくさく。

 

さらに、前回のComputer Vision APIを叩くスクリプトと、

アップロードしたBLOBのURLが以下で記述されることを合わせればアップロードした画像のディスクリプションを取得できました。

http://<storage-account-name>.blob.core.windows.net/<contain‌​er-name>/<blob-name> 

 

次回

残りは以下の2項目です。

それなりにさくさく進んでます。

  • Pythonプロジェクト上からBLOBをリネーム
  • 画像をアップロードしたらリネームされたものをzipでダウンロード

 

ただちょっと調べた感じだとBLOBのリネーム手段が用意されていないっぽくて少しめんどくさそうでした。

Computer Vision APIから返ってきたdescriptionをダウンロードの時のファイル名として使えばいいか。

なんとなくリネームしたデータを取っておきたいので、あとで付き合わせられるように何かしらの形では残したいです。

 

最悪リネームしたファイル名で再度新しくBLOBアップロード、そのURLを返すという解決法もありですね。

ダサいのと料金が倍になりそうなのが問題ですが。

 

参考

コメントを残す