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で実行したいと考えています。次のスレッドで回答を参照してください。フラスコ.pocoo.org
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にリダイレクトされることはありません。(ショーンズでは、それがどのように達成されたかはすぐにはわかりません)。
  • 静的ファイルをアプリのルートフォルダーに追加するのはクリーンではありません
  • 最後に、提案されたソリューションは、ミドルウェアを追加するアプローチよりもはるかにクリーンに見えます。

22

これは古い回答の質問ですが、この投稿はGoogleの検索結果でかなり高くなっているので、私はこれに答えています。ドキュメントでは説明されていませんが、APIドキュメントを読んだ場合、Flask Applicationオブジェクトコンストラクターのをとカバーされます。次の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年

これは正しいですが、他の答えはより柔軟です。これは、1つのディレクトリパスしか処理できないという事実によって制限されます。
Thomas Dignan 2013

これは元の質問に対する答えではありません。
Paolo Casciello 2013

2
static_url_pathを ""に設定すると、/からファイルを提供できます。
2013

これにより、Flaskは静的ファイルを提供します。nginxまたはapacheでそれらを提供したい場合はどうなりますか?
Markon

15

静的ファイルの提供は、動的コンテンツの配信を目的としたアプリケーションとは関係ありません。静的ファイルを提供する正しい方法は、使用しているサーバーによって異なります。結局のところ、アプリを起動して実行するときは、アプリをWebサーバーにバインドする必要があります。私はapache httpdについてのみ話すことができるので、静的ファイルを提供する方法は、mod-wsgiを介してアプリケーションにバインドしている仮想ホストで定義されます。サイトマップ、robots.txt、または静的コンテンツを提供する方法を示すガイドは次のとおりです:http : //code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Mounting_At_Root_Of_Site


それが私が探していた答えです。ありがとう!
10

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/からアイデアを得ました

さらに、スタンドアロンマシンでフラスコを使用して開発していますが、運用サーバーで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」を調べていたところ、flassk.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.
'''

...フラスコ.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

動的Webアプリケーションにも静的ファイルが必要です。これは通常、CSSおよびJavaScriptファイルのソースです。理想的には、ウェブサーバーがサービスを提供するように構成されていますが、開発中はFlaskもそれを実行できます。パッケージ内またはモジュールの横にstaticと呼ばれるフォルダーを作成するだけで、アプリケーションの/ staticで使用できるようになります。

URLのその部分へのURLを生成するには、特別な「静的」URL名を使用します。

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

ファイルはstatic / style.cssとしてファイルシステムに保存する必要があります。


0

私も同じジレンマを抱えています。検索して私の答えを見つけました(MHO):

ドキュメントから引用することもできます

動的Webアプリケーションにも静的ファイルが必要です。これは通常、CSSおよびJavaScriptファイルのソースです。理想的には、ウェブサーバーがサービスを提供するように構成されていますが、開発中はFlaskもそれを行うことができます。パッケージ内またはモジュールの横にstaticと呼ばれるフォルダーを作成するだけで、アプリケーションの/ staticで使用できるようになります。

IMHO:アプリケーションが本番環境で稼働している場合、静的ファイルサービスはWebサーバー(nginx、apache)で構成する必要があります(または理想的に構成します)。しかし開発、Flaskは静的ファイルを提供できるようにしました。これは、迅速な開発を支援するためです-Webサーバーなどをセットアップする必要はありません。

それが役に立てば幸い。


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.