Скачивание большого двоичного объекта с помощью Python

В этой статье показано, как скачать большой двоичный объект с помощью клиентской библиотеки служба хранилища Azure для Python. Данные BLOB-объектов можно скачать в различные места назначения, включая локальный путь к файлу, поток или текстовую строку. Вы также можете открыть поток BLOB-объектов и прочитать из него.

Сведения о скачивании больших двоичных объектов с помощью асинхронных API см. в статье "Загрузка больших двоичных объектов" асинхронно.

Необходимые компоненты

  • В этой статье предполагается, что у вас уже есть проект, настроенный для работы с клиентской библиотекой Хранилище BLOB-объектов Azure для Python. Сведения о настройке проекта, включая установку пакета, добавление import инструкций и создание авторизованного клиентского объекта, см. в статье "Начало работы с Хранилище BLOB-объектов Azure и Python".
  • Сведения об использовании асинхронных API в коде см. в разделе " Асинхронное программирование ".
  • Механизм авторизации должен иметь разрешения для выполнения операции скачивания. Дополнительные сведения см. в руководстве по авторизации для следующей операции REST API:

Скачивание большого двоичного объекта

Для скачивания большого двоичного объекта можно использовать следующий метод:

Метод download_blob возвращает объект служба хранилища StreamDownloader. Во время скачивания клиентские библиотеки разбиваются запрос на скачивание на блоки, где каждый блок загружается с отдельным запросом на получение диапазона BLOB-объектов . Это поведение зависит от общего размера большого двоичного объекта и способа установки параметров передачи данных.

Загрузка по пути к файлу

В следующем примере большой двоичный объект загружается в путь к файлу:

def download_blob_to_file(self, blob_service_client: BlobServiceClient, container_name):
    blob_client = blob_service_client.get_blob_client(container=container_name, blob="sample-blob.txt")
    with open(file=os.path.join(r'filepath', 'filename'), mode="wb") as sample_blob:
        download_stream = blob_client.download_blob()
        sample_blob.write(download_stream.readall())

Скачивание в поток

В следующем примере выполняется скачивание большого двоичного объекта в поток. В этом примере служба хранилищаStreamDownloader.read_into загружает содержимое большого двоичного объекта в поток и возвращает количество байтов, считываемых:

def download_blob_to_stream(self, blob_service_client: BlobServiceClient, container_name):
    blob_client = blob_service_client.get_blob_client(container=container_name, blob="sample-blob.txt")

    # readinto() downloads the blob contents to a stream and returns the number of bytes read
    stream = io.BytesIO()
    num_bytes = blob_client.download_blob().readinto(stream)
    print(f"Number of bytes: {num_bytes}")

Скачивание большого двоичного объекта в блоках

В следующем примере скачивается большой двоичный объект и выполняется итерацию по блокам в потоке загрузки. В этом примере служба хранилища StreamDownloader.chunks возвращает итератор, который позволяет считывать содержимое большого двоичного объекта в блоках:

def download_blob_chunks(self, blob_service_client: BlobServiceClient, container_name):
    blob_client = blob_service_client.get_blob_client(container=container_name, blob="sample-blob.txt")

    # This returns a StorageStreamDownloader
    stream = blob_client.download_blob()
    chunk_list = []

    # Read data in chunks to avoid loading all into memory at once
    for chunk in stream.chunks():
        # Process your data (anything can be done here - 'chunk' is a byte array)
        chunk_list.append(chunk)

Скачивание в строку

В следующем примере содержимое большого двоичного объекта загружается в виде текста. В этом примере encoding параметр необходим для readall() возврата строки, в противном случае он возвращает байты:

def download_blob_to_string(self, blob_service_client: BlobServiceClient, container_name):
    blob_client = blob_service_client.get_blob_client(container=container_name, blob="sample-blob.txt")

    # encoding param is necessary for readall() to return str, otherwise it returns bytes
    downloader = blob_client.download_blob(max_concurrency=1, encoding='UTF-8')
    blob_text = downloader.readall()
    print(f"Blob contents: {blob_text}")

Скачивание блочного BLOB-объекта с параметрами конфигурации

При скачивании большого двоичного объекта можно определить параметры конфигурации клиентской библиотеки. Эти параметры можно настроить для повышения производительности и повышения надежности. В следующих примерах кода показано, как определить параметры конфигурации для скачивания как на уровне метода, так и на уровне клиента при создании экземпляра BLOBClient. Эти параметры также можно настроить для экземпляра ContainerClient или экземпляра BlobServiceClient.

Указание параметров передачи данных при загрузке

