AWS ソリューションアーキテクト プロフェッショナル 勉強メモ

随時追記。

Flask ことはじめ(1)- Flask以前とその基礎-

新人が、Flask のコードが少しでも簡単に読めるよう…と言った体で書いてみようと思います。 (いうて私もちゃんとした勉強挫折しかかってるので、気合を込める意味でも)

4回くらいに分けて

  • Flask以前とその基礎
  • テンプレート(Jinja 2)の使い方
  • DBとの接続(SQL Alchemy)
  • その他実際のアプリケーション応用など

と言った感じで、記事自体は長くても、中身は軽めにサクッと。

Flask 以前

この意識が結構重要だと思うので。背景重要。

基礎の基礎

基本Webページは、

  1. サーバに対してHTTP(S)リクエストを送って
  2. レスポンスとして返ってる文字列を、ブラウザが解釈して表示

で成り立っています。 もう少し具体的には、HTTP(S)リクエストの中身はこんな感じになってます。

POST /www.example.com?q=foo/ HTTP/1.1
...
...
Content-Type: text/plain    # ここまでヘッダ
                            # 一行空く
key1=bar&key2=baz           # ここからボディ

レスポンスのほうは

HTTP/1.1 200 OK
...
...
Content-Type: text/plain    # ここまでヘッダ
                            # 一行空く
<!DOCTYPE html>             # ここからボディ
...

みたいな感じです。

要はこういう形で、決まった形でくるリクエストを理解して、それに応じたレスポンスを決まった形で返す 役割のプログラムさえあれば、Webページを作れちゃうことになります。

Webアプリケーションフレームワークの役目

Python のようなスクリプト言語には大抵、サーバに置いとくとリクエストを理解して、レスポンスを返してくれるライブラリが標準で備わっています。(このような仕組みをCGIといいます) こんな感じのファイルを適切なディレクトリにおいて、CGIを利用すると宣言してサーバーを立ち上げてアクセスすると、Webページが表示されます。

gist314113b1ace11b93a1b992635fa6f68d

……どうでしょう、ちょっとめんどいですよね?
まず目につくのがなんどもprint文を繋げてリクエストを作っているところです。
一文で済ませてもいいのですが、煩雑なのに変わりはありませんし、可読性も低いままです。
別途ひな形のファイルを用意し、それをfileopenで読んで加工すればましになります。が、同じようなページを少しずつ変えて作りたい時など、ページ数が増えてくると複雑になってしまいます。
また実際にページを公開する上では、インジェクション対策など様々な作り込みも必要になります。

こういった問題に対し、

  • 継承などで流用ができる、可読性の高いテンプレートを用意
  • バリデーションやDB接続など、様々な種類の便利なライブラリを提供

してくれるのがWebフレームワークというものになります。

ようはお作法さえ押さえれば簡単に構造しっかりしたWebページつくれちゃうぜ!というものです。
有名どころにRuby on RailsCakePHPがあります。
Pythonでは

などがあります。トレンドはこんな感じで、Flaskの人気がジリジリ伸びてることがわかります(理由は後述、日本では…ですが)。

Flask

Flask の特徴

マイクロフレームワークと呼ばれるように、Flask本体は機能が最小限にまとまっており、欲しい機能は外部ライブラリとしてインストールし読み込む形をとります。
そのため、Djangoのうな最初から全ての機能が入っているもの(フルスタックフレームワーク)と比べ

  • 軽量
  • 学習コストが低い

反面で

  • どういうライブラリがあるかを調べ、どれを選択するかを決めるのが面倒

と言った特徴があります。

[余談] 現在のフレームワークの主流はAngularやReact+Redux+React routerのような、Javascriptによるクライアントサイドフレームワークで、 あまりがっつりサーバサイドをやる意義はなく、逆説的にFlaskのような軽量なものの立場が上がってきている、のかもしれません。

Flaskの基本

前段が長くなりましたがここからFlaskの説明です。
今回はPython 3を想定していますが、Print文さえ読み代えればPython 2でも動作するはずです。

インストール

pip install flask

でインストールできます。超簡単。

シンプルなWebアプリケーション

公式のチュートリアルはあまりにシンプルなので、少し拡張したこんなものを用意しました。

gistf290402b64eebb644bb3d1ceceb4dc9b

このhello.pyを適当なディレクトリにおいて、python hello.pyと走らせるとサーバーが立ち上がり、localhost:5000で動作を始めます。
細かい話は後回しにして、リンクを貼りますので、サーバを手元で立ち上げた後に、コードと見比べながらクリックして試して見てください。

http://localhost:5000/
http://localhost:5000/user/%E5%A4%AA%E9%83%8E
http://localhost:5000/user-agent
http://localhost:5000/error
http://localhost:5000/cookie
http://localhost:5000/redirect
http://localhost:5000/user_verify/001

ああなんとなくこんな感じで動くんだなーという感覚持てればおっけーです。

解説

appの生成

L1では、あとあと使うモジュールをインポートしてあります。
L2のように、Flask アプリケーションは、flask.Flask()メソッドで初期化、実行されています。
(Flaskで動いてるアプリケーションのルートディレクトリを見るとこの宣言があるはずです。__init__.pyの中に仕込まれることも。)

このように生成されたインスタンスから(今回はapp、通常慣例的にappが使用されます)、関数を呼び出してリクエストに対するレスポンスを定義していきます。

ルーティング

このアドレスにリクエストが来た場合はこのレスポンスを返すというのが、もっとも簡単な応答の定義になるかと思います。
これについてFlaskはapp.routeメソッドを継承して利用することでシンプルに記述ができます。
この際、簡単に記述するためにデコレータと呼ばれる記述方法を用います。

@app.route(/)                            # [HOME]/へリクエストが来た時に
def message()                            # message関数が利用され
    return "もっとも単純なルーティングです"   # このメッセージがレスポンスボディとして送信される

最初は少し面食らいますが要はこんなこと言ってんだくらいの理解で良いかと思います。
(詳しく勉強したい場合 Pythonのデコレータを理解するための12Step - Qiita などを参照ください。)

今回は7パターン用意をしてあります。

モジュールの利用

先ほど述べたように、より簡単にレスポンスを定義するために様々なモジュールがFlaskから提供されています。

  • request: リクエストに含まれる種々のパラメータを読み込む
  • make_response Cookie利用
  • redirect リダイレクト
  • abort エラー処理

を今回利用しています。動作についてはぽちぽち触りながら確認してもらえば。
(説明足りないようなら追記も検討します。)

とにもかくにも 「リクエストを理解して、それに応じたレスポンスを返す」助けをしてくれるのがFlask、ということを常に意識していてください。

次回

今回は単純なレスポンスを返しましたが、通常はHTMLのひながたをリクエストに応じて書き換えて(動的、とよくいいます)
レスポンスとして返すのが一般的な利用の仕組みになります。
(もしかするとこんなことはせずただJSONを返すのに徹する、というのが最近の利用形態なのかもしれませんが)

このテンプレートエンジンについて、簡単に説明できればと思います。

参考