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

Python中如何将FileStorage对象转为b2sdk.v2.AbstractUploadSource

问题原因

AttributeError: 'SpooledTemporaryFile' object has no attribute 'get_content_length'

你的API调用方式确实不符合b2sdk的参数要求:b2sdk.v2的bucket.upload方法要求upload_source参数为SDK内置的上传源类型,这些类型统一实现了get_content_length方法用于校验上传内容长度,而Flask的FileStorage实例底层封装的SpooledTemporaryFile没有对应实现,因此触发报错。
另外你现有代码存在冗余问题:函数已经定义了file参数,后续又用file = request.files['file']覆盖了参数值,可根据实际业务逻辑调整。

解决方案

方案1:小文件场景(直接读取字节上传)

适合上传文件体积不大的场景,直接将文件内容读取为字节后用SDK提供的UploadSourceBytes封装即可:

# 新增导入
from b2sdk.v2 import UploadSourceBytes

# 此处省略授权相关代码
def upload_file():
    bucket = b2_api.get_bucket_by_name(bucket_name)
    file_obj = request.files['file']
    # 读取文件内容封装为SDK要求的上传源
    upload_source = UploadSourceBytes(file_obj.read())
    bucket.upload(
        upload_source=upload_source,
        file_name=file_obj.filename,
    )

方案2:大文件场景(流式上传避免内存占用过高)

如果上传文件体积较大,全量读入内存会影响服务性能,可以使用UploadSourceStream封装文件流,手动传入内容长度:

# 新增导入
from b2sdk.v2 import UploadSourceStream

# 此处省略授权相关代码
def upload_file():
    bucket = b2_api.get_bucket_by_name(bucket_name)
    file_obj = request.files['file']
    # 获取文件长度,优先取请求头中的content-length
    content_length = file_obj.content_length
    if not content_length:
        # 若请求头未传长度则手动读取计算
        file_obj.seek(0)
        content_length = len(file_obj.read())
        file_obj.seek(0)
    # 封装为流式上传源
    upload_source = UploadSourceStream(file_obj, content_length)
    bucket.upload(
        upload_source=upload_source,
        file_name=file_obj.filename,
    )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:09:04