La respuesta depende de cómo esté sirviendo esta aplicación.
Submontado dentro de otro contenedor WSGI
Suponiendo que va a ejecutar esta aplicación dentro de un contenedor WSGI (mod_wsgi, uwsgi, gunicorn, etc.); realmente necesita montar, en ese prefijo la aplicación como una subparte de ese contenedor WSGI (cualquier cosa que hable WSGI servirá) y establecer su APPLICATION_ROOT
valor de configuración en su prefijo:
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/"
Establecer el APPLICATION_ROOT
valor de configuración simplemente limita la cookie de sesión de Flask a ese prefijo de URL. Todo lo demás será manejado automáticamente por usted por las excelentes capacidades de manejo de WSGI de Flask y Werkzeug.
Un ejemplo de submontaje adecuado de su aplicación
Si no está seguro de lo que significa el primer párrafo, eche un vistazo a esta aplicación de ejemplo con Flask montado en su interior:
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 solicitudes a la aplicación
Si, por otro lado, ejecutará su aplicación Flask en la raíz de su contenedor WSGI y le enviará solicitudes de proxy (por ejemplo, si está siendo FastCGI, o si nginx está proxy_pass
solicitando un sub-endpoint a su stand-alone uwsgi
/ gevent
servidor, entonces puede:
- Use un plano, como Miguel señala en su respuesta .
- o use la respuesta
DispatcherMiddleware
from werkzeug
(o PrefixMiddleware
from su27 ) para submontar su aplicación en el servidor WSGI independiente que está usando. (Vea Un ejemplo de sub-montaje apropiado de su aplicación arriba para el código que debe usar).
flask.Flask#create_url_adapter
ywerkzeug.routing.Map#bind_to_environ
parece que debería funcionar - ¿cómo estaba ejecutando el código? (La aplicación en realidad debe montarse en la ruta secundaria en un entorno WSGI paraurl_for
devolver el valor esperado).DispatcherMiddleware
enfoque, cuando se ejecuta el matraz solo. Parece que no puedo hacer que esto funcione cuando corro detrás de Gunicorn.uwsgi -s /tmp/yourapplication.sock --manage-script-name --mount /yourapplication=myapp:app
. los detalles se refieren a (documento uwsgi) [ flask.pocoo.org/docs/1.0/deploying/uwsgi/]Puede poner sus rutas en un plano:
Luego, registra el plano con la aplicación usando un prefijo:
fuente
app.register_blueprint
y entre registrarlo cuando crea una instancia del objeto Blueprint arriba, pasandourl_prefix='/abc/123
? ¡Gracias!register_blueprint
llamada le da a la aplicación la libertad de "montar" el plano en cualquier lugar que desee, o incluso montar el mismo plano varias veces en diferentes URL. Si coloca el prefijo en el propio plano, facilita la aplicación, pero tiene menos flexibilidad.Debe tener en cuenta que
APPLICATION_ROOT
NO es para este propósito.Todo lo que tiene que hacer es escribir un middleware para realizar los siguientes cambios:
PATH_INFO
para manejar la URL prefijada.SCRIPT_NAME
para generar la URL prefijada.Me gusta esto:
Envuelva su aplicación con el middleware, así:
visita
http://localhost:9010/foo/bar
,Obtendrá el resultado correcto:
The URL for this page is /foo/bar
Y no olvide configurar el dominio de las cookies si es necesario.
Esta solución viene dada por la esencia de Larivact . No
APPLICATION_ROOT
es para este trabajo, aunque parece que sí. Es realmente confuso.fuente
APPLICATION_ROOT
no es para este trabajo" - aquí es donde me estaba equivocando.Blueprint
Elurl_prefix
parámetro de deseo yAPPLICATION_ROOT
se combinaron de forma predeterminada, de modo que podría tenerAPPLICATION_ROOT
URL de alcance para toda la aplicación yurl_prefix
URL de alcanceAPPLICATION_ROOT
solo para el plano individual. SuspiroAPPLICATION_ROOT
.__call__
método:response = Response('That url is not correct for this application', status=404) return response(environ, start_response)
usarfrom werkzeug.wrappers import BaseResponse as Response
Esta es más una respuesta de Python que una respuesta de Flask / werkzeug; pero es simple y funciona.
Si, como yo, desea que la configuración de su aplicación (cargada desde un
.ini
archivo) también contenga el prefijo de su aplicación Flask (por lo tanto, no tener el valor establecido durante la implementación, sino durante el tiempo de ejecución), puede optar por lo siguiente:Podría decirse que esto es algo hacker y se basa en el hecho de que la función de ruta Frasco requiere una
route
como primer argumento posicional.Puedes usarlo así:
NB: No vale nada que sea posible usar una variable en el prefijo (por ejemplo, configurándola en
/<prefix>
), y luego procesar este prefijo en las funciones que decore con su@app.route(...)
. Si lo hace, obviamente debe declarar elprefix
parámetro en sus funciones decoradas. Además, es posible que desee verificar el prefijo enviado con algunas reglas y devolver un 404 si la verificación falla. Para evitar una reimplementación 404 personalizada, por favorfrom werkzeug.exceptions import NotFound
y luegoraise NotFound()
si la verificación falla.fuente
Blueprint
. ¡Gracias por compartir!Entonces, creo que una respuesta válida a esto es: el prefijo debe configurarse en la aplicación de servidor real que usa cuando se completa el desarrollo. Apache, nginx, etc.
Sin embargo, si lo desea al trabajo durante el desarrollo mientras se ejecuta la aplicación en el frasco de depuración, echar un vistazo a este GIST .
¡Frasco está
DispatcherMiddleware
al rescate!Copiaré el código aquí para la posteridad:
Ahora, cuando se ejecuta el código anterior como una aplicación Flask independiente,
http://localhost:5000/spam/
se mostraráHello, world!
.En un comentario sobre otra respuesta, expresé que deseaba hacer algo como esto:
Aplicando
DispatcherMiddleware
a mi ejemplo artificial:fuente
Otra forma completamente diferente es con los puntos de montaje en formato
uwsgi
.Del documento sobre el alojamiento de varias aplicaciones en el mismo proceso ( enlace permanente ).
En tu
uwsgi.ini
tu agregasSi no llama a su archivo
main.py
, debe cambiar tanto elmount
como elmodule
Tu
main.py
podrías lucir así:Y una configuración de nginx (nuevamente para completar):
Ahora la llamada
example.com/foo/bar
se mostrará/foo/bar
como devuelta por el frascourl_for('bar')
, ya que se adapta automáticamente. De esa manera, sus enlaces funcionarán sin problemas de prefijo.fuente
fuente
Necesitaba algo similar llamado "raíz de contexto". Lo hice en el archivo conf en /etc/httpd/conf.d/ usando WSGIScriptAlias:
myapp.conf:
Entonces ahora puedo acceder a mi aplicación como: http: // localhost: 5000 / myapp
Consulte la guía: http://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html
fuente
Mi solución donde coexisten las aplicaciones flask y PHP nginx y PHP5.6
MANTENGA Flask en root y PHP en subdirectorios
Agregar 1 línea
USE UBICACIONES ANIDADAS para PHP y deje que FLASK permanezca en la raíz
LEA detenidamente https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms
Necesitamos entender la coincidencia de ubicación (ninguna): si no hay modificadores, la ubicación se interpreta como una coincidencia de prefijo. Esto significa que la ubicación proporcionada se comparará con el comienzo del URI de solicitud para determinar una coincidencia. =: Si se usa un signo igual, este bloque se considerará una coincidencia si el URI de la solicitud coincide exactamente con la ubicación proporcionada. ~: Si hay un modificador de tilde, esta ubicación se interpretará como una coincidencia de expresión regular sensible a mayúsculas y minúsculas. ~ *: Si se usa un modificador de tilde y asterisco, el bloque de ubicación se interpretará como una coincidencia de expresión regular que no distingue entre mayúsculas y minúsculas. ^ ~: Si hay un modificador de quilate y tilde, y si este bloque se selecciona como la mejor coincidencia de expresión no regular, no se realizará la coincidencia de expresión regular.
El orden es importante, según la descripción de la "ubicación" de nginx:
Para encontrar una ubicación que coincida con una solicitud dada, nginx primero verifica las ubicaciones definidas usando las cadenas de prefijo (ubicaciones de prefijo). Entre ellos, se selecciona y recuerda la ubicación con el prefijo coincidente más largo. A continuación, se comprueban las expresiones regulares, en el orden de aparición en el archivo de configuración. La búsqueda de expresiones regulares termina en la primera coincidencia y se utiliza la configuración correspondiente. Si no se encuentra ninguna coincidencia con una expresión regular, se utiliza la configuración de la ubicación del prefijo recordada anteriormente.
Significa:
fuente
Para las personas que todavía luchan con esto, el primer ejemplo funciona, pero el ejemplo completo está aquí si tiene una aplicación Flask que no está bajo su control:
fuente