¿Por qué la ejecución del servidor de desarrollo Flask se ejecuta dos veces?
Estoy usando Flask para desarrollar un sitio web y durante el desarrollo ejecuto flask usando el siguiente archivo:
#!/usr/bin/env python
from datetime import datetime
from app import app
import config
if __name__ == '__main__':
print('################### Restarting @', datetime.utcnow(), '###################')
app.run(port=4004, debug=config.DEBUG, host='0.0.0.0')
Cuando inicio el servidor, o cuando se reinicia automáticamente porque los archivos se actualizaron, siempre muestra la línea de impresión dos veces:
################### Restarting @ 2014-08-26 10:51:49.167062 ###################
################### Restarting @ 2014-08-26 10:51:49.607096 ###################
Aunque realmente no es un problema (el resto funciona como se esperaba), simplemente me pregunto ¿por qué se comporta así? ¿Algunas ideas?
El recargador Werkzeug genera un proceso hijo para que pueda reiniciarlo cada vez que cambia su código. Werkzeug es la biblioteca que proporciona a Flask el servidor de desarrollo cuando llamas app.run()
.
Ver el restart_with_reloader()
código de función ; su script se ejecuta nuevamente con subprocess.call()
.
Si lo configura, use_reloader
verá False
que el comportamiento desaparece, pero también perderá la funcionalidad de recarga:
app.run(port=4004, debug=config.DEBUG, host='0.0.0.0', use_reloader=False)
flask run
También puedes desactivar el recargador cuando usas el comando:
FLASK_DEBUG=1 flask run --no-reload
Puede utilizar la werkzeug.serving.is_running_from_reloader
función si desea detectar cuándo se encuentra en el proceso secundario de recarga:
from werkzeug.serving import is_running_from_reloader
if is_running_from_reloader():
print(f"################### Restarting @ {datetime.utcnow()} ###################")
Sin embargo, si necesita configurar globales de módulo, entonces debería usar el @app.before_first_request
decorador en una función y hacer que esa función configure dichas globales. Se llamará solo una vez después de cada recarga cuando llegue la primera solicitud:
@app.before_first_request
def before_first_request():
print(f"########### Restarted, first request @ {datetime.utcnow()} ############")
Tenga en cuenta que si ejecuta esto en un servidor WSGI a gran escala que utiliza bifurcaciones o nuevos subprocesos para manejar solicitudes, se puedenbefore_first_request
invocar controladores para cada nuevo subproceso.
Si está utilizando el flask run
comando moderno, no app.run
se utiliza ninguna de las opciones. Para desactivar el recargador por completo, pase --no-reload
:
FLASK_DEBUG=1 flask run --no-reload
Además, __name__ == '__main__'
nunca será cierto porque la aplicación no se ejecuta directamente. Utilice las mismas ideas de la respuesta de Martijn , excepto sin el __main__
bloque.
if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
# do something only once, before the reloader
if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
# do something each reload
Tuve el mismo problema y lo resolví configurándolo app.debug
en False
. Configurarlo en True
estaba causando que me __name__ == "__main__"
llamaran dos veces.
A partir de Flask 0.11, se recomienda ejecutar la aplicación en flask run
lugar de python application.py
. Usar este último podría resultar en ejecutar su código dos veces.
Como se indica aquí :
... a partir del Flask 0.11 se recomienda el método del matraz. La razón de esto es que debido a cómo funciona el mecanismo de recarga, hay algunos efectos secundarios extraños (como ejecutar cierto código dos veces...)