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

Flask生成图表后删除上传文件的最佳实践咨询

解决方案与实践建议

1. 先解决跨用户图表混淆问题(无登录前提下)

核心思路是用Flask的session给每个用户分配唯一标识,实现文件/图表的隔离:

  • 初始化Flask时配置SECRET_KEY(用于加密session):
    app.secret_key = "your-random-secret-key-here"
    
  • 用户首次访问时,自动生成唯一UUID存入session:
    import uuid
    from flask import session
    
    @app.route('/')
    def upload_page():
        if "user_uid" not in session:
            session["user_uid"] = str(uuid.uuid4())
        # 渲染上传表单页面
        return render_template("upload.html")
    
  • 后续所有上传、图表生成操作,都基于session["user_uid"]创建独立目录(比如temp/{user_uid}/),确保每个用户只能访问自己的文件和图表。

2. 彻底解决存储占用:图表Base64嵌入(最优方案)

完全不用在服务器存储任何文件,直接把图表转为Base64字符串嵌入HTML,从根源解决存储和用户混淆问题:

  • 处理CSV并生成图表的逻辑:
    import pandas as pd
    import matplotlib.pyplot as plt
    from io import BytesIO
    import base64
    from flask import request, render_template
    
    @app.route("/plot", methods=["POST"])
    def generate_plot():
        # 读取上传的CSV文件(直接读内存,不存磁盘)
        csv_file = request.files["csv_file"]
        df = pd.read_csv(csv_file)
    
        # 生成图表(示例:折线图)
        plt.figure()
        df.plot(kind="line")
        # 将图表存入内存缓冲区
        img_buffer = BytesIO()
        plt.savefig(img_buffer, format="png")
        img_buffer.seek(0)
        # 转成Base64字符串
        img_base64 = base64.b64encode(img_buffer.getvalue()).decode("utf-8")
        plt.close()  # 释放图表内存
    
        # 直接把Base64数据传给模板渲染
        return render_template("result.html", plot_data=img_base64)
    
  • 在结果模板result.html中嵌入图表:
    <img src="data:image/png;base64,{{ plot_data }}" alt="生成的图表">
    

这个方案无需任何服务器存储,也不用做文件清理,同时天然避免了用户间的资源混淆。

3. 若必须用文件存储:临时文件清理实践

如果因为图表过大等原因必须存文件,可结合两种清理方式:

即时清理用户旧文件

在用户每次发起新的绘图请求时,先清空当前用户目录下的旧文件:

import os
import shutil

@app.route("/plot", methods=["POST"])
def generate_plot():
    user_uid = session["user_uid"]
    user_dir = f"temp/{user_uid}"
    # 清空用户目录旧文件
    if os.path.exists(user_dir):
        for file in os.listdir(user_dir):
            os.remove(os.path.join(user_dir, file))
    else:
        os.makedirs(user_dir)
    
    # 后续上传文件、生成图表的逻辑(都存在user_dir下)
    # ...

全局定时清理过期文件

在PythonAnywhere后台设置定时任务,定期清理所有超过指定时长的临时文件:

  • 编写清理脚本cleanup_temp.py:
    import os
    import time
    import shutil
    
    def cleanup():
        temp_root = "temp/"
        # 清理1小时前的文件/目录
        cutoff = time.time() - 3600
        for item in os.listdir(temp_root):
            item_path = os.path.join(temp_root, item)
            if os.path.isdir(item_path):
                if os.path.getmtime(item_path) < cutoff:
                    shutil.rmtree(item_path)
                else:
                    # 清理目录内的过期文件
                    for file in os.listdir(item_path):
                        file_path = os.path.join(item_path, file)
                        if os.path.getmtime(file_path) < cutoff:
                            os.remove(file_path)
    
    if __name__ == "__main__":
        cleanup()
    
  • 在PythonAnywhere的「Tasks」页面添加定时任务,比如每小时运行一次该脚本。

4. 额外优化点

  • 限制上传文件大小:配置app.config["MAX_CONTENT_LENGTH"] = 16 * 1024 * 1024(限制为16MB),避免大文件占用存储。
  • 验证CSV文件:检查上传文件的扩展名和MIME类型,防止恶意文件上传。

内容的提问来源于stack exchange,提问作者João Guilherme Bezerra Alves

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 10:20:19