4
7

More than 1 year has passed since last update.

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

Posted at

はじめに

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共同作成者」を選びました。
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クラスのget_blob_client()で作成済みのコンテナーを指定できます。

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)

local_pathには格納するファイルが入っているパス名を入力し、local_file_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名>"
    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.careful_ant_rbvh6tjqm5_3/」の中にあったので次のように書きます。

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

あとはoutputs_pathから始まる名前のBLOBのリストをlist_blobs()で取り出し、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をダウンロードしてみます。

4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7