使用python API列出Azure BlobStorage上的文件

问题描述

代码尝试列出Blob存储中的文件

#!/usr/bin/env python3

import os

from azure.storage.blob import BlobServiceClient,BlobClient,ContainerClient,__version__
from datetime import datetime,timedelta
import azure.cli.core as az

print(f"Azure Blob storage v{__version__} - Python quickstart sample")

account_name = "my_account"
container_name = "my_container"
path_on_datastore = "test/path"

def _create_sas(expire=timedelta(seconds=10)) -> str:
    cli = az.get_default_cli()

    expire_date = datetime.utcNow() + expire
    expiry_string = datetime.strftime(expire_date,"%Y-%m-%dT%H:%M:%sZ")
    cmd = ["storage","container","generate-sas","--name",container_name,"--account-name",account_name,"--permissions","lr","--expiry",expiry_string,"--auth-mode","login","--as-user"]
    if cli.invoke(cmd) != 0:
        raise RuntimeError("Could not receive a SAS token for user {}@{}".format(
            account_name,container_name))

    return cli.result.result


sas = _create_sas()
blob_service_client = BlobServiceClient(
    account_url=f"{account_name}.blob.core.windows.net",container_name=container_name,credential=sas)

container_client = blob_service_client.create_container(container_name)
blob_list = container_client.list_blobs()
for blob in blob_list:
    print("\t" + blob.name)

代码在几周前运行良好,但随后我们总是收到错误消息:

azure.core.exceptions.ClientAuthenticationError:服务器无法验证请求。确保包括签名在内的Authorization标头的值正确形成。

有人知道什么是错的吗?

PS。使用版本12.3.2的Azure blob存储包。

[编辑]

出于安全方面的考虑,我们不允许在此处使用帐户密钥。

解决方法

我不太确定您的代码有什么问题,但是看起来您的SAS令牌不是预期的格式。您是否测试过SAS URL是否可在浏览器中使用?

此外,您的_create_sas函数似乎正在使用Azure CLI命令创建SAS签名。我认为您不需要这样做,因为azure-storage-blob程序包具有generate_account_sas之类的方法来生成SAS签名。这将消除很多复杂性,因为您无需担心SAS签名格式。

from datetime import datetime,timedelta
from azure.storage.blob import (
    BlobServiceClient,generate_account_sas,ResourceTypes,AccountSasPermissions,)
from azure.core.exceptions import ResourceExistsError

account_name = "<account name>"
account_url = f"https://{account_name}.blob.core.windows.net"
container_name = "<container name>"

# Create SAS token credential
sas_token = generate_account_sas(
    account_name=account_name,account_key="<account key>",resource_types=ResourceTypes(container=True),permission=AccountSasPermissions(read=True,write=True,list=True),expiry=datetime.utcnow() + timedelta(hours=1),)

为该SAS签名授予对blob容器的读取,写入和列出权限,有效时间为1小时。您可以根据自己的喜好将其更改。

然后我们可以使用此SAS签名作为凭证来创建BlobServiceClient,然后创建容器客户端以列出blob。

# Create Blob service client to interact with storage account
# Use SAS token as credential
blob_service_client = BlobServiceClient(account_url=account_url,credential=sas_token)

# First try to create container
try:
    container_client = blob_service_client.create_container(name=container_name)

# If container already exists,fetch the client
except ResourceExistsError:
    container_client = blob_service_client.get_container_client(container=container_name)

# List blobs in container
for blob in container_client.list_blobs():
    print(blob.name)

注意:上面使用的是azure-storage-blob==12.5.0版,这是最新的软件包。这与您的版本相比并不太遥远,因此我可能会更新您的代码以使用最新功能,如文档中所提供的那样。


更新

如果出于安全原因无法使用帐户密钥,则可以创建服务主体并将其赋予Storage Blob Data Contributor角色到您的存储帐户。它将作为AAD应用程序创建,可以访问您的存储帐户。

要进行此设置,可以使用文档中的guide

示例代码

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient
token_credential = DefaultAzureCredential()

blob_service_client = BlobServiceClient(
    account_url="https://<my_account_name>.blob.core.windows.net",credential=token_credential
)
,

该模块似乎已弃用:

从v5.0.0开始,“ azure”元软件包已被弃用,不能 安装了。请安装特定于服务的软件包,前缀为 您的应用需要azure

可用软件包的完整列表可以在以下位置找到: https://aka.ms/azsdk/python/all

可以找到对该决定的原理进行更全面的讨论 在以下问题中: https://github.com/Azure/azure-sdk-for-python/issues/10646