web-dev-qa-db-ja.com

flaskアプリケーションを別のスレッドで開始する

現在、リアルタイム統計を表示したいPythonアプリケーションを開発しています。使いやすく、理解しやすくするためにFlaskを使用したかったです。

問題は、my Flaskサーバーはmy Pythonアプリケーションの最初から開始し、最後で停止する必要があることです。次のようになります。

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 

(統計のために)アプリケーションコンテキストが必要なので、multiprocessing.Processは使用できません。それからthreading.Threadを使用しようとしましたが、Werkzeugはそれを好まないようです:

 * 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

メインスレッドでFlaskを実行せずにこれを行うにはどうすればよいですか?

37
FunkySayu

デバッグモードでFlaskを実行しているため、reloader(コードが変更されたときにFlaskサーバーをリロードします)。

Flaskは別のスレッドで正常に実行できますが、リローダーはメインスレッドで実行することを想定しています。


問題を解決するには、デバッグ(_app.debug = False_)を無効にするか、リローダー(_app.use_reloader=False_)を無効にする必要があります。

それらは引数として_app.run_:app.run(debug=True, use_reloader=False)に渡すこともできます。

55
Thomas Orozco

flaskでアプリケーションを別のスレッドで実行するipythonターミナルにアクセスする場合は、この例を試してください:-

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

このファイルをipythonで実行します

12
Rashid Mv

Python 3の回答を更新しました。

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

werkzeug documentation から:

サーバーのシャットダウン

バージョン0.7の新機能。

Werkzeug 0.7以降、開発サーバーはリクエスト後にサーバーをシャットダウンする方法を提供します。現在、これはPython 2.6以降でのみ動作し、開発サーバーでのみ動作します。シャットダウンを開始するには、WSGI環境で 'werkzeug.server.shutdown'という名前の関数を呼び出す必要があります。

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