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

Flask部署XGBoost模型时无法上传、保存及读取CSV文件的问题排查求助

Hey there! Let's walk through the issues in your code step by step—there are a few key bugs preventing your CSV from saving correctly and the download from working:

1. Incorrect File Path Construction in predict()

Your pathout lines have multiple critical issues:

  • You’re using os.path.join('uploads', path, '_out.csv'.format(n)), but path already includes the uploads/ prefix (since you created it with os.path.join('uploads', secrets.token_hex(8))). This would create a invalid double uploads/uploads/... path that doesn’t exist.
  • The format(n) is broken: n isn’t defined anywhere, and you’re trying to format an empty string. Instead, you need to append _out.csv to the original unique filename (not the full path).

Fix it by extracting the base filename and building the correct output path:

# Inside predict() function
filename = os.path.basename(path)
pathout = os.path.join('uploads', f"{filename}_out.csv")

2. Flask Route Method Mismatch

Your /csvOut route is set to methods=['POST'], but redirect(url_for('csvOut', ...)) sends a GET request. This will trigger a 405 Method Not Allowed error. Update the route to accept GET requests:

@app.route("/csvOut", methods=['GET'])
def csvOut():
    # ... rest of your code

3. Missing Static File Access for Uploads

Flask doesn’t automatically serve files from the uploads directory. To make the download link work, add a dedicated route to serve uploaded files:

from flask import send_from_directory

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory('uploads', filename)

Then update your out.html download link to use this route:

<a href="{{ url_for('uploaded_file', filename=download_filename) }}" download><button>Download File</button></a>

4. Fragile Column Name Matching

Comparing the entire column list with an exact, ordered match is fragile—extra whitespace, case differences, or column reordering will break it. Use a subset check to verify required columns exist (regardless of order):

# For model4
required_cols_4 = {'Leukocytes', 'Platelets', 'Eosinophils', 'Monocytes'}
if required_cols_4.issubset(data.columns):
    data['Prediction'] = model4.predict(data)
    out = 1
# For model14
required_cols_14 = {'Hematocrit', 'Hemoglobin', 'Platelets', 'MPV', 'Erythrocytes', 'Lymphocytes', 'MCHC', 'Leukocytes', 'Basophils', 'MCH', 'Eosinophils', 'MCV', 'Monocytes', 'RDW'}
elif required_cols_14.issubset(data.columns):
    data['Prediction'] = model14.predict(data)
    out = 2

5. Safe Directory Creation

Using os.mkdir('uploads') will throw an error if the directory already exists. Replace it with os.makedirs which safely creates the directory only if it doesn’t exist:

os.makedirs('uploads', exist_ok=True)

Corrected Full Code

Here’s the fixed version of your core Flask code:

import os
import secrets
import pandas as pd
from flask import Flask, request, redirect, url_for, render_template, send_from_directory

app = Flask(__name__)

# Assume model4 and model14 are loaded here

def predict(path):
    data = pd.read_csv(path)
    filename = os.path.basename(path)
    pathout = os.path.join('uploads', f"{filename}_out.csv")
    
    required_cols_4 = {'Leukocytes', 'Platelets', 'Eosinophils', 'Monocytes'}
    if required_cols_4.issubset(data.columns):
        data['Prediction'] = model4.predict(data)
        out = 1
    elif {'Hematocrit', 'Hemoglobin', 'Platelets', 'MPV', 'Erythrocytes', 'Lymphocytes', 'MCHC', 'Leukocytes', 'Basophils', 'MCH', 'Eosinophils', 'MCV', 'Monocytes', 'RDW'}.issubset(data.columns):
        data['Prediction'] = model14.predict(data)
        out = 2
    else:
        out = 3
    
    data.to_csv(pathout, index=False)  # Avoid extra index column in output
    return out, pathout

@app.route("/csvIn", methods=['GET', 'POST'])
def csvInput():
    if request.method == 'POST':
        csv = request.files['file']
        os.makedirs('uploads', exist_ok=True)
        filename = secrets.token_hex(8)
        path = os.path.join('uploads', filename)
        csv.save(path)
        out, pathout = predict(path)
        return redirect(url_for('csvOut', out=out, pathout=pathout))
    return render_template("csv.html")

@app.route("/csvOut", methods=['GET'])
def csvOut():
    pathout = request.args.get("pathout")
    out = request.args.get("out")
    
    if out in ('1', '2'):  # request.args returns strings, not integers
        result = "Please find the predicted output in the column titled 'Prediction' in the file attached below"
    else:
        result = "The uploaded csv file does not match the provided template. Please recheck the CSV file below and upload again. \n If the problem persists, please contact the admin teams for further clarification."
    
    download_filename = os.path.basename(pathout)
    return render_template("out.html", download_filename=download_filename, result=result)

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory('uploads', filename)

if __name__ == '__main__':
    app.run(debug=True)

And update your out.html to use the new download variable:

<head>
    <title>Batch Prediction</title>
</head>
<body>
    <div>
        <h2><b> Result: {{ result }} </b></h2><br>
        <p>If the file format is correct, the model predictions have been appended to the dataset in the form of a feature titled "Prediction".</p><br>
        <a href="{{ url_for('uploaded_file', filename=download_filename) }}" download><button>Download File</button></a><br>
        <a href="/home"><button class="btnbl">Return Home</button></a>
    </div>
</body>

Quick Test Tips

  • Enable debug=True to see detailed error messages if something goes wrong.
  • Ensure model4 and model14 are properly loaded before running the app.
  • The index=False flag in to_csv keeps the output file clean by avoiding an extra index column.

内容的提问来源于stack exchange,提问作者Ali Safdari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 01:37:29