Je développe actuellement une application Python sur laquelle je souhaite voir des statistiques en temps réel. Je voulais utiliser Flask
afin de le rendre facile à utiliser et à comprendre.
Le problème est que mon serveur Flask doit démarrer au tout début de mon application Python et s’arrêter à la toute fin. Ça devrait ressembler à ça:
def main():
""" My main application """
from watcher.flask import app
# watcher.flask define an app as in the Quickstart flask documentation.
# See: http://flask.pocoo.org/docs/0.10/quickstart/#quickstart
app.run() # Starting the flask application
do_my_stuff()
app.stop() # Undefined, for the idea
Parce que j'ai besoin de mon contexte d'application (pour les statistiques), je ne peux pas utiliser un multiprocessing.Process
. Ensuite, j'ai essayé d'utiliser un threading.Thread
, mais il semblerait que Werkzeug ne l'aime pas:
* Running on http://0.0.0.0:10079/
Exception in thread Flask Server:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File ".../develop-eggs/watcher.flask/src/watcher/flask/__init__.py", line 14, in _run
app.run(Host=HOSTNAME, port=PORT, debug=DEBUG)
File ".../eggs/Flask-0.10.1-py2.7.Egg/flask/app.py", line 772, in run
run_simple(Host, port, self, **options)
File ".../eggs/Werkzeug-0.7-py2.7.Egg/werkzeug/serving.py", line 609, in run_simple
run_with_reloader(inner, extra_files, reloader_interval)
File ".../eggs/Werkzeug-0.7-py2.7.Egg/werkzeug/serving.py", line 524, in run_with_reloader
signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
ValueError: signal only works in main thread
Comment puis-je faire cela sans exécuter Flask dans le thread principal?
Vous exécutez Flask
en mode débogage, ce qui active le rechargeur (recharge le serveur Flask lorsque votre code change).
Flask peut très bien fonctionner dans un thread séparé, mais le rechargeur s'attend à s'exécuter dans le thread principal.
Pour résoudre votre problème, vous devez désactiver le débogage (app.debug = False
) ou désactiver le rechargeur (app.use_reloader=False
).
Ceux-ci peuvent également être passés comme arguments à app.run
: app.run(debug=True, use_reloader=False)
.
si vous souhaitez accéder à un terminal ipython dans flask.__, exécutez votre application dans un thread séparé Essayez cet exemple: -
from flask import Flask
import thread
data = 'foo'
app = Flask(__name__)
@app.route("/")
def main():
return data
def flaskThread():
app.run()
if __== "__main__":
thread.start_new_thread(flaskThread,())
exécuter ce fichier dans ipython
Réponse mise à jour pour Python 3 qui est un peu plus simple:
from flask import Flask
import threading
data = 'foo'
app = Flask(__name__)
@app.route("/")
def main():
return data
if __== "__main__":
threading.Thread(target=app.run).start()
Dans la documentation werkzeug :
Fermeture du serveur
Nouveau dans la version 0.7.
À partir de Werkzeug 0.7, le serveur de développement fournit un moyen de Arrêtez le serveur après une requête. Cela ne fonctionne actuellement qu'avec Python 2.6 et versions ultérieures ne fonctionneront qu'avec le serveur de développement . Pour lancer l'arrêt, vous devez appeler une fonction nommée 'werkzeug.server.shutdown' dans l'environnement WSGI:
def shutdown_server(environ): if not 'werkzeug.server.shutdown' in environ: raise RuntimeError('Not running the development server') environ['werkzeug.server.shutdown']()