python asyn c upload_blob - TypeError: объект AccessToken нельзя использовать в выражении 'await' - PullRequest
0 голосов
/ 29 марта 2020

Я использую Python 3.6.8 и следующие пакеты:

azure - обычно 1.1.25
azure - ядро ​​1.3.0
azure - identity 1.3.0
azure -nspkg 3.0.2
azure -storage-blob 12.3.0

Следующая строка в моем коде:

await blobClient.upload_blob(data, overwrite=True)

Дает мне трассировку стека с сообщением:

TypeError: object AccessToken can't be used in 'await' expression

Если я уберу 'await', код будет работать нормально, хотя он никогда не отдает управление другим задачам, но он отлично загружает большие двоичные объекты. Я использую асинхронную функцию upload_blob (). Я не могу понять, почему я получаю эту ошибку, какие-либо идеи?

Вот код без некоторых присвоений переменных:

from azure.identity import ClientSecretCredential
from azure.storage.blob.aio import BlobClient
import asyncio
import os

async def task(name, work_queue):
    """                                                                                                                                            
    """
    while not work_queue.empty():
        f = await work_queue.get()

        blobClient = BlobClient(
            "https://{}.blob.core.windows.net".format(accountName),
            credential = creds,
            container_name = container,
            blob_name = (f.replace(sourceDirPrefix, '')),
        )

        # Upload content to blob                                                                                                                   
        with open(f, "rb") as data:
            await blobClient.upload_blob(data, overwrite=True)


def main():
    """                                                                                                                                            
    This is the main entry point for the program                                                                                                   
    """
    # Create the queue of work                                                                                                                     
    work_queue = asyncio.Queue()

    # Put some work in the queue                                                                                                                   
    for (path, dirs, files) in os.walk(sourceDir):
        for f in files:
            work_queue.put_nowait(os.path.join(path, f))

    # Run the tasks                                                                                                                                
    loop = asyncio.get_event_loop()
    loop.run_until_complete(
        asyncio.gather(
            task("1", work_queue),
            task("2", work_queue),
            task("3", work_queue),
        )
    )
    loop.close()

Трассировка стека:

Traceback (most recent call last):
  File "test04.py", line 77, in <module>
    main()
  File "test04.py", line 70, in main
    task("3", work_queue),
  File "/usr/lib64/python3.6/asyncio/base_events.py", line 484, in run_until_complete
    return future.result()
  File "test04.py", line 44, in task
    await blobClient.upload_blob(data, overwrite=True, asyncio=True)
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/core/tracing/decorator_async.py", line 70, in wrapper_use_tracer
    return await func(*args, **kwargs)
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/storage/blob/aio/_blob_client_async.py", line 256, in upload_blob
    return await upload_block_blob(**options)
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/storage/blob/aio/_upload_helpers.py", line 79, in upload_block_blob
    **kwargs)
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/storage/blob/_generated/aio/operations_async/_block_blob_operations_async.py", line 207, in upload
    pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs)
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/core/pipeline/_base_async.py", line 213, in run
    return await first_node.send(pipeline_request)  # type: ignore
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/core/pipeline/_base_async.py", line 91, in send
    response = await self.next.send(request)  # type: ignore
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/core/pipeline/_base_async.py", line 91, in send
    response = await self.next.send(request)  # type: ignore
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/core/pipeline/_base_async.py", line 91, in send
    response = await self.next.send(request)  # type: ignore
  [Previous line repeated 3 more times]
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/core/pipeline/_base_async.py", line 89, in send
    await _await_result(self._policy.on_request, request)
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/core/pipeline/_base_async.py", line 62, in _await_result
    return await result  # type: ignore
  File "/work/python/venv_sm_36/lib/python3.6/site-packages/azure/core/pipeline/policies/_authentication_async.py", line 37, in on_request
    self._token = await self._credential.get_token(*self._scopes)  # type: ignore
TypeError: object AccessToken can't be used in 'await' expression

1 Ответ

1 голос
/ 30 марта 2020

В async def task(name, work_queue) метод -> после этой строки кода blobClient = BlobClient(xxx), вы должны использовать следующий код:

       async with blobClient:
            with open(f, "rb") as data:
                await blobClient.upload_blob(data, overwrite=True)

Завершенный метод:

async def task(name, work_queue):
    """                                                                                                                                            
    """
    while not work_queue.empty():
        f = await work_queue.get()

        blobClient = BlobClient(
            "https://{}.blob.core.windows.net".format(accountName),
            credential = creds,
            container_name = container,
            blob_name = (f.replace(sourceDirPrefix, '')),
        )

        async with blobClient:
            with open(f, "rb") as data:
                await blobClient.upload_blob(data, overwrite=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...