FastAPI接收CSV/Excel文件时出现422错误的解决咨询
解决FastAPI接收CSV/Excel文件时的422错误及优化方案
核心问题分析
422 Unprocessable Entity错误主要源于两个常见问题:
- 请求未以
multipart/form-data格式提交文件 - 代码中重复读取文件流:
await file.read()执行一次后,文件指针会移动到末尾,二次读取会得到空内容,导致pd.read_csv/pd.read_excel解析失败
具体修复步骤
1. 修复文件流重复读取问题
先一次性读取文件内容到内存,再复用该数据,避免二次读取空内容:
@app.post("/predict_file/") async def predict_file(file: UploadFile = File(...)): try: # 一次性读取文件内容到内存 file_content = await file.read() content_bytes = BytesIO(file_content) if file.filename.endswith(".csv"): df = pd.read_csv(content_bytes) elif file.filename.endswith(".xlsx"): df = pd.read_excel(content_bytes) else: raise HTTPException(status_code=400, detail="File must be CSV or Excel") if "text" not in df.columns: raise HTTPException(status_code=400, detail="Dataset must contain a 'text' column") results = [] for _, row in df.iterrows(): sentiment = analyze_sentiment(row['text']) results.append({"text": row['text'], "sentiment": sentiment}) return {"results": results} except Exception as e: raise HTTPException(status_code=500, detail=str(e))
2. 确保请求以正确格式发送
无论用curl、Postman还是前端代码,都必须以multipart/form-data格式提交文件:
- curl示例:
curl -X POST "http://localhost:8000/predict_file/" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "file=@your_file.csv"
- Postman操作:选择POST请求,Body切换为
form-data,Key填file,类型选择File,再上传本地目标文件
3. 额外优化建议
- 限制文件大小:通过
File(..., max_length=10*1024*1024)限制文件为10MB,避免超大文件拖垮服务 - 增加MIME类型校验:仅允许合法的文件类型,避免仅靠后缀判断的漏洞:
ALLOWED_MIME_TYPES = {"text/csv", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"} if file.content_type not in ALLOWED_MIME_TYPES: raise HTTPException(status_code=400, detail="Invalid file type. Only CSV/Excel allowed.")
- 异步处理批量预测:如果
analyze_sentiment是同步阻塞函数,用asyncio.to_thread封装,避免阻塞事件循环:
import asyncio # 替换原同步调用代码 sentiment = await asyncio.to_thread(analyze_sentiment, row['text'])
内容的提问来源于stack exchange,提问作者Bintang Sinaga
相关产品推荐
相关产品推荐

