FastAPI结合aioboto3实现流式文件下载的问题求助
解决FastAPI代理S3文件流式传输阻塞问题
你当前的代码没有充分利用AsyncStreamingBody的异步迭代能力,通过指定分块大小并使用异步生成器,就能实现按n MiB块持续下载并流式传输文件,修正后的实现如下:
from fastapi import FastAPI, StreamingResponse import aioboto3 app = FastAPI() session = aioboto3.Session() # 定义分块大小,例如设置为2MiB(可根据需求调整) CHUNK_SIZE = 2 * 1024 * 1024 # 单位:字节 @app.get('/s3/{file_name:path}') async def file_proxy(file_name: str): async with session.client('s3', region_name='你的区域') as s3: # 获取S3对象的元数据和流,此步骤不会下载整个文件 s3_response = await s3.get_object(Bucket='bucket-name', Key=file_name) async def stream_file_chunks(): # 按指定块大小异步迭代读取S3文件流 async for chunk in s3_response['Body'].iter_chunks(chunk_size=CHUNK_SIZE): yield chunk # 从S3响应中获取文件类型,默认使用二进制流类型 content_type = s3_response.get('ContentType', 'application/octet-stream') return StreamingResponse( stream_file_chunks(), media_type=content_type, headers={ 'Content-Disposition': f'inline; filename="{file_name}"', 'Content-Length': str(s3_response['ContentLength']) } )
核心要点说明:
- 异步生成器
stream_file_chunks:通过async for遍历S3的异步流,每读取一块就立即推送给客户端,避免整个请求阻塞到文件完全下载。 - 自定义分块大小:
CHUNK_SIZE可根据需求设置为n MiB,只需将数值转换为对应字节数(1MiB = 1024*1024字节)。 - 响应头优化:添加
Content-Type、Content-Disposition和Content-Length,让客户端能正确识别文件类型、名称和总大小,提升传输兼容性。 - 资源正确释放:使用
async with管理S3客户端,确保请求结束后资源自动回收。
这段代码会实现真正的流式传输——读取一小块文件就立即返回给客户端,无需等待整个文件下载完成。
内容的提问来源于stack exchange,提问作者ffempegging
相关产品推荐
相关产品推荐

