Получение списка файлов в Azure BlobStorage с помощью API Python

Этот код пытается вывести список файлов в хранилище 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. с помощью пакета хранилища BLOB-объектов Azure версии 12.3.2.

[Изменить]

Из соображений безопасности нам не разрешено использовать здесь ключи учетной записи.


person Matthias    schedule 03.11.2020    source источник


Ответы (2)


Я не совсем уверен, что не так с вашим кодом, но похоже, что ваш токен SAS не соответствует ожидаемому формату. Вы проверяли, работает ли URL-адрес SAS в браузере?

Кроме того, ваша функция _create_sas создает подпись SAS с помощью команды Azure CLI. Я не думаю, что вам нужно это делать, потому что 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 разрешения на чтение, запись и перечисление в контейнерах больших двоичных объектов со сроком действия 1 час. Вы можете изменить это по своему вкусу.

Затем мы можем создать BlobServiceClient с этой подписью SAS в качестве учетных данных, а затем создать клиент контейнера для вывода списка больших двоичных объектов.

# 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, которое будет иметь доступ к вашей учетной записи хранения.

Чтобы получить эту настройку, вы можете использовать этот руководство из документации.

Пример кода

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
)
person RoadRunner    schedule 03.11.2020
comment
Спасибо за быстрый ответ. Есть ли возможность создать токен sas без ключа учетной записи? - person Matthias; 04.11.2020
comment
@ Матиас, я в это не верю. Если вашей конечной целью является просто перечисление больших двоичных объектов, вы, вероятно, можете использовать субъект-службу для аутентификации в Azure AD. Это происходит через этот метод: github.com/Azure/azure-sdk-for-python/tree/master/sdk/storage/. - person RoadRunner; 04.11.2020
comment
Конечная цель состоит в том, чтобы перечислить и предоставить ссылку для скачивания (с sas) файлов. Из соображений безопасности нам не разрешено использовать ключ учетной записи. - person Matthias; 04.11.2020
comment
@ Матиас Понял. Я предоставил обновление, чтобы показать вам, как использовать субъект-службу. Если вам нужен наиболее безопасный вариант, то здесь лучше всего использовать управляемые удостоверения, поскольку они не используют учетные данные. - person RoadRunner; 04.11.2020

Похоже, модуль устарел:

Начиная с версии 5.0.0, метапакет Azure устарел и больше не может быть установлен. Установите пакеты для конкретных служб с префиксом azure, необходимые для вашего приложения.

Полный список доступных пакетов можно найти по адресу: https://aka.ms/azsdk/python/all

Более подробное обсуждение обоснования этого решения можно найти в следующем выпуске: https://github.com/Azure/azure-sdk-for-python/issues/10646

person Judev1    schedule 03.11.2020