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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 02:15:03