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
相关产品推荐
相关产品推荐

