基于FastAPI与Python Requests的HTTP大视频可靠传输问询
50MB级视频文件上传稳定实现方案(FastAPI + Python Requests)
服务端(FastAPI)实现
FastAPI基于Starlette框架,默认请求体大小上限仅1MB,必须先调整上限,同时采用分块写盘逻辑,避免大文件占满内存导致服务崩溃。
import os from fastapi import FastAPI, UploadFile, File # 全局请求大小上限设为100MB,留足冗余容纳50MB视频+请求头、附加字段开销 app = FastAPI(client_max_size=100 * 1024 * 1024) # 视频存储目录,不存在则自动创建 SAVE_DIR = "./uploaded_videos" os.makedirs(SAVE_DIR, exist_ok=True) @app.post("/upload_video/") async def upload_video(video_file: UploadFile = File(...)): # 基础格式校验,拦截非视频文件 if not video_file.content_type.startswith("video/"): return {"code": 400, "msg": "仅支持上传视频文件"} save_path = os.path.join(SAVE_DIR, video_file.filename) # 单块1MB分块写入磁盘,禁止一次性读取全量文件到内存 with open(save_path, "wb") as f: while chunk := await video_file.read(1024 * 1024): f.write(chunk) return { "code": 200, "msg": "上传成功", "data": { "file_name": video_file.filename, "saved_path": save_path } }
如果你用Nginx做反向代理,必须在Nginx配置中添加
client_max_body_size 100M;,否则Nginx会在请求到达FastAPI前直接拦截大文件,返回413错误。
客户端(Python Requests)实现
采用流式上传逻辑,不要手动全量读取文件,设置合理超时避免传输中途被强制断开。
import requests UPLOAD_ENDPOINT = "http://你的服务端地址/upload_video/" LOCAL_VIDEO_PATH = "./your_local_video.mp4" def upload_large_video(): # 二进制模式打开文件,Requests会自动做分块流式上传,不会全量加载到内存 with open(LOCAL_VIDEO_PATH, "rb") as f: upload_files = { "video_file": ( "uploaded_video.mp4", # 上传到服务端的文件名 f, "video/mp4" # 根据实际视频格式调整MIME类型,mov对应video/quicktime ) } # 超时配置:(连接超时时间, 读取超时时间),读取超时留足上传时间,120秒适配绝大多数网络场景 resp = requests.post( UPLOAD_ENDPOINT, files=upload_files, timeout=(10, 120) ) resp.raise_for_status() # 遇到4xx/5xx错误直接抛出异常,方便排查问题 return resp.json() if __name__ == "__main__": res = upload_large_video() print("上传返回结果:", res)
稳定性优化注意事项
- 禁止在服务端或客户端代码中调用
.read()一次性读取整个视频文件,全量加载到内存极易触发OOM导致程序崩溃,分块读写是大文件传输的核心原则 - 超时时间根据实际网络情况调整,普通家庭宽带上行带宽多为10-50Mbps,50MB文件理论传输时间为10-40秒,留2-3倍冗余即可,不要用过短的默认超时
- 服务端存储文件时建议做重名处理,比如给文件名加时间戳、随机串后缀,避免不同用户上传同名文件被覆盖
- 对文件完整性要求高的场景,可以加校验逻辑:客户端提前计算视频文件的MD5/SHA256值,随请求传给服务端,服务端存完文件后重新计算哈希比对,值一致才算上传成功,避免传输过程中文件损坏
- 50MB属于中等体积文件,网络稳定的场景不需要额外做分片断点续传;如果是跨公网、网络波动大的场景,再考虑增加分片、断点续传逻辑即可
内容的提问来源于stack exchange,提问作者Arkadip Bhattacharya
相关产品推荐
相关产品推荐

