【问题标题】:What's the proper way to think about filepaths with a Flask application being served on apache with mod_wsgi使用 mod_wsgi 在 apache 上提供 Flask 应用程序来考虑文件路径的正确方法是什么
【发布时间】:2019-01-07 20:49:06
【问题描述】:

我试图允许用户从我的烧瓶应用程序下载 csv 文件,但在处理从运行 Apache2 的 ubuntu 18 服务器下载文件的路径中。

import flask
import os
from io import BytesIO

basedir = os.path.abspath(os.path.dirname(__file__))

app = flask.Flask(__name__)
app.config["DEBUG"] = True

@app.route('/<string:report>/<string:action>', methods=['GET'])
def report(report,action):
    if action == 'download': 
        files = os.listdir(os.path.join(basedir, f'static/reports/{report}'))
        filepath = url_for(f'static/reports/{report}/{files[-1]}')
        output = BytesIO()
        with open(filepath, 'rb') as f:
            data = f.read()
        output.write(data)
        output.seek(0)
        return send_file(output,attachment_filename=files[-1], as_attachment=True)

但我收到此错误:[Errno 2] No such file or directory: '/static/reports'

我的 Apache2 配置已经有静态文件的别名 像这样:

Alias /static /var/www/FlaskApp/FlaskApp/static
<Directory /var/www/FlaskApp/FlaskApp/static/>
   Order allow,deny
   Allow from all
</Directory>

我也尝试在静态下为我的报告文件夹创建一个别名,但我仍然得到相同的结果。

我有什么明显的遗漏吗?

【问题讨论】:

  • 为什么要将数据读入BytesIO() 对象? send_file() 将接受filepath 直接,并更有效地启动文件。
  • 或者使用send_from_directory(),它需要一个目录和文件名。

标签: flask apache2


【解决方案1】:

您的错误是使用url_for() 生成路径。 url_for() 生成 URL 路径,而不是文件系统路径。您不能使用结果打开本地文件。 url_for() 用于将浏览器发送到正确的位置。

您正在从标准 static 路径提供文件。只需弄清楚 Flask 的位置,app / current_app 对象 has a .static_folder attribute

您还想使用send_from_directory() function 直接提供文件。此处无需先将数据加载到BytesIO() 对象中。 send_from_directory 接受相对路径作为第二个参数。

这应该可行:

@app.route('/<string:report>/<string:action>', methods=['GET'])
def report(report, action):
    if action == 'download': 
        files = os.listdir(os.path.join(app.static_folder, 'reports', report))
        filename = files[-1]
        filepath = os.path.join('reports', report, filename)
        return send_from_directory(app.static_folder, filepath, as_attachment=True)

我省略了attachment_filename,因为默认已经使用正在服务的文件的文件名。

您可能需要重新考虑files[-1] 策略。 os.listdir() 以任意顺序生成文件(操作系统决定的任何顺序都是最方便的)。如果您希望它是最近创建或修改的文件,则必须先进行自己的排序。

【讨论】:

  • 谢谢! static_folder 的解释很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-08
  • 1970-01-01
  • 2017-01-24
相关资源
最近更新 更多