Das ist also peinlich. Ich habe eine Anwendung, die ich zusammengestellt habe, Flask
und im Moment wird nur eine einzige statische HTML-Seite mit einigen Links zu CSS und JS bereitgestellt. Und ich kann nicht finden, wo in der Dokumentation Flask
die Rückgabe statischer Dateien beschrieben wird. Ja, ich könnte verwenden, render_template
aber ich weiß, dass die Daten nicht mit Vorlagen versehen sind. Ich hätte gedacht send_file
oder url_for
war das Richtige, aber ich konnte diese nicht zum Laufen bringen. In der Zwischenzeit öffne ich die Dateien, lese Inhalte und richte einen Response
mit dem entsprechenden Mimetyp ein:
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)
Möchte jemand ein Codebeispiel oder eine URL dafür angeben? Ich weiß, dass das ganz einfach sein wird.
python
flask
static-files
hughdbrown
quelle
quelle
Antworten:
Die bevorzugte Methode besteht darin, nginx oder einen anderen Webserver zum Bereitstellen statischer Dateien zu verwenden. Sie werden es effizienter machen können als Flask.
Sie können
send_from_directory
jedoch Dateien aus einem Verzeichnis senden, was in einigen Situationen sehr praktisch sein kann:Verwenden Sie keinen
send_file
odersend_static_file
einen vom Benutzer angegebenen Pfad.send_static_file
Beispiel:quelle
send_from_directory
entwickelt, um dieses Sicherheitsproblem zu lösen. Es besteht ein Fehler, wenn der Pfad außerhalb des jeweiligen Verzeichnisses führt.<path>
entspricht<string:path>
und weil Sie möchten, dass Flask einen pfadähnlichen Parameter sicherstellt, nach dem Sie fragen<path:path>
.Wenn Sie nur den Speicherort Ihrer statischen Dateien verschieben möchten, ist es am einfachsten, die Pfade im Konstruktor zu deklarieren. Im folgenden Beispiel habe ich meine Vorlagen und statischen Dateien in einen Unterordner namens verschoben
web
.static_url_path=''
Entfernt alle vorhergehenden Pfade aus der URL (dh die Standardeinstellung/static
).static_folder='web/static'
um alle im Ordner gefundenen Dateienweb/static
als statische Dateien bereitzustellen.template_folder='web/templates'
In ähnlicher Weise wird dadurch der Vorlagenordner geändert.Mit dieser Methode gibt die folgende URL eine CSS-Datei zurück:
Und zum Schluss hier ein Ausschnitt aus der Ordnerstruktur, in der
flask_server.py
sich die Flask-Instanz befindet:quelle
get_static_file('index.html')
?Sie können auch, und dies ist mein Favorit, einen Ordner als statischen Pfad festlegen, damit die darin enthaltenen Dateien für alle erreichbar sind.
Mit diesem Set können Sie das Standard-HTML verwenden:
quelle
project/static/style.css
verfügbar ist.Ich bin sicher, dass Sie dort finden, was Sie brauchen: http://flask.pocoo.org/docs/quickstart/#static-files
Grundsätzlich benötigen Sie nur einen "statischen" Ordner im Stammverzeichnis Ihres Pakets. Anschließend können Sie
url_for('static', filename='foo.bar')
Ihre Dateien mit http://example.com/static/foo.bar verwenden oder direkt mit ihnen verknüpfen .BEARBEITEN : Wie in den Kommentaren vorgeschlagen, können Sie den
'/static/foo.bar'
URL-Pfad direkt verwenden, ABER derurl_for()
Aufwand (in Bezug auf die Leistung) ist recht gering. Wenn Sie ihn verwenden, können Sie das Verhalten anschließend problemlos anpassen (Ordner ändern, URL-Pfad ändern, Verschieben Sie Ihre statischen Dateien nach S3 usw.).quelle
'/static/foo.bar'
direkt?Sie können diese Funktion verwenden:
quelle
send_static_file
bei Benutzereingaben aufgerufen werden muss. Verwenden Sie diese Lösung nicht für wichtige Zwecke.Was ich benutze (und es hat großartig funktioniert), ist ein "Vorlagen" -Verzeichnis und ein "statisches" Verzeichnis. Ich platziere alle meine .html-Dateien / Flask-Vorlagen im Vorlagenverzeichnis und static enthält CSS / JS. Meines Wissens funktioniert render_template für generische HTML-Dateien einwandfrei, unabhängig davon, in welchem Umfang Sie die Vorlagen-Syntax von Flask verwendet haben. Unten finden Sie einen Beispielaufruf in meiner Datei views.py.
Stellen Sie einfach sicher, dass Sie url_for () verwenden, wenn Sie auf eine statische Datei im separaten statischen Verzeichnis verweisen möchten. Sie werden dies wahrscheinlich sowieso in Ihren CSS / JS-Dateilinks in HTML tun. Zum Beispiel...
Hier ist ein Link zum "kanonischen" informellen Flask-Tutorial - viele großartige Tipps, die Ihnen dabei helfen, die ersten Schritte zu unternehmen.
http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world
quelle
Ein einfachstes Arbeitsbeispiel basierend auf den anderen Antworten ist das Folgende:
Mit dem HTML- Code index.html :
WICHTIG: Und index.html befindet sich in einem Ordner namens static , was bedeutet, dass
<projectpath>
die.py
Datei und<projectpath>\static
diehtml
Datei vorhanden sind.Wenn der Server im Netzwerk sichtbar sein soll, verwenden Sie
app.run(debug=True, host='0.0.0.0')
BEARBEITEN: Verwenden Sie diese Option, um auf Anfrage alle Dateien im Ordner anzuzeigen
Welches ist im Wesentlichen
BlackMamba
die Antwort, also geben Sie ihnen eine Gegenstimme.quelle
Für Winkel + Boilerplate-Fluss, der den nächsten Ordnerbaum erstellt:
Ich benutze folgende Lösung:
Es hilft, den 'statischen' Ordner neu zu definieren.
quelle
Also habe ich die Dinge zum Laufen gebracht (basierend auf der Antwort von @ user1671599) und wollte sie mit euch teilen.
(Ich hoffe, ich mache es richtig, da es meine erste App in Python ist.)
Ich war das -
Projektstruktur:
server.py:
AppStarter.py:
quelle
Eine der einfachen Möglichkeiten. Prost!
demo.py.
Erstellen Sie nun den Ordnernamen Vorlagen . Fügen Sie Ihre index.html- Datei im Vorlagenordner hinzu
index.html
Projektstruktur
quelle
render_template
Lösung bekannt ist, ich wollte sie aber nicht, da die Datei statisch und ohne Ersatz war: "Ja, ich könnte render_template verwenden, aber ich weiß, dass die Daten nicht mit Vorlagen versehen sind."Ich dachte daran zu teilen ... dieses Beispiel.
Das funktioniert besser und einfacher.
quelle
Verwenden
redirect
undurl_for
Dieser Server alle Dateien (CSS & JS ...), auf die in Ihrem HTML verwiesen wird.
quelle
Am einfachsten ist es, einen statischen Ordner im Hauptprojektordner zu erstellen. Statischer Ordner mit CSS-Dateien.
Hauptordner
Bild des Hauptordners mit statischen Ordnern und Vorlagenordnern und Flask-Skript
Flasche
HTML (Layout)
html
quelle
Wenn Sie Vorlagen in Ihrem Stammverzeichnis haben, funktioniert das Platzieren von app = Flask ( Name ), wenn sich die Datei, die diese enthält, ebenfalls am selben Speicherort befindet. Wenn sich diese Datei an einem anderen Speicherort befindet, müssen Sie den zu aktivierenden Vorlagenspeicherort angeben Flasche, um auf den Ort zu zeigen
quelle
Alle Antworten sind gut, aber was für mich gut funktioniert hat, ist nur die einfache Funktion
send_file
von Flask. Dies funktioniert gut, wenn Sie nur eine HTML-Datei als Antwort senden müssen, wenn host: port / ApiName die Ausgabe der Datei im Browser anzeigtquelle
Standardmäßig verwendet flask einen "Vorlagen" -Ordner, der alle Ihre Vorlagendateien enthält (jede
.html
Nur -Text-Datei, aber normalerweise oder eine Art Vorlagensprache wie jinja2), und einen "statischen" Ordner, der alle Ihre statischen Dateien enthält (dh.js
.css
und Ihre Bilder).In Ihrer
routes
können Sierender_template()
eine Vorlagendatei (wie oben erwähnt, standardmäßig imtemplates
Ordner abgelegt ) als Antwort auf Ihre Anfrage rendern . Und in der Vorlagendatei (normalerweise eine HTML-ähnliche Datei) können Sie einige.js
und / oder CSS-Dateien verwenden. Ich denke, Ihre Frage ist, wie Sie diese statischen Dateien mit der aktuellen Vorlagendatei verknüpfen.quelle
Wenn Sie nur versuchen, eine Datei zu öffnen, können Sie verwenden
app.open_resource()
. Das Lesen einer Datei würde also ungefähr so aussehenquelle