😊

Azure Functions + PythonでBlob Storage SDKを使う

2022/05/15に公開2

Microsoft Azure の Azure Functions を Python で作成し、Azure Blob StorageをPython v12 SDKを使って操作していきます。

Azure Functions から Azure Blob Storage を利用する場合、入出力バインドを使う方法もありますが、入出力バインドでは込み入った操作がおこなえない場合があるので、ここでは SDK を使って操作します。

入出力バインドでの Blob Storage の利用は、次の記事を参考にしてください。
https://zenn.dev/gatabutsu/articles/ff0ec275a0084f

この記事の前提条件

  • アクティブなサブスクリプションが含まれる Azureアカウント がある
  • Azureに ストレージアカウント が作成済である
  • ChromeBook で開発する
  • ChromeBook には VSCode がインストールされている
  • HttpトリガーのFunctionが作成済である

ChromeBook への VSCode のインストール、PythonでのAzure開発の始め方は、次の記事を参考にしてください。
https://zenn.dev/gatabutsu/articles/82008b901c4f04
https://zenn.dev/gatabutsu/articles/73c2cdeb0f264a

ストレージへの接続

接続文字列の確認

まずは、Blob Storageにアクセスするための接続文字列を確認します。
Azureにサインインし、入出力先となるストレージアカウントを選択します。メニューから「アクセスキー」を表示し「キーの表示」をクリックしたあと、表示された key1 → 接続文字列 の値をコピーします。

local.settings.jsonの編集

ローカルでの開発時に参照される接続文字列をlocal.settings.jsonに書いていきます。

local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<コピーした接続文字列>",
    "FUNCTIONS_WORKER_RUNTIME": "python"
  }
}

Azure上でサービスを実行する場合には、Azure Functionsのアプリケーション設定に設定されている同キーの値が参照されます。

パッケージのインストール

Python 用の Azure Blob Storage クライアント ライブラリ パッケージをインストールします。

VSCodeのターミナルで対象プロジェクトのディレクトリに行き、次のコマンドでインストールします。

pip install azure-storage-blob

requirements.txtに追加

インストールした「azure-storage-blob」を依存パッケージの一覧であるrequirements.txtにも追記します。
Azureにデプロイする際にシステムによってインストールされます。

requirements.txt
azure-functions
azure-storage-blob

Python関数の編集と実行

Httpトリガーで起動された関数が、予め Azure Blob Storage 上に作成されたテキストファイルを読み取って内容を編集し、上書き保存するというプログラムを書いていきます。

プログラムの全体像

  1. Azure Blob Storage に接続し、BLOBを操作するために BlobClient オブジェクトへの参照を取得します
  2. 操作の対象となる BLOB を一旦ダウンロードします
  3. ダウンロードしたファイルを編集します
  4. 編集後のファイルを再び Azure Blob Storage にアップロードします
__init__.py
import logging

import azure.functions as func

import os
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient, __version__

from tempfile import NamedTemporaryFile

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    #環境変数から Blob Storage への接続文字列を取得中します
    connect_str = os.environ['AzureWebJobsStorage']
    #Azure Storage リソースと BLOB コンテナーを操作を操作するためのBlobServiceClientを用意します
    blob_service_client = BlobServiceClient.from_connection_string(connect_str)
    #Azure Storage BLOB を操作するための BlobClient オブジェクトへの参照を取得します
    #コンテナ:container , ディレクトリ:sdk-sample , ファイル:sample.txt は予め作成しておくものとします
    blob_client = blob_service_client.get_blob_client(container='container/sdk-sample', blob='sample.txt')

    # 一時ファイルを作成し、Blobをダウンロードします
    # バイナリモードでオープンする必要があります
    with NamedTemporaryFile('wb',delete=False) as tmp:
        tmp.write(blob_client.download_blob().readall())
        #ダウンロードしたファイルに1行追記します
        writestr = "\n行を追加"
        #テキストファイルですが、バイナリモードで開いているのでエンコードして書き込みます
        tmp.write(writestr.encode())

    # 一時ファイルをいったんクローズしたあと再度オープンし、Blob Storageにアップロードします
    # その際、ファイルは上書きします
    with open(tmp.name, "rb") as data:
        blob_client.upload_blob(data,overwrite=True)
        #レスポンス表示用にファイルの中身を取得
        data.seek(0)
        filedata = data.read()
        filestr = filedata.decode()

    # 一時ファイルを削除します
    os.remove(tmp.name)

    return func.HttpResponse(f"ok.\n{filestr}")

1.BlobClient オブジェクトへの参照を取得する

環境変数「AzureWebJobsStorage」から Azure Blob Storage への接続文字列を取得します。ローカルでの開発時にはlocal.settings.jsonの値が参照され、Azure上でサービスを実行する場合には、Azure Functionsのアプリケーション設定に設定されている同キーの値が参照されます。

その接続文字列を使って Azure Storage リソースと BLOB コンテナーを操作を操作するためのBlobServiceClientを用意し、さらにBLOB を操作するためのBlobClientオブジェクトへの参照を取得します。

ここでは、予め Azure Blob Storage 上に、コンテナ「container」、ディレクトリ「sdk-sample」、BLOB「sample.txt」を作成しておくものとします。

connect_str = os.environ['AzureWebJobsStorage']
blob_service_client = BlobServiceClient.from_connection_string(connect_str)
blob_client = blob_service_client.get_blob_client(container='container/sdk-sample', blob='sample.txt')

2.BLOB を一旦ダウンロードする

BlobClientオブジェクトのdownload_blob()メソッドを使って、BLOBをダウンロードしそれを一時ファイルに書き込みます。

テキストファイルですが、バイナリモードでオープンする必要があります。また、あとでアップロードするので自動的に削除はしないでおきます。

with NamedTemporaryFile('wb',delete=False) as tmp:
    tmp.write(blob_client.download_blob().readall())

3.ファイルを編集する

ダウンロードしたファイルを編集します。
ここでは、ファイルの末尾に文字列を1行追加します。バイナリモードで開いているのでエンコードして書き込みます。

writestr = "\n行を追加"
tmp.write(writestr.encode())

4.編集後のファイルをアップロードする

ファイルを編集後、再度オープンしてBlobClientオブジェクトのupload_blob()メソッドを使ってBLOBをアップロードします。その際、Azure Blob Storageのファイルは上書きします。

with open(tmp.name, "rb") as data:
    blob_client.upload_blob(data,overwrite=True)

実行結果

関数を実行するとsample.txtの末尾に1行追加されます。

まとめ

本記事では Python で作成した Azure Functions で Azure Blob Storageを Python v12 SDKを使って操作する方法を紹介しました。
openpyxlでExcelファイルを操作する場合など、SDKを使うことで Azure Blob Storage 上のファイルを編集しやすくなります。

参考

Discussion

skmkzykskmkzyk

タイトルが「Bolb Storage SDK」になっちゃってますー!

ふみこーふみこー

ほんとですね。まったく気づきませんでした。ありがとうございます。