99

是否有任何巧妙的解决方案可以将静态文件存储在 Flask 的应用程序根目录中。robots.txt 和 sitemap.xml 预计会在 / 中找到,所以我的想法是为它们创建路由:

@app.route('/sitemap.xml', methods=['GET'])
def sitemap():
  response = make_response(open('sitemap.xml').read())
  response.headers["Content-type"] = "text/plain"
  return response

一定有更方便的东西:)

4

10 回答 10

80

最好的方法是将static_url_path设置为根 url

from flask import Flask

app = Flask(__name__, static_folder='static', static_url_path='')
于 2013-06-12T19:22:19.947 回答
69

这个问题的最干净的答案是这个(相同的)问题的答案:

from flask import Flask, request, send_from_directory
app = Flask(__name__, static_folder='static')    

@app.route('/robots.txt')
@app.route('/sitemap.xml')
def static_from_root():
    return send_from_directory(app.static_folder, request.path[1:])

总结一下:

  • 正如大卫指出的那样,使用正确的配置可以通过 prod 提供一些静态文件
  • 寻找 /robots.txt 不应导致重定向到 /static/robots.txt。(在 Seans 的回答中,目前尚不清楚这是如何实现的。)
  • 将静态文件添加到应用程序根文件夹中是不干净的
  • 最后,建议的解决方案看起来比添加中间件方法更干净:
于 2013-01-31T12:18:03.383 回答
67

@vonPetrushev 是对的,在生产中,您需要通过 nginx 或 apache 提供静态文件,但对于开发来说,让您的开发环境简单,让您的 python 应用程序也提供静态内容,这样您就不必担心关于更改配置和多个项目。为此,您需要使用SharedDataMiddleware

from flask import Flask
app = Flask(__name__)
'''
Your app setup and code
'''
if app.config['DEBUG']:
    from werkzeug import SharedDataMiddleware
    import os
    app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
      '/': os.path.join(os.path.dirname(__file__), 'static')
    })

此示例假设您的静态文件位于“static”文件夹中,请根据您的环境进行调整。

于 2011-02-10T08:36:28.310 回答
23

尽管这是一个老问题,但我之所以回答这个问题,是因为这篇文章在谷歌搜索结果中的排名很高。虽然文档中没有涵盖它,但如果您阅读了 Flask Application 对象构造函数的 API 文档,它就会被涵盖。通过static_folder像这样传递命名参数:

from flask import Flask
app = Flask(__name__,
            static_folder="/path/to/static",
            template_folder="/path/to/templates")

...您可以定义从何处提供静态文件。同样,你可以定义一个template_folder,你的名字static_url_path

于 2013-01-17T22:50:15.977 回答
16

提供静态文件与旨在提供动态内容的应用程序无关。提供静态文件的正确方法取决于您使用的服务器。毕竟,当您启动并运行您的应用程序时,您需要将其绑定到 Web 服务器。我只能说 apache httpd,因此提供静态文件的方式是在您通过 mod-wsgi 绑定到应用程序的虚拟主机中定义的。以下指南将向您展示如何提供站点地图、robots.txt 或任何静态内容: http ://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Mounting_At_Root_Of_Site

于 2010-11-22T00:54:22.823 回答
14

发送静态文件的另一种方法是使用这样的包罗万象的规则:

@app.route('/<path:path>')
def catch_all(path):
    if not app.debug:
        flask.abort(404)
    try:
        f = open(path)
    except IOError, e:
        flask.abort(404)
        return
    return f.read()

我用它来尽量减少开发时的设置。我从http://flask.pocoo.org/snippets/57/得到这个想法

此外,我正在我的独立机器上使用烧瓶进行开发,但在生产服务器中使用 Apache 进行部署。我用:

file_suffix_to_mimetype = {
    '.css': 'text/css',
    '.jpg': 'image/jpeg',
    '.html': 'text/html',
    '.ico': 'image/x-icon',
    '.png': 'image/png',
    '.js': 'application/javascript'
}
def static_file(path):
    try:
        f = open(path)
    except IOError, e:
        flask.abort(404)
        return
    root, ext = os.path.splitext(path)
    if ext in file_suffix_to_mimetype:
        return flask.Response(f.read(), mimetype=file_suffix_to_mimetype[ext])
    return f.read()

[...]

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-d', '--debug', dest='debug', default=False,
                      help='turn on Flask debugging', action='store_true')

    options, args = parser.parse_args()

    if options.debug:
        app.debug = True
        # set up flask to serve static content
        app.add_url_rule('/<path:path>', 'static_file', static_file)
    app.run()
于 2012-10-26T00:53:02.227 回答
6

自从提出这个问题以来,这可能已经添加了,但我正在查看烧瓶的“helpers.py”,我发现了 flask.send_from_directory:

send_from_directory(directory, filename, **options)
'''
  send_from_directory(directory, filename, **options)
  Send a file from a given directory with send_file.  This
  is a secure way to quickly expose static files from an upload folder
  or something similar.
'''

...引用flask.send_file:

send_file(filename_or_fp, mimetype=None, as_attachment=False, attachment_filename=None, add_etags=True, cache_timeout=43200, conditional=False)

...虽然 send_from_directory 直接将 **options 传递给 send_file,但这对于更多控制似乎更好。

于 2011-07-23T02:00:23.617 回答
3

从这里的文档:http: //flask.pocoo.org/docs/quickstart/#static-files

动态 Web 应用程序也需要静态文件。这通常是 CSS 和 JavaScript 文件的来源。理想情况下,您的 Web 服务器配置为为您提供服务,但在开发过程中 Flask 也可以这样做。只需在您的包中或模块旁边创建一个名为 static 的文件夹,它就会在应用程序的 /static 中可用。

要生成该部分 URL 的 URL,请使用特殊的“静态”URL 名称:

url_for('static', 文件名='style.css')

该文件必须作为 static/style.css 存储在文件系统中。

于 2011-03-24T16:35:14.457 回答
1

我也有同样的困境。做了一些搜索并找到了我的答案(MHO):

不妨从文档中引用

动态 Web 应用程序也需要静态文件。这通常是 CSS 和 JavaScript 文件的来源。理想情况下,您的 Web 服务器配置为为您提供服务,但在开发过程中 Flask 也可以这样做。只需在您的包中或模块旁边创建一个名为 static 的文件夹,它就会在应用程序的 /static 中可用。

恕我直言:当您的应用程序投入生产时,应该(或理想情况下)在网络服务器(nginx、apache)上配置静态文件服务;但在开发期间,Flask 使其可用于提供静态文件。这是为了帮助您快速开发 - 无需设置网络服务器等。

希望能帮助到你。

于 2011-09-18T06:59:05.713 回答
1

试试这个:

@app.route("/ProtectedFolder/<path:filename>")
@CheckUserSecurityAccessConditions
def Protect_Content(filename):
  return send_from_directory((os.path.join(os.path.dirname(__file__), 'ProtectedFolder')),filename)
于 2020-06-27T07:15:38.057 回答