2012-03-13 38 views
14

Tengo la configuración de mi servidor Apache y está manejando las respuestas del Frasco a través de mod_wsgi. Me he registrado el guión WSGI a través del alias:¿Cómo utilizo las rutas de Flask con Apache y mod_wsgi?

[httpd.conf]

WSGIScriptAlias /service "/mnt/www/wsgi-scripts/service.wsgi" 

He añadido el archivo WSGI correspondiente a la ruta anterior:

[/ mnt/www/WSGI-scripts/service.wsgi]

import sys 
sys.path.insert(0, "/mnt/www/wsgi-scripts") 

from service import application 

Y tengo un script Python Frasco prueba sencilla que proporciona el módulo de servicio:

[/mnt/www/wsgi-scripts/service.py]

from flask import Flask 

app = Flask(__name__) 

@app.route('/') 
def application(environ, start_response): 
     status = '200 OK' 
     output = "Hello World!" 
     response_headers = [('Content-type', 'text/plain'), 
          ('Content-Length', str(len(output)))] 
     start_response(status, response_headers) 
     return [output] 

@app.route('/upload') 
def upload(environ, start_response): 
     output = "Uploading" 
     status = '200 OK' 
     response_headers = [('Content-type', 'text/plain'), 
          ('Content-Length', str(len(output)))] 
     start_response(status, response_headers) 
     return [output] 

if __name__ == '__main__': 
     app.run() 

Cuando voy a mi sitio web URL [nombre de host]/servicio funciona como se esperaba y me sale "Hello World!" espalda. El problema es que no sé cómo hacer funcionar otras rutas, como 'subir' en el ejemplo anterior. Esto funciona bien en Flask independiente, pero en mod_wsgi estoy perplejo. Lo único que puedo imaginar es registrar un alias de script de WSGI por separado en httpd.conf para cada punto final que quiero, pero eso quita el elegante soporte de enrutamiento de Flask. ¿Hay alguna manera de hacer que esto funcione?

+3

¿Ha intentado navegar a '/ service/upload'? Usted puede estar gratamente sorprendido. –

+0

Cuando pulso/servicio/carga, la solicitud se envía a la función 'aplicación'. De hecho, puedo eliminar la declaración de ruta antes de la función de la aplicación y todavía funciona. Es como si la aplicación siempre fuera utilizada por mod_wsgi como punto de entrada a la aplicación. Siento que tengo que hacer algo dentro de la 'aplicación' que inicia la lógica de enrutamiento de Flask. –

Respuesta

17

En su archivo wsgi, usted está haciendo from service import application, que está importando solo su método application.

Cambie eso a from service import app as application y todo funcionará como se esperaba.

Después de su comentario, pensé que había expandir la respuesta un poco:

Su archivo es wsgi código Python - que puede tener cualquier código Python válido dentro de este archivo. El "controlador" de wsgi que está instalado en Apache está buscando el nombre de la aplicación en este archivo, al que transferirá las solicitudes. Una instancia de clase Flask - app = Flask(__name__) - proporciona dicha interfaz, pero dado que se llama app y no application, tiene que alias cuando la importa, eso es lo que hace la línea from.

Puede - y esto está perfectamente bien - simplemente haga esto application = Flask(__name__) y luego apunte el controlador wsgi en Apache a su archivo service.py. Si service.py fuera importable (es decir, en algún lugar en PYTHONPATH), no necesitaría un script wsgi intermediario.

Aunque lo anterior funciona, es una mala práctica. El archivo wsgi necesita permisos del proceso Apache para funcionar; y generalmente lo separa del código fuente real que debería estar en otro lugar en su sistema de archivos, con los permisos apropiados.

+0

que hizo el truco. ¡Gracias! Además de cambiar service.wsgi para que coincidiera con lo que indicaba, también necesitaba revertir mi service.py para que fuera un matraz puro. En la declaración del problema original, creo que había salido de los raíles mezclando el código mod_wsgi puro con Flask.Creo que la génesis de esta confusión fue nombrar mi 'aplicación' de manejador de ruta raíz. –

+1

Creo que no tenía claro el mod_wsgi frente al código de Flask. Entiendo que todo es Python. A lo que me estaba atascando es que en el ejemplo anterior mi '@ app.route ('/')' está decorando la función 'aplicación'. En mi configuración original, estaba importando solo la aplicación, por lo que solo se llamaba a esa función. Cuando cambié _service.wsgi_ para usar 'from service import app as application' que hacía referencia al objeto Flask, pero también parece haber creado un conflicto de nomenclatura con la función' application'. Cambié el nombre de esta función a '@def root():' y ahora funciona bien. ¡Gracias de nuevo! –

+0

¡Dulce! Esta fue la respuesta a mis problemas. –

Cuestiones relacionadas