【Azure Blob Storage】PythonからBlob・コンテナーを操作してみる

はじめに

AzureのBlobを 公式のクイックスタート を参考にPythonからアップロード・ダウンロードしてみます。またAutoMLでトレーニングしたベストモデルに出力されたoutputsフォルダなどをローカルにダウンロードしてみます。

開発環境

  • OS Windows 10(NVIDIA GTX 1650Ti,16GB RAM, i5-10300H CPU)
  • Visual Studio Code 1.73.1
  • Python 3.8

パスワードレスでBlobのアクセスを行ってみる

Blobへのアクセスは、パスワードレスの方法と接続文字列を使った2種類のやり方があります。

まずはパスワードレスのやり方でやってみます。

ロール割り当て

ストレージアカウントを開き、「アクセス制御」>「追加」>「ロール割り当ての追加」をクリックします。

無題.png
目的のロールに絞ります。今回は「ストレージBLOB共同作成者」を選びました。

目的のロールに絞ります。今回は「ストレージBLOB共同作成者」を選びました。

image.png

そして、メンバーの選択を行います。

無題.png

これで「レビューと割り当て」を選んで完了です。

これでいよいよPythonからBlobを操作してみます。

まずはコンテナー作成から行います。

コンテナー作成

Azureの認証をDefaultAzureCredentialを用いて行います。

そのために、まずはAzure CLIへログインします。

インストールしていない方は こちら をご覧ください。

az login

次に下記コードを実行してコンテナーを作成します。

create_container.py
import os, uuid
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient

try:
    print("Azure Blob Storage Python quickstart sample")
    account_url = "https://.blob.core.windows.net"
    default_credential = DefaultAzureCredential()
    blob_service_client = BlobServiceClient(account_url, credential=default_credential)
    #コンテナー作成
    container_name = ""
    containe_client = blob_service_client.create_container(container_name)

        blob_client.upload_blob(data)
except Exception as ex:
    print("Exception:")
    print(ex)

account_urlの<ストレージアカウント>は赤線部分の文字列をコピペします。

無題.png

container_nameには、作成するコンテナーの名前を入れます。今回は「sas-test-tkawano」としました。

container_name = "sas-test-tkawano"

Azure Portalで確認したところ、コンテナーが作成されていました。

無題.png

続いて作成したコンテナーにBLOBをアップロードしてみます。

BLOBにファイルをアップロード

ローカルにある”train.csv”というファイルをアップロードしてみます。

Blobclientクラスのgetblobclient()で作成済みのコンテナーを指定できます。

upload_blob.py
import os, uuid
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient

try:
    account_url = "https://.blob.core.windows.net"
    default_credential = DefaultAzureCredential()
    blob_service_client = BlobServiceClient(account_url, credential=default_credential)

    container_name = ""

    #アップロードするファイルが格納されたパス・ファイル名
    local_path="./"
    local_file_name = "train.csv"

    blob_client = blob_service_client.get_blob_client(container=container_name, blob=local_file_name)

    #アップロード
    with open(file=upload_file_path, mode="rb") as data:
        blob_client.upload_blob(data)
except Exception as ex:
    print("Exception:")
    print(ex)

localpathには格納するファイルが入っているパス名を入力し、localfile_nameにはアップロードするファイル名を入れます。

実行してコンテナーを見ると「train.csv」がアップロードされていました。

image.png

今度はアップロードしたBlobをローカルへダウンロードしてみます。

ダウンロード

ローカルのパスを指定し、そこへBLOBをダウンロードします。

download.py
import os, uuid
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

try:
    account_url = "https://.blob.core.windows.net"
    default_credential = DefaultAzureCredential()
    blob_service_client = BlobServiceClient(account_url, credential=default_credential)
    #コンテナー
    container_name = ""

    #ファイル
    local_path="./"
    local_file_name="train.csv"

    container_client=blob_service_client.get_container_client(container_name)

    #ダウンロード
    download_file_path = os.path.join(local_path,str.replace(local_file_name, ".csv","DOWNLOAD.csv"))
    print("\nDownloading blob to \n\t")

    with open(file=download_file_path, mode="wb") as download_file:
        download_file.write(container_client.download_blob(local_file_name).readall())

