とても簡単だと思ったことをする方法について少し混乱しています。 Flask
を使用して記述されたシンプルなアプリがあります。次のようになります。
from flask import Flask
app = Flask(__name__)
def _run_on_start(a_string):
print "doing something important with %s" % a_string
@app.route('/')
def root():
return 'hello world'
if __name__ == "__main__":
if len(sys.argv) < 2:
raise Exception("Must provide domain for application execution.")
else:
DOM = sys.argv[1]
_run_on_start("%s" % DOM)
app.run(debug=True)
私が見つけているのは、私の端末が_run_on_start
で印刷ステートメントを出力しているが、他の通常のFlaskアプリデバッグコードではないことです。app.runの前に呼び出しを削除すると、さらに、起動時に_run_on_start
の出力が2回繰り返されることがわかりますが、奇妙な出力なのか、関数が実際に2回呼び出されているのかはわかりません。
これは、app.run
を呼び出す前に関数呼び出しを追加する正しい方法ではないと思います。 Flask docsを調べ、使用できるさまざまなデコレータの言及を見つけました。これにより、特定のリクエストの前後に関数を実行できますが、アプリサーバーが実行されているときに呼び出しを実行したいと思います。
さらに、このモジュールを別のモジュールから呼び出す場合、つまり__name__ != "__main__"
の場合ではないので、_run_on_start
への呼び出しを取得できないことを理解しています。
ここで正しいアプローチは何ですか? CLと別のモジュールから開始する場合、どちらの場合でも?
関数からの重複出力は、リローダーで説明できます。最初に行うことは、メイン関数を新しいスレッドで開始して、ソースファイルを監視し、変更時にスレッドを再起動できるようにすることです。 use_reloader=False
オプションでこれを無効にします。
別のモジュールからサーバーを起動するときに関数を実行できるようにするには、それを関数にラップし、その関数を他のモジュールから呼び出します。
def run_server(dom):
_run_on_start("%s" % dom)
app.run(debug=True, use_reloader=False)
if __name__ == '__main__':
if len(sys.argv) < 2:
raise Exception("Must provide domain for application execution.")
else:
DOM = sys.argv[1]
run_server(DOM)
「正しいアプローチ」は、実際にここで達成しようとしていることに依存します。組み込みサーバーは、本番サーバーにデプロイする前にローカルのテスト環境でアプリケーションを実行するためのものです。そのため、別のモジュールから起動するという問題は、それ自体ではあまり意味がありません。
おそらくあなたが探していたのはFlask.before_first_request
デコレータ。
@app.before_first_request
def _run_on_start(a_string):
print "doing something important with %s" % a_string
from flask import Flask
def create_app():
app = Flask(__name__)
def run_on_start(*args, **argv):
print "function before start"
run_on_start()
return app
app = create_app()
@app.route("/")
def hello():
return "Hello World!"