Die Antwort hängt davon ab, wie Sie diese Anwendung bereitstellen.
In einem anderen WSGI-Container untermontiert
Angenommen, Sie führen diese Anwendung in einem WSGI-Container aus (mod_wsgi, uwsgi, gunicorn usw.). Sie müssen die Anwendung an diesem Präfix tatsächlich als Unterteil dieses WSGI-Containers bereitstellen (alles, was WSGI spricht, funktioniert) und Ihren APPLICATION_ROOT
Konfigurationswert auf Ihr Präfix setzen:
app.config["APPLICATION_ROOT"] = "/abc/123"
@app.route("/")
def index():
return "The URL for this page is {}".format(url_for("index"))
# Will return "The URL for this page is /abc/123/"
Durch Festlegen des APPLICATION_ROOT
Konfigurationswerts wird das Sitzungscookie von Flask einfach auf dieses URL-Präfix beschränkt. Alles andere wird automatisch von Flask und Werkzeugs hervorragenden WSGI-Handhabungsfunktionen für Sie erledigt.
Ein Beispiel für die ordnungsgemäße Untermontage Ihrer App
Wenn Sie sich nicht sicher sind, was der erste Absatz bedeutet, sehen Sie sich diese Beispielanwendung mit darin montiertem Kolben an:
from flask import Flask, url_for
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
app = Flask(__name__)
app.config['APPLICATION_ROOT'] = '/abc/123'
@app.route('/')
def index():
return 'The URL for this page is {}'.format(url_for('index'))
def simple(env, resp):
resp(b'200 OK', [(b'Content-Type', b'text/plain')])
return [b'Hello WSGI World']
app.wsgi_app = DispatcherMiddleware(simple, {'/abc/123': app.wsgi_app})
if __name__ == '__main__':
app.run('localhost', 5000)
Proxying-Anfragen an die App
Wenn Sie andererseits Ihre Flask-Anwendung im Stammverzeichnis des WSGI-Containers ausführen und Anforderungen an ihn weiterleiten (z. B. wenn FastCGI-Anforderungen erfüllt werden oder wenn nginx proxy_pass
Anforderungen für einen Subendpunkt sendet zu Ihrem Standalone uwsgi
/ gevent
Server können Sie dann entweder:
- Verwenden Sie eine Blaupause, wie Miguel in seiner Antwort betont .
- Oder verwenden Sie das
DispatcherMiddleware
from werkzeug
(oder die AntwortPrefixMiddleware
von su27 ), um Ihre Anwendung auf dem von Ihnen verwendeten eigenständigen WSGI-Server zu unterbinden . ( Informationen zur Verwendung des Codes finden Sie oben unter Ein Beispiel für die ordnungsgemäße Untermontage Ihrer App .)
flask.Flask#create_url_adapter
undwerkzeug.routing.Map#bind_to_environ
es sieht so aus, als ob es funktionieren sollte - wie hast du den Code ausgeführt? (Die App muss tatsächlich in einer WSGI-Umgebung auf dem Unterpfad bereitgestellt werdenurl_for
, um den erwarteten Wert zurückzugeben.)DispatcherMiddleware
Ansatzes, wenn der Kolben von selbst betrieben wird. Ich kann nicht scheinen, dass dies funktioniert, wenn ich hinter Gunicorn renne.uwsgi -s /tmp/yourapplication.sock --manage-script-name --mount /yourapplication=myapp:app
. Details siehe (uwsgi-Dokument) [ flask.pocoo.org/docs/1.0/deploying/uwsgi/]Sie können Ihre Routen in eine Blaupause einfügen:
Anschließend registrieren Sie den Entwurf bei der Anwendung mit einem Präfix:
quelle
app.register_blueprint
und der Registrierung, wenn Sie das Blaupausenobjekt oben instanziieren, durch Übergebenurl_prefix='/abc/123
? Danke dir!register_blueprint
Anwendung mit dem URL-Präfix im Aufruf die Freiheit hat, die Blaupause an einer beliebigen Stelle zu "mounten" oder sogar dieselbe Blaupause mehrmals an verschiedenen URLs zu mounten. Wenn Sie das Präfix in die Blaupause selbst einfügen, wird dies für die Anwendung einfacher, Sie haben jedoch weniger Flexibilität.Sie sollten beachten, dass das
APPLICATION_ROOT
NICHT für diesen Zweck ist.Sie müssen lediglich eine Middleware schreiben, um die folgenden Änderungen vorzunehmen:
PATH_INFO
, um die vorangestellte URL zu behandeln.SCRIPT_NAME
, um die vorangestellte URL zu generieren.So was:
Wickeln Sie Ihre App folgendermaßen mit der Middleware ein:
Besuchen Sie
http://localhost:9010/foo/bar
,Sie erhalten das richtige Ergebnis:
The URL for this page is /foo/bar
Und vergessen Sie nicht, die Cookie-Domain festzulegen, wenn Sie müssen.
Diese Lösung wird von Larivacts Kern gegeben . Das
APPLICATION_ROOT
ist nicht für diesen Job, obwohl es so aussieht. Es ist wirklich verwirrend.quelle
APPLICATION_ROOT
ist nicht für diesen Job" - hier habe ich mich geirrt. Ich wünschteBlueprint
denurl_prefix
Parameter undAPPLICATION_ROOT
wurde standardmäßig kombiniert, so dass ichAPPLICATION_ROOT
Bereichs-URLs für die gesamte App undurl_prefix
Bereichs-URLsAPPLICATION_ROOT
nur für den einzelnen Entwurf haben konnte. SighAPPLICATION_ROOT
.__call__
Methode:response = Response('That url is not correct for this application', status=404) return response(environ, start_response)
mitfrom werkzeug.wrappers import BaseResponse as Response
Dies ist eher eine Python-Antwort als eine Flask / Werkzeug-Antwort. aber es ist einfach und funktioniert.
Wenn Sie wie ich möchten, dass Ihre Anwendungseinstellungen (aus einer
.ini
Datei geladen ) auch das Präfix Ihrer Flask-Anwendung enthalten (damit der Wert nicht während der Bereitstellung, sondern zur Laufzeit festgelegt wird), können Sie sich für Folgendes entscheiden:Dies mag ein wenig hackish und stützt sich auf die Tatsache , dass der Kolben Route Funktion erfordert eine
route
als ein erstes Positions Argument.Sie können es so verwenden:
NB: Es ist nichts wert, dass es möglich ist, eine Variable im Präfix zu verwenden (z. B. indem Sie sie auf setzen
/<prefix>
) und dieses Präfix dann in den Funktionen zu verarbeiten, die Sie mit Ihrem dekorieren@app.route(...)
. Wenn Sie dies tun, müssen Sie denprefix
Parameter natürlich in Ihren dekorierten Funktionen deklarieren . Darüber hinaus möchten Sie möglicherweise das übermittelte Präfix anhand einiger Regeln überprüfen und eine 404 zurückgeben, wenn die Überprüfung fehlschlägt. Um eine benutzerdefinierte 404-Neuimplementierung zu vermeiden, klicken Sie bittefrom werkzeug.exceptions import NotFound
darauf,raise NotFound()
wenn die Prüfung fehlschlägt.quelle
Blueprint
. Danke für das Teilen!Daher glaube ich, dass eine gültige Antwort darauf lautet: Das Präfix sollte in der tatsächlichen Serveranwendung konfiguriert werden, die Sie nach Abschluss der Entwicklung verwenden. Apache, Nginx usw.
Wenn Sie jedoch möchten, dass dies während der Entwicklung funktioniert, während Sie die Flask-App im Debug ausführen, sehen Sie sich diese Übersicht an .
Flasche
DispatcherMiddleware
zur Rettung!Ich werde den Code hier für die Nachwelt kopieren:
Wenn Sie den obigen Code jetzt als eigenständige Flask-App ausführen,
http://localhost:5000/spam/
wird er angezeigtHello, world!
.In einem Kommentar zu einer anderen Antwort habe ich zum Ausdruck gebracht, dass ich so etwas tun möchte:
Anwendung
DispatcherMiddleware
auf mein erfundenes Beispiel:quelle
Ein anderer ganz anderer Weg ist mit Mountpoints in
uwsgi
.Aus dem Dokument über das Hosten mehrerer Apps im selben Prozess ( Permalink ).
In deinem
uwsgi.ini
fügst du hinzuWenn Sie Ihre Datei nicht aufrufen
main.py
, müssen Sie sowohl diemount
als auch die ändernmodule
Du
main.py
könntest so aussehen:Und eine Nginx-Konfiguration (der Vollständigkeit halber noch einmal):
Jetzt wird der Anruf als von den Flaschen zurückgegeben
example.com/foo/bar
angezeigt , da er sich automatisch anpasst. Auf diese Weise funktionieren Ihre Links ohne Präfixprobleme./foo/bar
url_for('bar')
quelle
quelle
Ich brauchte eine ähnliche sogenannte "Kontextwurzel". Ich habe es in der conf-Datei unter /etc/httpd/conf.d/ mit WSGIScriptAlias gemacht:
myapp.conf:
Jetzt kann ich auf meine App zugreifen als: http: // localhost: 5000 / myapp
Siehe die Anleitung - http://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html
quelle
Meine Lösung, bei der Flask- und PHP-Apps neben Nginx und PHP5.6 existieren
KEEP Flask in root und PHP in Unterverzeichnissen
1 Zeile hinzufügen
VERWENDEN SIE NESTED LOCATIONS für PHP und lassen Sie FLASK im Stammverzeichnis
LESEN Sie sorgfältig https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms
Wir müssen die Standortübereinstimmung verstehen (keine): Wenn keine Modifikatoren vorhanden sind, wird der Standort als Präfixübereinstimmung interpretiert. Dies bedeutet, dass der angegebene Speicherort mit dem Beginn des Anforderungs-URI abgeglichen wird, um eine Übereinstimmung zu ermitteln. =: Wenn ein Gleichheitszeichen verwendet wird, wird dieser Block als Übereinstimmung betrachtet, wenn der Anforderungs-URI genau mit dem angegebenen Ort übereinstimmt. ~: Wenn ein Tilde-Modifikator vorhanden ist, wird dieser Speicherort als Übereinstimmung zwischen regulären Ausdrücken und Groß- und Kleinschreibung interpretiert. ~ *: Wenn ein Tilde- und ein Sternchen-Modifikator verwendet werden, wird der Positionsblock als Übereinstimmung zwischen regulären Ausdrücken ohne Berücksichtigung der Groß- und Kleinschreibung interpretiert. ^ ~: Wenn ein Modifikator für Karat und Tilde vorhanden ist und dieser Block als beste Übereinstimmung mit nicht regulären Ausdrücken ausgewählt ist, findet keine Übereinstimmung mit regulären Ausdrücken statt.
Die Reihenfolge ist wichtig, aus der Beschreibung des "Standorts" von nginx:
Um einen Standort zu finden, der einer bestimmten Anforderung entspricht, überprüft nginx zunächst Standorte, die mithilfe der Präfixzeichenfolgen (Präfixpositionen) definiert wurden. Unter diesen wird der Ort mit dem längsten übereinstimmenden Präfix ausgewählt und gespeichert. Anschließend werden reguläre Ausdrücke in der Reihenfolge ihres Auftretens in der Konfigurationsdatei überprüft. Die Suche nach regulären Ausdrücken endet mit der ersten Übereinstimmung und die entsprechende Konfiguration wird verwendet. Wenn keine Übereinstimmung mit einem regulären Ausdruck gefunden wird, wird die Konfiguration des zuvor gespeicherten Präfixorts verwendet.
Es bedeutet:
quelle
Für Leute, die immer noch damit zu kämpfen haben, funktioniert das erste Beispiel, aber das vollständige Beispiel finden Sie hier, wenn Sie eine Flask-App haben, die nicht unter Ihrer Kontrolle steht:
quelle