Also das ist peinlich. Ich habe eine Anwendung, die ich in Flask
zusammengewürfelt habe und die im Moment nur eine einzige statische HTML-Seite mit einigen Links zu CSS und JS ausgibt. Und ich kann in der Dokumentation nicht finden, wo Flask
die Rückgabe statischer Dateien beschreibt. Ja, ich könnte render_template
verwenden, aber ich weiß, dass die Daten nicht in Templates vorliegen. Ich hätte gedacht, dass send_file
oder url_for
das Richtige wäre, aber ich konnte diese nicht zum Laufen bringen. In der Zwischenzeit öffne ich die Dateien, lese den Inhalt und erstelle eine Response
mit dem entsprechenden Mimetyp:
import os.path
from flask import Flask, Response
app = Flask(__name__)
app.config.from_object(__name__)
def root_dir(): # pragma: no cover
return os.path.abspath(os.path.dirname(__file__))
def get_file(filename): # pragma: no cover
try:
src = os.path.join(root_dir(), filename)
# Figure out how flask returns static files
# Tried:
# - render_template
# - send_file
# This should not be so non-obvious
return open(src).read()
except IOError as exc:
return str(exc)
@app.route('/', methods=['GET'])
def metrics(): # pragma: no cover
content = get_file('jenkins_analytics.html')
return Response(content, mimetype="text/html")
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def get_resource(path): # pragma: no cover
mimetypes = {
".css": "text/css",
".html": "text/html",
".js": "application/javascript",
}
complete_path = os.path.join(root_dir(), path)
ext = os.path.splitext(path)[1]
mimetype = mimetypes.get(ext, "text/html")
content = get_file(complete_path)
return Response(content, mimetype=mimetype)
if __name__ == '__main__': # pragma: no cover
app.run(port=80)
Kann mir jemand ein Codebeispiel oder eine URL dafür geben? Ich weiß, dass das ganz einfach sein wird.
Die bevorzugte Methode ist es, nginx oder einen anderen Webserver zu verwenden, um statische Dateien zu servieren; sie werden in der Lage sein, es effizienter zu tun als Flask.
Sie können jedoch send_from_directory
verwenden, um Dateien aus einem Verzeichnis zu senden, was in manchen Situationen sehr praktisch sein kann:
from flask import Flask, request, send_from_directory
# set the project root directory as the static folder, you can set others.
app = Flask(__name__, static_url_path='')
@app.route('/js/<path:path>')
def send_js(path):
return send_from_directory('js', path)
if __name__ == "__main__":
app.run()
Verwenden Sie nicht send_file
oder send_static_file
mit einem vom Benutzer angegebenen Pfad.
Beispiel send_static_file
:
from flask import Flask, request
# set the project root directory as the static folder, you can set others.
app = Flask(__name__, static_url_path='')
@app.route('/')
def root():
return app.send_static_file('index.html')
Ich bin sicher, dass Sie dort finden, was Sie brauchen: http://flask.pocoo.org/docs/quickstart/#static-files
Im Grunde brauchen Sie nur einen "static" Ordner im Stammverzeichnis Ihres Pakets, und dann können Sie url_for('static', filename='foo.bar')
verwenden oder direkt auf Ihre Dateien mit http://example.com/static/foo.bar verlinken.
EDIT: Wie in den Kommentaren vorgeschlagen, könnten Sie auch direkt den URL-Pfad '/static/foo.bar'
verwenden Aber der Overhead von url_for()
(in Bezug auf die Leistung) ist ziemlich gering, und wenn Sie es verwenden, können Sie das Verhalten im Nachhinein leicht anpassen (den Ordner ändern, den URL-Pfad ändern, Ihre statischen Dateien nach S3 verschieben, usw.).
Was ich verwende (und es funktioniert hervorragend) ist ein Verzeichnis "templates" und ein Verzeichnis "static". Ich lege alle meine .html-Dateien/Flask-Vorlagen im templates-Verzeichnis ab, und static enthält CSS/JS. render_template funktioniert meines Wissens gut für generische html-Dateien, unabhängig davon, inwieweit man Flask's Templating-Syntax verwendet. Unten ist ein Beispielaufruf in meiner views.py Datei.
@app.route('/projects')
def projects():
return render_template("projects.html", title = 'Projects')
Stellen Sie einfach sicher, dass Sie url_for() verwenden, wenn Sie auf eine statische Datei im separaten statischen Verzeichnis verweisen wollen. Sie werden dies wahrscheinlich sowieso in Ihren CSS/JS-Dateilinks in HTML tun. Zum Beispiel...
<script src="{{ url_for('static', filename='styles/dist/js/bootstrap.js') }}"></script>
Hier's ein Link zum "canonical" informellen Flask-Tutorial - viele tolle Tipps, die Ihnen den Einstieg erleichtern.
http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world