Static files in Flask - robot.txt, sitemap.xml (mod_wsgi)

前端 未结 10 579
后悔当初
后悔当初 2020-11-29 15:15

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

相关标签:
10条回答
  • 2020-11-29 15:53

    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='')
    
    0 讨论(0)
  • 2020-11-29 15:56

    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)
    
    0 讨论(0)
  • 2020-11-29 16:01

    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:
    0 讨论(0)
  • 2020-11-29 16:02

    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()
    
    0 讨论(0)
  • 2020-11-29 16:04

    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.

    0 讨论(0)
  • 2020-11-29 16:07

    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.

    0 讨论(0)
提交回复
热议问题