1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

BlobをREST APIでダウンロード【Azure,Python】

Last updated at Posted at 2021-06-01

はじめに

AzureのREST APIでBlobをダウンロードしたのですが忘れそうなのでメモです。Pythonで実行しました。共有キーによる認証でクライアント側がアクセスキーを知っている必要があるのでサーバからリクエストするときとかはこれで大丈夫かな?

環境

  • Azureのストレージアカウントを持っている
  • Python3.6(Anaconda)

HTTPリクエストをするのでpip install requestsしておきます。urllibが使える人はそっちでも大丈夫です。

やること

雑にコードを載せます。myaccountはストレージアカウント名、mycontainerはコンテナ名、myaccess_keyはアクセスキーでそれぞれ自分のものに置き換えてください。アクセスキーはここを参考に確認してください。

# 必要なライブラリのimport
import base64
import hashlib
import hmac
from urllib.parse import quote, unquote
import requests
import datetime

# 自分のアクセスキーで置き換える
access_key = 'myaccess_key'
# 操作したいblobのurl
blob_url = 'https://myaccount.blob.core.windows.net/mycontainer/test.png'

# 必須のヘッダー
x_ms_date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT') #曜日, dd 月 yyyy hh:mm:ss GMT
x_ms_version = "2020-08-04"

# 改行の数などはこの通りに
# 最後の行はクエリとかがある場合はそれもいるっぽい(未確認)
StringToSign = \
    "GET\n\n\n\n\n\n\n\n\n\n\n\n"+ \
    "x-ms-date:" + x_ms_date + "\n" + \
    "x-ms-version:" + x_ms_version + "\n" + \
    "/myaccount/mycontainer/test.png" 

# 使う関数を定義
def url_quote(url):
    return quote(url)

def encode_base64(data):
    if isinstance(data, str):
        data = data.encode('utf-8')
    encoded = base64.b64encode(data)
    return encoded.decode('utf-8')

def decode_base64_to_bytes(data):
    if isinstance(data, str):
        data = data.encode('utf-8')
    return base64.b64decode(data)

def decode_base64_to_text(data):
    decoded_bytes = decode_base64_to_bytes(data)
    return decoded_bytes.decode('utf-8')

def decode_base64_to_text(data):
    decoded_bytes = decode_base64_to_bytes(data)
    return decoded_bytes.decode('utf-8')

def sign_string(key, string_to_sign, key_is_base64=True):
    if key_is_base64:
        key = decode_base64_to_bytes(key)
    else:
        if isinstance(key, str):
            key = key.encode('utf-8')
    if isinstance(string_to_sign, str):
        string_to_sign = string_to_sign.encode('utf-8')
    signed_hmac_sha256 = hmac.HMAC(key, string_to_sign, hashlib.sha256)
    digest = signed_hmac_sha256.digest()
    encoded_digest = encode_base64(digest)
    return encoded_digest

# アクセスキーとStringToSignを使って署名を作成
signature = sign_string(access_key,StringToSign)

# headerには以下の3つを入れる(PUTとかだと他にもいるかも)
headers = {
    "x-ms-date": x_ms_date,
    "x-ms-version":x_ms_version,
    "Authorization":"SharedKey myaccount:"+signature
}

# 署名を使ってREST APIをたたく
response = requests.get(blob_url,headers=headers)

# 保存用
if response.status_code >= 400:
    print(response.text)
else:
    results = response.content
    with open('./test.png', 'wb') as f:
        f.write(results)

あいまいなところがありすみません。
StringToSignの改行には意味があります。詳しくは**ここ**をご覧ください。

リクエストヘッダーに必要なものやURL、メソッドについては**REST APIのリファレンス**を参照してください。

関数はAzure SDK for Pythonを参考にしてます(リンク)。

おわりに

requestsじゃなくてurllib使えるならPython標準ライブラリだけで実装できるのでAWS Lambda使うときにはLayerを追加しなくて済みます。

何か間違いがあればご指摘よろしくお願いします。

参考

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?