Параметры конфигурации можно задать при создании экземпляра клиента для оптимизации производительности операций передачи данных. При создании клиентского объекта в Python можно передать следующие ключевое слово аргументы:

  • max_chunk_get_size — максимальный размер блока, используемый для скачивания большого двоичного объекта. По умолчанию — 4 МиБ.
  • max_single_get_size — максимальный размер большого двоичного объекта для скачивания в одном вызове. Если общий размер большого двоичного объекта превышается max_single_get_size, остальные данные большого двоичного объекта скачиваются в блоках. По умолчанию — 32 МиБ.

Для операций загрузки можно также передать max_concurrency аргумент при вызове download_blob. Этот аргумент определяет максимальное количество параллельных подключений для операции скачивания.

В следующем примере кода показано, как указать параметры передачи данных при создании BlobClient объекта и как скачать данные с помощью этого клиентского объекта. Значения, указанные в этом примере, не предназначены для рекомендации. Чтобы правильно настроить эти значения, необходимо учитывать конкретные потребности приложения.

def download_blob_transfer_options(self, account_url: str, container_name: str, blob_name: str):
    # Create a BlobClient object with data transfer options for download
    blob_client = BlobClient(
        account_url=account_url, 
        container_name=container_name, 
        blob_name=blob_name,
        credential=DefaultAzureCredential(),
        max_single_get_size=1024*1024*32, # 32 MiB
        max_chunk_get_size=1024*1024*4 # 4 MiB
    )

    with open(file=os.path.join(r'file_path', 'file_name'), mode="wb") as sample_blob:
        download_stream = blob_client.download_blob(max_concurrency=2)
        sample_blob.write(download_stream.readall())

Асинхронное скачивание BLOB-объектов

Клиентская библиотека Хранилище BLOB-объектов Azure для Python поддерживает асинхронную загрузку больших двоичных объектов. Дополнительные сведения о требованиях к настройке проекта см. в статье асинхронное программирование.

Выполните следующие действия, чтобы скачать большой двоичный объект с помощью асинхронных API:

  1. Добавьте в файл следующие операторы импорта:

    import asyncio
    
    from azure.identity.aio import DefaultAzureCredential
    from azure.storage.blob.aio import BlobServiceClient, BlobClient
    
  2. Добавьте код для запуска программы с помощью asyncio.run. Эта функция запускает переданную корутину в main() нашем примере и управляет циклом asyncio событий. Корутины объявляются с синтаксисом async/await. В этом примере main() корутин сначала создает верхний уровень BlobServiceClient с помощью async with, а затем вызывает метод, который скачивает большой двоичный объект. Обратите внимание, что использовать только клиент верхнего уровня, так как другие клиенты, созданные из него, используют async withтот же пул подключений.

    async def main():
        sample = BlobSamples()
    
        # TODO: Replace <storage-account-name> with your actual storage account name
        account_url = "https://<storage-account-name>.blob.core.windows.net"
        credential = DefaultAzureCredential()
    
        async with BlobServiceClient(account_url, credential=credential) as blob_service_client:
            await sample.download_blob_to_file(blob_service_client, "sample-container")
    
    if __name__ == '__main__':
        asyncio.run(main())
    
  3. Добавьте код для скачивания большого двоичного объекта. В следующем примере большой двоичный объект загружается в локальный путь к файлу BlobClient с помощью объекта. Код совпадает с синхронным примером, за исключением того, что метод объявляется с async ключевое слово, а await при вызове download_blob метода используется ключевое слово.

    async def download_blob_to_file(self, blob_service_client: BlobServiceClient, container_name):
        blob_client = blob_service_client.get_blob_client(container=container_name, blob="sample-blob.txt")
        with open(file=os.path.join(r'filepath', 'filename'), mode="wb") as sample_blob:
            download_stream = await blob_client.download_blob()
            data = await download_stream.readall()
            sample_blob.write(data)
    

С помощью этой базовой настройки вы можете реализовать другие примеры в этой статье в качестве корутин с помощью синтаксиса async/await.

Ресурсы

Дополнительные сведения о том, как скачать большие двоичные объекты с помощью клиентской библиотеки Хранилище BLOB-объектов Azure для Python, см. в следующих ресурсах.

Операции REST API

Пакет SDK Azure для Python содержит библиотеки, которые создаются на основе REST API Azure, что позволяет взаимодействовать с операциями REST API с помощью знакомых парадигм Python. Методы клиентской библиотеки для скачивания больших двоичных объектов используют следующую операцию REST API:

Примеры кода

Ресурсы клиентской библиотеки