Dus dit is gênant. Ik'heb een applicatie die ik in Flask
in elkaar heb gegooid en voor nu serveert het gewoon een enkele statische HTML pagina met wat links naar CSS en JS. En ik kan niet vinden waar in de documentatie Flask
het retourneren van statische bestanden beschrijft. Ja, ik zou render_template
kunnen gebruiken, maar ik weet dat de data niet getemplatiseerd is. Ik'had gedacht dat send_file
of url_for
de juiste oplossing was, maar die kreeg ik niet aan de praat. In de tussentijd open ik de bestanden, lees de inhoud en maak een Response
met het juiste mimetype:
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)
Wil iemand hier een codevoorbeeld of url voor geven? Ik weet dat dit doodsimpel gaat worden.
De voorkeursmethode is om nginx of een andere webserver te gebruiken om statische bestanden te serveren; zij'zullen het efficiënter kunnen doen dan Flask.
Je kunt echter send_from_directory
gebruiken om bestanden vanuit een directory te versturen, wat in sommige situaties best handig kan zijn:
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()
Gebruik niet send_file
of send_static_file
met een door de gebruiker opgegeven pad.
send_static_file
voorbeeld:
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')
Ik ben er zeker van dat je daar vindt wat je nodig hebt: http://flask.pocoo.org/docs/quickstart/#static-files
In principe heb je gewoon een "static" map nodig in de root van je pakket, en dan kun je url_for('static', filename='foo.bar')
gebruiken of direct linken naar je bestanden met http://example.com/static/foo.bar.
EDIT: Zoals gesuggereerd in de opmerkingen zou je direct het '/static/foo.bar'
URL pad kunnen gebruiken MAAR url_for()
overhead (performance wise) is vrij laag, en het gebruik ervan betekent dat je'het gedrag achteraf gemakkelijk kunt aanpassen (verander de map, verander het URL pad, verplaats je statische bestanden naar S3, etc).
Wat ik gebruik (en het'werkt geweldig) is een "templates" directory en een "static" directory. Ik plaats al mijn .html bestanden/Flask templates in de templates directory, en static bevat CSS/JS. render_template werkt prima voor generieke html bestanden voor zover ik weet, ongeacht de mate waarin je Flask's templating syntax gebruikt. Hieronder is een voorbeeld aanroep in mijn views.py bestand.
@app.route('/projects')
def projects():
return render_template("projects.html", title = 'Projects')
Zorg er alleen voor dat je url_for() gebruikt wanneer je wel wilt verwijzen naar een of ander statisch bestand in de aparte statische directory. Je'll waarschijnlijk uiteindelijk doen dit anyways in uw CSS / JS-bestand links in html. Bijvoorbeeld...
<script src="{{ url_for('static', filename='styles/dist/js/bootstrap.js') }}"></script>
Hier's een link naar de "canonical" informele Flask tutorial - veel goede tips in hier om u te helpen de grond raken running.
http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world