except Exception as ex:
    print("Exception:")
    print(ex)

実行すると、ローカルにtrainDOWNLOAD.csvができました。

image.png

さて、ファイルのアップロード・ダウンロードはできたので、今度はフォルダのダウンロードを行います。

フォルダのダウンロード

前回AutoMLで作成した一番精度の良いモデルのoutputsフォルダの中身をダウンロードしてみます。フォルダのダウンロードについては流行りのChat GPTにやり方を教えてもらいました^^

MicrosoftTeams-image.png

フォルダの中にあるファイルをfor文で1つずつ取り出していけば、フォルダのダウンロードができるようです。

folder.py
import os, uuid
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient

try:
    account_url = "https://.blob.core.windows.net"
    default_credential = DefaultAzureCredential()
    blob_service_client = BlobServiceClient(account_url, credential=default_credential)

    container_name = ""
    container_client = blob_service_client.get_container_client(container=container_name)

    outputs_path = ""
    blob_list = container_client.list_blobs(name_starts_with=outputs_path)

    outputs_folder = ""
    if not os.path.exists(outputs_folder):
        os.makedirs(outputs_folder)

    for blob in blob_list:
        blob_client = container_client.get_blob_client(blob.name)
        file_path=os.path.join(outputs_folder,(blob.name.split("/")[-1]))
        with open(file_path, mode="wb") as download_file:
            download_file.write(container_client.download_blob(blob.name).readall())

except Exception as ex:
    print("Exception:")
    print(ex)

outputs_pathにはダウンロードするフォルダがあるパスを入れます。

今回の「outputs」フォルダは「ExperimentRun/dcid.carefulantrbvh6tjqm5_3/」の中にあったので次のように書きます。

outputs_path = "ExperimentRun/dcid.careful_ant_rbvh6tjqm5_3/outputs/"

あとはoutputspathから始まる名前のBLOBのリストをlistblobs()で取り出し、1つずつファイルをローカルへダウンロードします。

ChatGPTから教えてもらったコードをほぼそのまま実行しただけですが、フォルダごとダウンロードできてました!!

image.png

以上がパスワードレスのやり方でPythonからコンテナー作成やBLOBをアップロード・ダウンロードする方法でした。続いて接続文字列を用いてBlob操作を行います。

接続文字列を使ったやり方

1. ストレージアカウントから接続文字列取得

「アクセス キー」をクリックすると「接続文字列」があるのでこれを保存します。

無題.png

2. 文字列の構成

コマンドプロンプトで以下のに接続文字列をコピペして実行し、環境変数を追加します。

setx AZURE_STORAGE_CONNECTION_STRING "<yourconnectionstring>"

追加したら一度コマンドプロンプトを再起動します。

それでは接続文字列を使って今度はBLOBリストを作成しましょう。

リストはBlobServiceClientクラスのlist_blobs()から得られます。

list.py
import os, uuid
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

try:
    connect_str = os.getenv("AZURE_STORAGE_CONNECTION_STRING")
    blob_service_client = BlobServiceClient.from_connection_string(connect_str)
    container_name = ""

    container_client = blob_service_client.get_container_client(container_name)

    blob_list=container_client.list_blobs()
    for blob in blob_list:
        print("\t"+blob.name)

except Exception as ex:
    print('Exception:')
    print(ex)

実行後、train.csvのみ返ってきました。

train.csv

公式ではパスワードレスのやり方が推奨されていますが、接続文字列を使っても同じようにBlob Storageへアクセスできました。

次の記事ではSASを生成し、SAS URIを使ってBLOBをダウンロードしてみます。

この記事を書いた人

azure-recipe-user