标签归档:mod-wsgi

Flask中的静态文件-robot.txt,sitemap.xml(mod_wsgi)

问题:Flask中的静态文件-robot.txt,sitemap.xml(mod_wsgi)

是否有任何聪明的解决方案将静态文件存储在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

必须有一些更方便的方法:)

Is there any clever solution to store static files in Flask’s application root directory. robots.txt and sitemap.xml are expected to be found in /, so my idea was to create routes for them:

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

There must be something more convenient :)


回答 0

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

from flask import Flask

app = Flask(__name__, static_folder='static', static_url_path='')

The best way is to set static_url_path to root url

from flask import Flask

app = Flask(__name__, static_folder='static', static_url_path='')

回答 1

@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”中,并根据您的环境进行调整。

@vonPetrushev is right, in production you’ll want to serve static files via nginx or apache, but for development it’s nice to have your dev environment simple having your python app serving up the static content as well so you don’t have to worry about changing configurations and multiple projects. To do that, you’ll want to use the 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')
    })

This example assumes your static files are in the folder “static”, adjust to whatever fits your environment.


回答 2

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

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:])

总结一下:

  • 正如David指出的那样,通过正确的配置,可以通过prod提供一些静态文件
  • 查找/robots.txt不应导致重定向到/static/robots.txt。(在肖恩斯回答中,目前尚不清楚如何实现。)
  • 将静态文件添加到应用程序根文件夹中并不干净
  • 最后,所提出的解决方案看起来比添加中间件方法更干净:

The cleanest answer to this question is the answer to this (identical) question:

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:])

To summarize:

  • as David pointed out, with the right config it’s ok to serve a few static files through prod
  • looking for /robots.txt shouldn’t result in a redirect to /static/robots.txt. (In Seans answer it’s not immediately clear how that’s achieved.)
  • it’s not clean to add static files into the app root folder
  • finally, the proposed solution looks much cleaner than the adding middleware approach:

回答 3

尽管这是一个古老的答案问题,但我正在回答这个问题,因为此帖子在Google搜索结果中的排名很高。尽管文档中未涉及它,但是如果您阅读了Flask Application对象构造函数的API文档,则将涉及它。通过static_folder像这样传递命名参数:

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

…您可以定义从何处提供静态文件。同样,您可以定义a template_folder,即您的名字static_url_path

Even though this is an old answered question, I’m answering this because this post comes up pretty high in the Google results. While it’s not covered in the documentation, if you read the API docs for the Flask Application object constructor it’s covered. By passing the named parameter static_folder like so:

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

…you can define where static files are served from. Similarly, you can define a template_folder, the name of you static_url_path.


回答 4

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

Serving static files has nothing to do with application that is meant to deliver dynamic content. The correct way of serving static files is dependent of what server you’re using. After all, when you get your app up and running, you will need to bind it to a web server. I can speak only for apache httpd, so the way of serving static files is defined in the virtual host that you are binding to your application through mod-wsgi. Here is the guide that will show you how to serve sitemaps, robots.txt or any static content: http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Mounting_At_Root_Of_Site


回答 5

发送静态文件的另一种方法是使用全部规则,如下所示:

@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/获得了这个想法

此外,我正在单机上使用flask开发,但在生产服务器中使用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()

Another way to send static files is to use a catch-all rule like this:

@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()

I use this to try to minimise the set-up when developing. I got the idea from http://flask.pocoo.org/snippets/57/

Further, I’m developing using flask on my standalone machine but deploying with Apache in production server. I use:

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()

回答 6

自从问了这个问题以来,可能已经添加了它,但是我正在查看flask的“ 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,但似乎可以更好地进行控制。

This might have been added since this question was asked, but I was looking through flask’s “helpers.py” and I found 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.
'''

… which references flask.send_file:

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

… which seems better for more control, although send_from_directory passes **options directly through to send_file.


回答 7

从此处的文档中:http : //flask.pocoo.org/docs/quickstart/#static-files

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

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

url_for(’静态’,filename =’style.css’)

该文件必须以static / style.css的形式存储在文件系统中。

From the documentation here: http://flask.pocoo.org/docs/quickstart/#static-files

Dynamic web applications need static files as well. That’s usually where the CSS and JavaScript files are coming from. Ideally your web server is configured to serve them for you, but during development Flask can do that as well. Just create a folder called static in your package or next to your module and it will be available at /static on the application.

To generate URLs to that part of the URL, use the special ‘static’ URL name:

url_for(‘static’, filename=’style.css’)

The file has to be stored on the filesystem as static/style.css.


回答 8

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

也可以从文档中引用

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

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

希望能帮助到你。

I’m having the same dilemma as well. Did some search and found my answer(MHO):

Might as well quote from the documentation

Dynamic web applications need static files as well. That’s usually where the CSS and JavaScript files are coming from. Ideally your web server is configured to serve them for you, but during development Flask can do that as well. Just create a folder called static in your package or next to your module and it will be available at /static on the application.

IMHO: When your application is up for production, static file serving should be (or is ideally) configured on the webserver (nginx, apache); but during development, Flask made it available to serve static files. This is to help you develop rapidly – no need to setup webservers and such.

Hope it helps.


回答 9

试试这个:

@app.route("/ProtectedFolder/<path:filename>")
@CheckUserSecurityAccessConditions
def Protect_Content(filename):
  return send_from_directory((os.path.join(os.path.dirname(__file__), 'ProtectedFolder')),filename)

Try this:

@app.route("/ProtectedFolder/<path:filename>")
@CheckUserSecurityAccessConditions
def Protect_Content(filename):
  return send_from_directory((os.path.join(os.path.dirname(__file__), 'ProtectedFolder')),filename)