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

FastAPI接收CSV/Excel文件时出现422错误的解决咨询

解决FastAPI接收CSV/Excel文件时的422错误及优化方案

核心问题分析

422 Unprocessable Entity错误主要源于两个常见问题:

  1. 请求未以multipart/form-data格式提交文件
  2. 代码中重复读取文件流: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 05:25:10