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

使用Azure upload_blob上传Starlette UploadFile报错:非路径类对象

问题:Starlette UploadFile 上传到 Azure Blob Storage 报错

通过客户端向Python编写的GraphQL服务器发送multipart文件,服务器接收为<starlette.datastructures.UploadFile object>。尝试使用Azure Storage的upload_blob方法上传时,出现错误:expected str, bytes or os.PathLike object, not UploadFile。已按照Starlette文档使用file.read()读取文件内容,以下是实现代码及报错堆栈。

原实现代码

@mutation.field("fileUpload")
async def resolve_fileUpload(_, info, file):
    print(f"File - {file.filename}")
    bytes_file = await file.read()
    container_client = blob_service_client.get_container_client(
        '4160000000')
    if not container_client.exists():
        container_client.create_container()

    with open(file, "rb") as file:
        result = container_client.upload_blob(
            name='avatar', data=bytes_file)
    return {
        "status": 200,
        "error": "",
        "fileUrl": "www.test.com"
    }

报错堆栈信息

[2023-06-07T16:30:47.294Z] expected str, bytes or os.PathLike object, not UploadFile

GraphQL request:3:3
2 |   __typename
3 |   fileUpload(file: $file) {
  |   ^
4 |   __typename
Traceback (most recent call last):
  File "C:\Users\sumch\AppData\Local\Programs\Python\Python310\lib\site-packages\graphql\execution\execute.py", line 528, in await_result
    return_type, field_nodes, info, path, await result
  File "C:\Users\sumch\OneDrive\Projects\Flutter Projects\bol\bol-api\bol-api\user_operations\mutations.py", line 86, in resolve_fileUpload        
    with open(file, "rb") as file:
TypeError: expected str, bytes or os.PathLike object, not UploadFile

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\sumch\AppData\Local\Programs\Python\Python310\lib\site-packages\graphql\execution\execute.py", line 1036, in await_result
    return build_response(await result, errors)  # type: ignore
  File "C:\Users\sumch\AppData\Local\Programs\Python\Python310\lib\site-packages\graphql\execution\execute.py", line 403, in set_result
    results[response_name] = await result
  File "C:\Users\sumch\AppData\Local\Programs\Python\Python310\lib\site-packages\graphql\execution\execute.py", line 535, in await_result
    self.handle_field_error(error, return_type)
  File "C:\Users\sumch\AppData\Local\Programs\Python\Python310\lib\site-packages\graphql\execution\execute.py", line 569, in handle_field_error    
    raise error
  File "C:\Users\sumch\AppData\Local\Programs\Python\Python310\lib\site-packages\graphql\execution\execute.py", line 528, in await_result
    return_type, field_nodes, info, path, await result
  File "C:\Users\sumch\OneDrive\Projects\Flutter Projects\bol\bol-api\bol-api\user_operations\mutations.py", line 86, in resolve_fileUpload        
    with open(file, "rb") as file:
graphql.error.graphql_error.GraphQLError: expected str, bytes or os.PathLike object, not UploadFile

GraphQL request:3:3
2 |   __typename
3 |   fileUpload(file: $file) {
  |   ^
4 |   __typename

错误原因

报错核心是代码中with open(file, "rb") as file:这一行:open()函数仅接受文件路径字符串、字节或路径对象,无法直接处理UploadFile实例。而且你已经通过await file.read()将文件内容读取到bytes_file变量中,这段open操作完全多余,反而引发了类型错误。

另外,Azure的upload_blob方法本身支持直接传入字节数据,无需额外打开文件。

修正后的代码

@mutation.field("fileUpload")
async def resolve_fileUpload(_, info, file):
    print(f"File - {file.filename}")
    bytes_file = await file.read()
    container_client = blob_service_client.get_container_client('4160000000')
    
    if not container_client.exists():
        container_client.create_container()

    # 直接使用读取到的字节数据上传,移除多余的open操作
    result = container_client.upload_blob(name='avatar', data=bytes_file)
    
    return {
        "status": 200,
        "error": "",
        "fileUrl": "www.test.com"
    }

大文件优化方案(可选)

如果处理大文件,为避免一次性将文件内容加载到内存,可以直接传入UploadFile的底层类文件对象实现流式上传:

@mutation.field("fileUpload")
async def resolve_fileUpload(_, info, file):
    print(f"File - {file.filename}")
    container_client = blob_service_client.get_container_client('4160000000')
    
    if not container_client.exists():
        container_client.create_container()

    # 直接传入UploadFile的底层文件对象,流式上传节省内存
    result = container_client.upload_blob(name='avatar', data=file.file)
    
    return {
        "status": 200,
        "error": "",
        "fileUrl": "www.test.com"
    }

内容的提问来源于stack exchange,提问作者Sumchans

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:50:22