※ コンテナーからディレクトリ一括でダウンロードする方法については、別記事(下記)で公開しています。
はじめに
現職では、ディープラーニングの学習をする際、会社でAzureのアカウントを契約してもらっていて、そこでNVIDIAのGPUを使って計算しています。
Azureストレージにコンテナを作成し、学習の計算時にはこれをマウントして、ディープラーニングで学習を実施する際の教師画像や学習記録のテキスト、生成されたモデルデータなどを保存していました。
これらを、個別のファイルあるいはディレクトリ一括でダウンロードしたいと思って調べたところ、意外とクリティカルな記事がなかなか見つからず、色々と泥沼にハマってしまい1日近く溶かしたので備忘録を残しておきます。
本記事では、
- Pythonでコンテナーから個別のファイルをダウンロードする方法
を紹介したいと思います。
プログラムあるいはコマンドでダウンロードすることを選んだのは、まずそもそもAzureポータルからGUIで直接ダウンロードするボタンがなかったことと、定期的にローカルにデータを移したい時の利便性なども考えて、方法を知っておくと役に立ちそうだなと思ったからです。
が、もう1つ正直に言うと、後からAzure Storage explorerなるものがあると知りまして、コチラではGUIでダウンロード含めAzureを扱えるようなので、GUIでの操作を知りたい方は例えばこんな記事様もぜひご参考にしてみてください。
⇒ Azure Storage Explorerを使ってみる
また、コンテナーからダウンロードをするということは当然Azureと通信するということなので、皆様の利用プランによって料金も変わってくるかと思います。私もまだまだAzureについては部分的に使えるだけで、どんな操作でどれくらいお金がかかるかという感覚が薄かったので、皆様もこの点にはぜひご注意ください。
環境
超簡単にですが、環境はWindows10、Pythonのバージョンは3.8.13です。
Azureのストレージ・コンテナーについて
先にAzureストレージについて簡単な説明ですが、ストレージは色々種類があるようで、この記事とかが参考になりそうです。
⇒ Azure Storageを使ってみる
私が使用しているコンテナーは、画像やテキストデータなどが入ったAzure Blobストレージだったようです。
また、Azure Blob Storage の概要 から引用しますと、
Blob Storage には、3 種類のリソースがあります。
- ストレージ アカウント
- ストレージ アカウント内のコンテナー
- コンテナー内の BLOB
とのことで、このBLOBというのが画像ファイルやらテキストファイルやら、個別のデータのことのようです。
ファイルをダウンロードする方法
ということで本題。
Pythonで、特定のファイルを指定してダウンロードする方法です。
このあたりの記事様を参考にしました。
- PythonでAzure Blobのファイル一覧取得・ダウンロードをする
- Azure StrageからPython APIでデータを読み込む
- PythonでAzure Blob Storageからcsvを取得する方法について
azure-storage-blobのインストール
PythonでAzure Blobストレージにアクセスするには、「azure-storage-blob」パッケージを使いますので、まずはこれをインストールします。
pip install azure-storage-blob
Anacondaの環境の人はconda
で行うなど、必要な環境があれば合わせてみてください。
ファイルダウンロード
それではazure-storage-blobパッケージを使って、ファイルをダウンロードします。
先にコードを示して、後から少し補足説明します。
import os
from azure.storage.blob import BlobServiceClient
def main():
container_name = "コンテナー名"
blob_name = "コンテナー内のファイルパス"
# 接続文字列を用いてBlobServiceClientを作成
connect_str = "接続文字列"
blob_service_client = BlobServiceClient.from_connection_string(connect_str)
blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)
"""
ローカルにダウンロード
"""
# ディレクトリ(がなければ)作成
dir_path = './ダウンロードしたいローカルのディレクトリパス'
os.makedirs(par_data_path, exist_ok=True)
# ファイルをダウンロード
data_name = "保存したいファイル名"
data_path = os.path.join(dir_path, data_name)
with open(data_path, "wb+") as file:
file.write(blob_client.download_blob().readall())
if __name__ == "__main__":
main()
コンテナー名
は、ストレージアカウントの左ペインから「データストレージ」 -> 「コンテナー」に入ったときに表示されるコンテナー達の名前です。
コンテナー内のファイルパス
は、上で表示したコンテナー内に入ってからのファイルパスを書きます。
接続文字列
は、ストレージアカウントの左ペインから「アクセス キー」に入り、「接続文字列」を表示させるとコピーできます。(以下画像参照)
また通信において、私の場合は会社の環境だったのでプロキシの設定が心配でしたが、今回はこれでそのままうまくダウンロードできました。
が、環境によってはプロキシの設定が必要になるかも知れませんのでご注意ください。
また参考記事では、ファイルのダウンロードだけでなく、ファイル一覧のパス取得も行っているので、気になる方はご参照ください。
1点注意なのは、ここで取得したパスには、実際にはファイルパスとディレクトリパスの両方が混在していることです。
ディレクトリ内のデータを一括でダウンロードするのもこのパス取得をうまく活用すればできるはずですが、「取得したパスがディレクトリパスならディレクトリ作成、ファイルパスならダウンロード」のようにうまく判別する必要があり、やろうと思えばできるが判別方法で稀なケース等を想定するのもちょっと面倒という理由で、ディレクトリ一括ダウンロードについては他の方法がないか探してみることにしました。
ディレクトリごと一括でダウンロードする方法
冒頭でも述べましたが、別記事としてこちらで公開しています。