1. ホーム
  2. python

[解決済み] Flaskの開発サーバーを実行すると、なぜ2回実行されるのですか?

2022-05-05 11:25:09

質問

を使っています。 フラスコ で、開発中に以下のファイルを使ってflaskを動かしています。

#!/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')

サーバーを起動したとき、またはファイルが更新されたために自動再起動したとき、必ず印刷行が2回表示されます。

################### Restarting @ 2014-08-26 10:51:49.167062 ###################
################### Restarting @ 2014-08-26 10:51:49.607096 ###################

特に問題はないのですが(他は期待通りに動作します)、なぜこのような挙動になるのか、単純に疑問です。何か思い当たることはありますか?

解決方法は?

Werkzeug リローダは子プロセスを生成し、コードが変更されるたびにそのプロセスを再開できるようにします。Werkzeug は、Flask に開発サーバーを提供するためのライブラリです。 app.run() .

をご覧ください。 restart_with_reloader() 関数コード スクリプトが実行されると 再び subprocess.call() .

を設定した場合 use_reloader から False を実行すると、この動作はなくなりますが、リロードの機能も失われます。

app.run(port=4004, debug=config.DEBUG, host='0.0.0.0', use_reloader=False)

を使用する場合、リローダを無効にすることができます。 flask run コマンドも使用できます。

FLASK_DEBUG=1 flask run --no-reload

を使用することができます。 werkzeug.serving.is_running_from_reloader 機能 は、リロードの子プロセスにいることを検出したい場合。

from werkzeug.serving import is_running_from_reloader

if is_running_from_reloader():
    print(f"################### Restarting @ {datetime.utcnow()} ###################")

しかし、モジュールグローバルを設定する必要がある場合は、代わりに @app.before_first_request デコレーター を関数に追加し、その関数にこのようなグローバルを設定させます。この関数はリロードのたびに最初のリクエストが来たときに一度だけ呼ばれます。

@app.before_first_request
def before_first_request():
    print(f"########### Restarted, first request @ {datetime.utcnow()} ############")

これを、リクエストを処理するためにフォークや新しいサブプロセスを使用する本格的な WSGI サーバで実行する場合、以下のことを考慮してください。 before_first_request ハンドラ かもしれません。 は、新しいサブプロセスごとに呼び出されます。