Flask의 정적 파일-robot.txt, sitemap.xml (mod_wsgi)


94

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

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

답변:


78

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

from flask import Flask

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

static_folder가 프로젝트 폴더에있을 필요는 없다는 점을 언급 할 가치가 있습니다. 예 : static_folder = '/ app / ui'는 괜찮습니다.
ashic

66

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


1
감사! 이것이 내가 필요했던 것입니다! 나는 내 제작 heroku를 위해 이것을 찾고 있습니다. 다음 스레드에서 답변을 참조하십시오 : flask.pocoo.org/mailinglist/archive/2012/2/22/…
David

2
주의-이제 더 쉽게 처리 할 수있는 방법이 있습니다. 내 답장을 확인하십시오.
Sean McSomething 2013 년

1
SharedDataMiddleware가 '/'를 index.html 또는 이와 유사한 것으로 해석하는 방법이 있습니까?
gromgull 2013 년

63

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

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

22

이것은 오래된 답변이지만이 게시물이 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.


@chmike 예, 기본값은 /static이지만을 재정 의하여 변경할 수 있습니다 static_url_path.
Sean McSomething 2013 년

이것은 정확하지만 다른 답변은 더 유연합니다. 이것은 하나의 디렉토리 경로 만 제공 할 수 있다는 사실에 의해 제한됩니다.
Thomas Dignan 2013

이것은 원래 질문에 대한 답이 아닙니다.
Paolo Casciello 2013

2
static_url_path를 ""로 설정하면 /에서 파일을 제공 할 수 있습니다.
Beau

이렇게하면 Flask가 정적 파일을 제공합니다. nginx 또는 apache가 서비스를 제공하려면 어떻게해야합니까?
Markon 2013-09-20

15

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


그게 제가 찾던 답입니다. 감사!
biesiad 2010

1
애플리케이션은 콘텐츠, 일부 동적 및 일부 정적을 제공하기위한 것입니다.
Dem Pilafian 2017

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/ 에서 아이디어를 얻었습니다.

또한 독립 실행 형 컴퓨터에서 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()

1
주의-이제 더 쉽게 처리 할 수있는 방법이 있습니다. 내 답장을 확인하십시오.
Sean McSomething 2013 년

여러 경로를 제공해야하는 경우 탁월한 방법입니다!
Thomas Dignan 2013

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는 ** 옵션을 send_file로 직접 전달합니다.


3

여기 문서에서 : http://flask.pocoo.org/docs/quickstart/#static-files

동적 웹 애플리케이션에는 정적 파일도 필요합니다. 일반적으로 CSS 및 JavaScript 파일의 출처입니다. 이상적으로는 웹 서버가이를 제공하도록 구성되어 있지만 개발 중에 Flask도 그렇게 할 수 있습니다. 패키지 또는 모듈 옆에 static이라는 폴더를 생성하면 애플리케이션의 / static에서 사용할 수 있습니다.

URL의 해당 부분에 대한 URL을 생성하려면 특수한 '정적'URL 이름을 사용하십시오.

url_for ( 'static', filename = 'style.css')

파일은 static / style.css로 파일 시스템에 저장되어야합니다.


0

저도 같은 딜레마를 겪고 있습니다. 일부 검색을 수행하고 내 대답을 찾았습니다 (MHO) :

문서에서 인용 할 수도 있습니다.

동적 웹 애플리케이션에는 정적 파일도 필요합니다. 일반적으로 CSS 및 JavaScript 파일의 출처입니다. 이상적으로는 웹 서버가이를 제공하도록 구성되어 있지만 개발 중에 Flask도이를 수행 할 수 있습니다 . 패키지 또는 모듈 옆에 static이라는 폴더를 생성하면 애플리케이션의 / static에서 사용할 수 있습니다.

IMHO : 애플리케이션이 프로덕션 단계에 있을 때 정적 파일 서비스는 웹 서버 (nginx, apache)에서 구성되어야합니다 (또는 이상적으로는). 하지만 개발 과정 에서 Flask는 정적 파일을 제공 할 수 있도록했습니다. 이는 웹 서버 등을 설정할 필요없이 빠르게 개발하는 데 도움이됩니다.

도움이되기를 바랍니다.


0

이 시도:

@app.route("/ProtectedFolder/<path:filename>")
@CheckUserSecurityAccessConditions
def Protect_Content(filename):
  return send_from_directory((os.path.join(os.path.dirname(__file__), 'ProtectedFolder')),filename)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.