[python] 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

더 편리한 것이 있어야합니다 🙂



답변

가장 좋은 방법은 static_url_path 를 루트 URL 로 설정하는 것입니다.

from flask import Flask

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


답변

@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”폴더에 있다고 가정하고 환경에 맞게 조정합니다.


답변

이 질문에 깨끗한 대답은입니다 대답 이 (동일)에 대한 질문 :

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로 리디렉션되지 않아야합니다. (Seans 대답에서는 그것이 어떻게 달성되었는지 즉시 명확하지 않습니다.)
  • 앱 루트 폴더에 정적 파일을 추가하는 것은 깨끗하지 않습니다.
  • 마지막으로 제안 된 솔루션은 미들웨어 추가 방식보다 훨씬 깔끔해 보입니다.

답변

이것은 오래된 답변이지만이 게시물이 Google 결과에서 상당히 높은 위치에 있기 때문에 대답하고 있습니다. 설명서에서는 다루지 않지만 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.


답변

정적 파일을 제공하는 것은 동적 콘텐츠를 제공하기위한 응용 프로그램과 관련이 없습니다. 정적 파일을 제공하는 올바른 방법은 사용중인 서버에 따라 다릅니다. 결국, 앱을 시작하고 실행할 때 웹 서버에 바인딩해야합니다. 나는 apache httpd에 대해서만 말할 수 있으므로 정적 파일을 제공하는 방법은 mod-wsgi를 통해 애플리케이션에 바인딩하는 가상 호스트에서 정의됩니다. 다음은 사이트 맵, robots.txt 또는 정적 콘텐츠를 제공하는 방법을 보여주는 가이드입니다.
http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Mounting_At_Root_Of_Site


답변

정적 파일을 보내는 또 다른 방법은 다음과 같은 포괄 규칙을 사용하는 것입니다.

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


답변

이 질문을받은 이후에 추가되었을 수 있지만 플라스크의 “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는 ** 옵션을 send_file로 직접 전달합니다.