2020-12-11に更新

[Python]Flaskアプリの基本構造を整理

はじめに

これまでなんとなくflaskのコードを良くわからないまま「おまじない」として書いていたので、一度ちゃんと調べて整理してみます。
目標としては、

  • その記述があることでどんなことが起こっているのか、を把握できるようにする
  • 書かれているコードの文法構造を理解し、言語化しておいてあとで調べられるようにする

この辺りを目指して整理してみます。脱コピペ。

flaskアプリの基本構造

シンプルなWebアプリの基本構造を見てみます。

解説などこちらを参照しました(スクリプトは一部違いがあります)
Flask を始めよう — Flask Handson 1 documentation

#①モジュールのインポート
from flask import Flask 

#②Webアプリ作成
app = Flask(__name__) 

#③エンドポイント設定(ルーティング)
@app.route('/')
def hello():
    return 'Hello World!'

 #④Webアプリ起動~~~~
if __name__ == '__main__':
    app.run(debug=True)

このスクリプトを実行し、ブラウザで「http://127.0.0.1:8000」にアクセスすると、画面には「Hello World!」と表示されているはずです。
そこまで上手くいっていれば、ローカルでWebアプリが起動できている、ということになります。

大まかな流れとイメージを掴む

上のスクリプトは大きく4つのパートに分かれています。

  • ①モジュールのインポート:アプリ作成に必要な機能の詰まったコードファイルを使えるようにします。
  • ②Webアプリを作成:必要な機能が詰まった「アプリの核」を用意します。
  • ③エンドポイントを指定(ルーティング):ブラウザからアクセスするURLと、それに対応した処理をここに書きます。
  • ④Webアプリを起動:ファイルが実行された時にアプリが立ち上がる(ブラウザで表示できる)ようにします。

僕らがFlaskでWebアプリを作る時は、③の部分を色々と作っていくことになります。
①のインポートはpythonの基本文法の一つ。そして②④はflaskの操作となっており基本的にコードを変更する必要はなさそうで、これが「おまじない」としてよく書かれている部分になります。

各パートを詳細に見てみる

①モジュールのインポート

from flask import Flask

flaskモジュールのFlaskクラスをインポートしています。
これにより、このスクリプト内でFlaskクラスの機能を活用できるようになります。

モジュールとは

関数やクラスなどが詰まったpythonファイルです。hogehoge.pyという名前で保存されているファイルが1つのモジュール、と考えて良さそうです。

②Webアプリ作成

app = Flask(__name__)

Flask(__name__)と第一引数に__name__を渡してFlaskクラスのインスタンスを作成し、それをappに代入しています。
このappにはflaskアプリの核が入っているイメージで、今後app.route()でルーティングを定義したり(③)、app.run()でローカルサーバー起動したりできるものになります。

グローバル変数__name__について

__name__というのはモジュールの属性の一つで、グローバル変数のようです(変な名前ですね)。
そしてその正体は「そのプログラムがどこから呼ばれて実行されているか」を格納している変数となります。

この.pyファイルが直接起動された時は、__name__には__main__という文字列が入ります。
一方で、このファイルが他のスクリプトからimportされて呼ばれた時には、__name__にはモジュール名(拡張子なしのファイル名)が入ります。

(これをFlask()の第一引数に渡すと何が起こっているのか、まではまだ理解ができずです)

③エンドポイント設定(ルーティング)

@app.route('/') 
def hello():
    return 'Hello World!'

この記述によりルーティングが定義されます
シンプルな記述ですが、だいぶ多くのことが凝縮されていそうです。

こちら(Flask を始めよう — Flask Handson 1 documentation)から引用しつつ整理してみます。

@app.route('/') という行は、 app に対して / というURLに対応するアクションを登録しています。

つまり、僕らが「http://hogehoge.com/」(パスが/)というURLにアクセスしたら、「こういう処理を返しますよ」というアクションを関数で作り、それらを1対1で紐づけています。
今回の例では、hello()関数の返り値(returnの後の文字列)がWebページに表示されることになります。
この関数を「ビュー関数」と呼んだりするようです。

さて、ここで@という変な記号が何を表しているのか、ですが…。

@ で始まる行はデコレータといって、その次の行で定義する関数やクラスに対して何らかの処理を行います。 @app.route('/') は、次の行で定義される関数を指定した URL にマッピングするという処理を実行しています。

ここでいう「デコレータ」はちょっと高度なPython言語の文法かと思います。
この辺りの文法的な理解と、ビュー関数がいかに動作して結果がWebに表示されるかはかなり難しそうなので、もうちょっと学習を進めながら理解を深めたいと思います。

デコレータと高層関数

「デコレータ」は「高層関数」を使った処理をスマートに記述できるpythonの記述の仕方で、「高層関数」とは引数として関数を受け取って処理をする関数、また戻り値として関数を返す関数のことです。
ここではデコレータを使って、hello()という関数を高層関数route()に渡して処理している、と考えられます。
(この辺りの理解が曖昧なので間違っていたら指摘をお願いします)

用語の整理

  • ルーティング:URLと動作の紐付けをすること。ここではパスと関数を紐付け。
  • エンドポイント:アクセスするためのURLを指す。
  • URLとパス:ファイルの位置を指定するためのもの。URLは絶対パス、インターネット上の住所のようなもの。
  • ビュー関数:リクエストに対してどのような動作を返すかを記した関数。

④Webアプリ起動

if __name__ == '__main__':
    app.run(debug=True)

最後に、app.run()を実行してローカルサーバーを起動し、アプリを立ち上げます。
if文は「このプログラムが直接実行されたかどうか」を判定しています。
②で見たように、ファイルをスクリプトとして直接実行した場合、__name__には__main__が代入されます。
つまりここでは、プログラムが直接実行された場合にapp.run()が実行されて、アプリが立ち上がるのです。

run()メソッド

  • このFlaskのrun()関数にキーワード引数で「ホスト」「ポート番号」「デバッグモード」の指定ができます。なくても起動可。
  • 例えばapp.run(host='http://127.0.0.1', port=8080, debug=True)と記述して起動することができます。
    • app.run(debug=True) -> デバッグモードで実行する
    • app.run(host='http://127.0.0.1') -> ホストを指定
    • app.run(port=8080) -> ポート番号を指定(デフォルトでは5000)

用語の整理

  • ホスト:(まとめ中)
  • ポート番号:(まとめ中)

(備考)WSGI規格

  • Web Server Gateway Interfaceの意味。
  • WebサーバーとWebアプリを接続するための標準化されたインターフェース規格をWSGI規格と呼ぶ。
  • Flask, DjangoなどPythonの多くフレームワークはこのWSGI規格を採用している。
  • 普通にWebアプリ開発するだけならあまり意識することはない。

おわりに

ほんとの初心者のうちは意識しなくても良いことですが、そこから次のステップに進むために理解を深めていくと出来ることが増えていくのかなあと感じます。
後半はかなり駆け足でまとめてしまったので、また理解度に応じて修正しようと思います。

ドキュメント読みます。
クイックスタート - Flask v0.5.1 documentation
API — Flask Documentation (1.0.x)

ツイッターでシェア
みんなに共有、忘れないようにメモ

Massa

北海道でアプリ制作に取り組んでるノンプログラマな農夫。仕事や日常生活で感じる小さな不便を解消すべく趣味と実益を兼ねて遊んでます ■Python・GAS + LINE bot

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント