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

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

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

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

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

解説などこちらを参照しました（スクリプトは一部違いがあります）
[Flask を始めよう — Flask Handson 1 documentation](https://methane.github.io/flask-handson/start.html#hello-world)

```python
#①モジュールのインポート
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アプリが起動できている、ということになります。

## 大まかな流れとイメージを掴む
上のスクリプトは大きく４つのパートに分かれています。

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

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


## 各パートを詳細に見てみる
### ①モジュールのインポート
```python
from flask import Flask
```

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

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


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

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

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

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

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

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

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

こちら（[Flask を始めよう — Flask Handson 1 documentation](https://methane.github.io/flask-handson/start.html#hello-world)）から引用しつつ整理してみます。

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

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

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

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

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

#### デコレータと高層関数

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


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



### ④Webアプリ起動
```python
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](https://a2c.bitbucket.io/flask/quickstart.html)
[API — Flask Documentation (1.0.x)](https://flask.palletsprojects.com/en/1.0.x/api/#flask.Flask)