it-swarm.com.de

Starten Sie eine Flaschenanwendung in einem separaten Thread

Ich entwickle derzeit eine Python-Anwendung, in der Echtzeitstatistiken angezeigt werden sollen. Ich wollte Flask verwenden, um es einfach zu verwenden und zu verstehen.

Das Problem ist, dass mein Flask-Server ganz am Anfang meiner Python-Anwendung starten und ganz am Ende stoppen sollte. Es sollte so aussehen:

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 

Da ich meinen Anwendungskontext (für die Statistik) benötige, kann ich keinen multiprocessing.Process verwenden. Dann habe ich versucht, einen threading.Thread zu verwenden, aber es sieht so aus, als würde es Werkzeug nicht gefallen: 

 * 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

Wie kann ich das tun, ohne Flask im Hauptthread auszuführen?

31
FunkySayu

Sie führen Flask im Debug-Modus aus, wodurch der Reloader (der Flask-Server neu geladen wird, wenn sich Ihr Code ändert). 

Die Flasche kann in einem separaten Thread problemlos ausgeführt werden, der Reloader erwartet jedoch, dass er im Hauptthread ausgeführt wird.


Um Ihr Problem zu lösen, sollten Sie entweder Debug (app.debug = False) oder den Reloader (app.use_reloader=False) deaktivieren. 

Diese können auch als Argumente an app.run: app.run(debug=True, use_reloader=False) übergeben werden.

51
Thomas Orozco

wenn Sie nach Zugriff auf das ipython-Terminal in flaskrun Ihre Anwendung in einem separaten Thread suchen, versuchen Sie dieses Beispiel: -

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,())

führen Sie diese Datei in ipython aus

12
Rashid Mv

Aktualisierte Antwort für Python 3, die etwas einfacher ist:

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()
1
skeller88

Aus der werkzeug Dokumentation :

Server herunterfahren

Neu in Version 0.7.

Beginnend mit Werkzeug 0.7 bietet der Entwicklungsserver einen Weg zu Fahren Sie den Server nach einer Anforderung herunter. Dies funktioniert derzeit nur mit Python 2.6 und höher funktioniert nur mit dem Entwicklungsserver. Um das Herunterfahren zu initiieren, müssen Sie eine Funktion namens .__ aufrufen. 'werkzeug.server.shutdown' in der WSGI-Umgebung:

def shutdown_server(environ):
    if not 'werkzeug.server.shutdown' in environ:
        raise RuntimeError('Not running the development server')
    environ['werkzeug.server.shutdown']()
0
Burhan Khalid