2012-02-14 14 views
22

Estoy un poco confundido acerca de cómo hacer algo que pensé que sería bastante simple. Tengo una aplicación simple escrita usando Flask. Se ve algo como esto:¿Cuál es el enfoque correcto para llamar funciones después de ejecutar una aplicación de matraz?

from flask import Flask 

app = Flask(__name__) 

def _run_on_start(a_string): 
    print "doing something important with %s" % a_string 

@app.route('/') 
def root(): 
    return 'hello world' 

if __name__ == "__main__": 
    if len(sys.argv) < 2: 
     raise Exception("Must provide domain for application execution.") 
    else: 
     DOM = sys.argv[1] 
     _run_on_start("%s" % DOM) 
     app.run(debug=True) 

Lo que estoy encontrando es que mi terminal está emitiendo las instrucciones de impresión en _run_on_start pero no del otro código habitual de depuración de aplicaciones frasco. Si elimino la llamada antes de app.run, la salida es normal. Además estoy encontrando que la salida de _run_on_start se repite dos veces en el inicio, aunque no sé si es una salida extraña o la función se está llamando dos veces.

Supongo que esta no es la forma correcta de agregar una llamada a función antes de llamar al app.run. Busqué en los documentos de Flask y encontré menciones de varios decoradores que uno puede usar, que le permiten ejecutar una función antes/después de ciertas solicitudes, pero quiero ejecutar la llamada cuando se ejecuta el servidor de la aplicación.

Además, me doy cuenta de que si llamo a este módulo desde otro módulo, es decir, no cuando __name__ != "__main__" mi no recibiré mi llamada al _run_on_start.

¿Cuál es el enfoque correcto aquí? En ambos casos cuando estoy empezando desde CL y desde otro módulo?

+0

Esto probablemente responder a la pregunta: http://stackoverflow.com/questions/27465533/run-code-after-flask-application- has-started? noredirect = 1 & lq = 1 –

Respuesta

9

La salida duplicada de su función puede ser explicada por el recargador. Lo primero que hace es iniciar la función principal en un nuevo hilo para que pueda monitorear los archivos fuente y reiniciar el hilo cuando cambien. Inhabilítelo con la opción use_reloader=False.

Si usted quiere ser capaz de ejecutar su función al iniciar el servidor desde un módulo diferente, lo envuelve en una función y llamar a esa función desde el otro módulo:

def run_server(dom): 
     _run_on_start("%s" % dom) 
     app.run(debug=True, use_reloader=False) 

if __name__ == '__main__': 
    if len(sys.argv) < 2: 
     raise Exception("Must provide domain for application execution.") 
    else: 
     DOM = sys.argv[1] 
     run_server(DOM) 

El "enfoque correcto" depende de lo que en realidad estás tratando de lograr aquí. El servidor integrado está destinado a ejecutar su aplicación en un entorno de prueba local antes de implementarlo en un servidor de producción, por lo que el problema de iniciarlo desde un módulo diferente no tiene mucho sentido por sí mismo.

38

Probablemente buscando Flask.before_first_request decorador, como en:

@app.before_first_request 
def _run_on_start(a_string): 
    print "doing something important with %s" % a_string 
+9

¿Hay alguna manera de invocar una función antes de que la aplicación obtenga la primera solicitud? Necesito ejecutar una función justo después de que comenzó nginx (por ejemplo)? –

+3

Esto se invocará solo después de que se realice la primera solicitud. Por lo tanto, es inapropiado en la mayoría de los casos si desea inicializar una gran cantidad de personal antes de comenzar a hacer las respuestas. – chefarov

Cuestiones relacionadas