コンテキストは実装部分まで調べると奥が深そうですね。
flask開発に必要な程度なら、概念を抑えて理解しておく程度でいいんじゃないかな
前回に引き続き、flaskチュートリアルのリクエストコンテキストの項目を進めいています。進めているチュートリアルはこちらのページになります。
こんな人の役に立つかも
・PythonでWebアプリケーションを作成したい人
・flaskのチュートリアルを行なっている人
・flaskのコンテキストについてイメージを深めたい人
コンテキストの仕組み
リクエストコンテキストの項目なのですが、さっそくコンテキスト自体の仕組みについて解説がはじまりました^^;チュートリアルの「How the Context Works」の部分です。
クライアントのリクエストから、コンテキストが作成されて処理が行われ、レスポンスをクライアントに返すという流れを図にしてみました。
リクエストを受け取ったら、リクエストコンテキストがスタックにプッシュされます。次に、アプリケーションコンテキストがプッシュされて、proxyの「request」「session」、「current_app」「g」にアクセスできるようになります。そして、サーバーで何かしらの処理を行い、returnでレスポンスを作成し、クライアントに送信します。クライアントにレスポンスを送信したら、リクエストコンテキストをスタックからポップして、その次にアプリケーションコンテキストをポップします。
このとき、「teardown」という処理が実行されます。
それぞれ、リクエストコンテキストをPOPする前に「teardown_request」に登録されている処理、アプリケーションコンテキストをPOPする前に「teardown_appcontext」に登録されている処理が実行されてからそれぞれのコンテキストはPOPされるとのことです。
また、このteardownの処理は、エラーが発生しても、実行されるということです。
flaskrチュートリアルでは、「db.py」のinit_app関数で「app.teardown_appcontext(close_db)」として、データベースを閉じる処理を必ず行うようにしていました。
ここの項目にコンテキストの全体について書かれていました。
コールバックとエラー
「before_request」、「after_request」に関数を登録することで、リクエストの前と後ろに特定の処理を実行することができます。また、「teardown」というコンテキストのPOP前に実行する処理とエラーについて勉強します。
①「before_request」が値を返す場合
各リクエストの前に実行される関数です。ここで登録された関数の一つが値を返す(return)と、他の登録された関数はスキップされます。そして、その返した値がレスポンスになります。そして、view関数も処理されず、スキップされます。
②「before_request」が値を返さない場合
設定されたルーティングのview関数が実行され、値を返します。
③「after_request」
view関数が返した値は、レスポンスのオブジェクトとして「after_request」に登録された処理に渡されます。レスポンスオブジェクトの修正または全く新しくレスポンスを作成します。
④「teardown」の2処理
レスポンスオブジェクトがクライアントに返され、「teardown_request」と「teardown_appcontext」の処理が呼び出されます。これは、unhandledなエラー(未処理のエラー)がここまでの処理で発生しても、teardownの処理は呼び出されます。
「teardown」処理の前にexceptionが発生した場合、「errorhandler()」に対応するエラーハンドラ(エラーを処理する関数)と照らし合わせてレスポンスを返します。ここで、エラーハンドラが見つからない、またはハンドラ自体がexceptionを出した場合、「500 Internal Server Errror」をレスポンスとして返します。これらの処理の後に、「exceptionオブジェクト」がteardownの処理に渡されます。
unhandledなエラーは予期しないエラーなので、そのままteardown処理を実行して、exeptionはあらかじめ指定された種類のエラーなのでerrorhandler()の処理が行われてteardownの処理が実行されるんですね。
デバッグモードの場合に上記の「500 Internal Server Errror」が発生した場合はレスポンスとして変換せず、そのままWSGIサーバーにエラーが渡されるようです。開発サーバーがデバッガにトレースバックできるようにするためとのことです。