PythonでAzure Storageへファイルをアップロードしたりダウンロードしたり

## はじめに
Azure StorageへPythonを使ってアップロードやダウンロードする事があったので、その備忘録

## そもそもAzure Storageとは
- Microsoft社が提供しているクラウドサービス「Azure」にあるクラウドストレージを提供するサービス。
- 汎用ストレージアカウントかBLOBストレージアカウントどちらかを選択して作成可能
- 詳しくは公式ドキュメントを参照
 - https://docs.microsoft.com/ja-jp/azure/storage/common/storage-create-storage-account

## 手順

### パッケージのインストール
PythonでAzure Storageの操作が行えるよう下記コマンドでパッケージインストール
```
pip install azure-storage
pip install pytz
```
※pytzはSASの時間設定をがタイムゾーンでの指定の為必要

### ソースコード
まず事前に、Azure Storagのアクセスに、Azure Storagのストレージアカウント名とストレージアカウントキーが必要になるので先に用意しておく必要。
またはSASトークンを使用してのアクセスを行うためそのソースも残しておく。
※SASについてこの記事がわかりやすかったの以下を参照(ストレージアカウント名とストレージアカウントキーがある場所についてもここに書いている。またPHPでのアップロードやダウンロード方法も載っている。)
[Azure Storageへのアクセス方法 【Shared Access Signatures (SAS)】](https://qiita.com/snomoto/items/c2793866dee81b4718e9)

#### SASトークン作成
ファイルのダウンロードにはストレージアカウント名とストレージアカウントキーそして、ダウンロードが格納されているコンテナ名が必要。
`azureblob.ContainerPermissions`でどのアクセス許可を指定可能。

```python:create_sas.py
def create_sas(account_name, account_key, container_name):
    blob_client = azureblob.BlockBlobService(account_name=account_name, account_key=account_key)
    expiry = datetime.now(timezone('UTC'))  + timedelta(minutes=6)
    permission = azureblob.ContainerPermissions(read=True, write=True)
    sas = blob_client.generate_container_shared_access_signature(container_name,permission=permission,expiry=expiry)
    return sas
```
#### ダウンロード部分
ファイルのダウンロードにはストレージアカウント名とストレージアカウントキーそして、ダウンロードが格納されているコンテナ名が必要。

```python:download.py
def download(account_name, account_key, container_name, download_file, download_dir):
    sas_token = create_sas(account_name, account_key, container_name)
    blob_client = azureblob.BlockBlobService(account_name=account_name, account_key=account_key, sas_token=sas_token)
    dl_file = "{}/{}".format(download_dir, download_file)
    blob_client.get_blob_to_path(container_name, download_file, dl_file)
```

またコンテナのファイルすべてをダウンロードしたい場合は以下のようなコードとなる。
ただ、このソースだと、コンテナ内に仮想ディレクトリがある場合、事前にダウンロードディレクトリに同じ名前のディレクトリを用意しておかないと行けないので注意

```python:download.py
def download(account_name, account_key, container_name, download_file, download_dir):
    sas_token = create_sas(account_name, account_key, container_name)
    blob_client = azureblob.BlockBlobService(account_name=account_name, account_key=account_key, sas_token=sas_token)
    generator = blob_client.list_blobs(container_name)
    for blob in generator:
        dl_file = "{}/{}".format(download_dir, os.path.dirname(blob.name))
        dl_dir = os.path.dirname(dl_file)
        blob_client.get_blob_to_path(container_name, blob.name, dl_file)
```
#### アップロード部分
アップロードする際に`azureblob.models.ContentSettings`でアップロードするファイルのtype以外にもファイルのencodingなども設定することが可能。

```python:upload.py
def upload(account_name, account_key, container_name, upload_file):
    sas_token = create_sas(container_name)
    blob_client = azureblob.BlockBlobService(account_name=account_name, account_key=account_key, sas_token=sas_token)
    content_settings = azureblob.models.ContentSettings(content_type='application/octet-stream')
    upload_name = os.path.basename(upload_file)
    blob_client.create_blob_from_path(container_name, upload_name, upload_file, content_settings)
```
## 参照
[クイック スタート: Python を使用して BLOB をアップロード、ダウンロード、および一覧表示する](https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-python)