2025/02/14

使用 Python request 連接 Azure Blob Storage

輸入下方指令安裝套件
pip install requests

代碼如下:
import requests
from datetime import datetime, UTC
import hmac
import hashlib
import base64


def get_auth_signature(account_name: str, account_key: str, container_name: str, timestamp: str) -> str:
    """
    取得 Azure Blob Storage 的簽章
    :param account_name: 帳號名稱
    :param account_key: 帳號金鑰
    :param container_name: 容器名稱
    :param timestamp: 時間戳記
    :return: 簽章字串
    """

    # 定義資源順序
    resource_path = f'/{account_name}/{container_name}'
    # 組合簽章字串
    string_to_sign = (
        'GET\n'  # HTTP 動詞
        '\n'  # Content-Encoding
        '\n'  # Content-Language
        '\n'  # Content-Length
        '\n'  # Content-MD5
        '\n'  # Content-Type
        '\n'  # Date
        '\n'  # If-Modified-Since
        '\n'  # If-Match
        '\n'  # If-None-Match
        '\n'  # If-Unmodified-Since
        '\n'  # Range
        f'x-ms-date:{timestamp}\n'  # x-ms-date
        f'x-ms-version:{azure_version}\n'  # x-ms-version
        f'{resource_path}\n'  # CanonicalizedResource
        'comp:list\n'  # Query params in lexicographical order
        'restype:container'  # Query params in lexicographical order
    )

    print("String to sign (raw):\n" + string_to_sign)

    # 計算簽章
    key = base64.b64decode(account_key)
    string_to_sign_bytes = string_to_sign.encode('utf-8')
    hmac_sha256 = hmac.new(key, string_to_sign_bytes, hashlib.sha256)
    signature = base64.b64encode(hmac_sha256.digest()).decode()

    return f"SharedKey {account_name}:{signature}"


# 主程式
account_name = ""
account_key = ""
container_name = ""
# ref https://learn.microsoft.com/en-us/rest/api/storageservices/previous-azure-storage-service-versions
azure_version = "2025-01-05"
timestamp = datetime.now(UTC).strftime('%a, %d %b %Y %H:%M:%S GMT')

# https://learn.microsoft.com/en-us/rest/api/storageservices/list-blobs?tabs=microsoft-entra-id
url = f"https://{account_name}.blob.core.windows.net/{container_name}?restype=container&comp=list"
headers = {
    'x-ms-date': timestamp,
    'x-ms-version': f'{azure_version}',
    'Authorization': get_auth_signature(account_name, account_key, container_name, timestamp)
}

print("\nRequest URL:", url)
print("Headers:", headers)

response = requests.get(url, headers=headers)
print("\nResponse:", response.text)