Azure存储异步操作报错:str不能用于await表达式求助
问题根源分析
错误"str can't be used in await expression"是因为代码中尝试await一个字符串对象,具体出现在await stream.readall()这一行——此时stream并非预期的AsyncBlobDownloader实例,而是下载过程中返回的错误信息字符串。
导致问题的核心原因:
- 异步上下文管理器使用错误:将
self.credential和self.blob_service_client放在同一个async with语句中,不符合异步上下文管理器的正确使用规范,导致凭证未正确初始化,进而使下载操作返回错误字符串而非Blob流。 - 不必要的手动资源关闭:在
async with上下文内,BlobServiceClient会自动管理子资源(如BlobClient)的生命周期,手动调用await blob_client.close()可能引发资源冲突。
修复后的代码
from azure.storage.blob.aio import BlobServiceClient from azure.identity.aio import DefaultAzureCredential import io class BlobService(object): def __init__(self, blob_name, blob_url, client_id) -> None: print(blob_name, blob_url, client_id) self.blob_name = blob_name self.blob_url = blob_url self.credential = None self.blob_service_client = None try: self.credential = DefaultAzureCredential( managed_identity_client_id=client_id, exclude_environment_credential=True, exclude_cli_credential=True, exclude_powershell_credential=True, exclude_visual_studio_code_credential=True, exclude_shared_token_cache_credential=True, exclude_interactive_browser_credential=True ) print("Default cred working") except Exception as e: print("Default cred error: ", e) try: self.blob_service_client = BlobServiceClient( account_url=blob_url, credential=self.credential ) print("Blob cred working") except Exception as e: print("Blobservice error : ", e) async def get_blob(self, copy_from_container): print("Downloading file from container using managed identity") # 正确嵌套异步上下文管理器,确保凭证与服务客户端资源正常初始化 async with self.credential: async with self.blob_service_client as blob_service_client: blob_client = blob_service_client.get_blob_client( container=copy_from_container, blob=self.blob_name ) # 获取异步Blob下载器实例 stream = await blob_client.download_blob() print("Download complete using managed identity") # 读取字节流并解码为字符串,拆分逻辑提升可读性 blob_content = await stream.readall() return_data = io.StringIO(blob_content.decode("utf-8")) return return_data
关键修复点
- 拆分嵌套异步上下文:将凭证与Blob服务客户端的上下文管理器分开嵌套,确保两者都能正确完成资源初始化与释放。
- 移除手动关闭操作:删除
await blob_client.close(),由上下文管理器自动处理子资源的生命周期。 - 简化读取逻辑:将字节流读取与解码操作拆分,避免嵌套表达式引发的潜在问题,同时提升代码可维护性。
内容的提问来源于stack exchange,提问作者TalendDeveloper
相关产品推荐
相关产品推荐

