You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 10:24:49