概要
以下の書籍を読み進めた際の読書メモです。
所要時間は約15時間。(うち環境構築周りの作業や調査が3時間程度)
触れ込み通り、非常に軽量でサクサク開発でき、拡張も容易なフレームワークという印象でした。
書籍概要
- 書籍名:ゼロからFlaskがよくわかる本
- 著者 :本田崇智
- 発刊日:不明(2018年7月頃?)
- 頁数 :214ページ
- 備考 :Kindle版のみ
環境構築
Python環境構築
-
brewでインストールしていたPythonのアンインストール
$ brew uninstall python
$ brew uninstall python3
-
公式インストーラでインストールしていたPythonのアンインストール
-
pyenvのセットアップ
-
pyenvによるPythonのインストール・バージョン指定・動作確認
$ pyenv install -l
$ pyenv install 3.8.2
$ pyenv rehash
$ pyenv global 3.8.2
$ pyenv versions
$ which python
$ python -V
$ python2 -V
$ python3 -V
-
pipのインストール・動作確認
$ pip install --upgrade pip
$ pip -V
$ pip3 -V
-
Pipenvのセットアップ(プロジェクトごとに専用環境を構築しパッケージを管理できる)
$ pip install pipenv
$ pipenv --version
-
今後は
$ pipenv shell
で仮想環境に入ってから各種パッケージのインストールやコマンドの実行を行う- 仮想環境にインストールしたパッケージは
$ pipenv graph
で確認可能
- 仮想環境にインストールしたパッケージは
参考情報:MacのデフォルトのPythonについて
-
macOSにはデフォルトでPython2.7が入っている
- 実体は
/System/Library/Frameworks/Python.framework
以下(システムで使われているため消したりはできない)
- 実体は
-
さらに、macOS CatalinaにはPython3も入っている(2020年5月時点のバージョンは3.7.3)
- 実体は
/usr/bin/python3
(同じく消せない)
- 実体は
-
/usr/bin/を見ると
python
とpython2
系のコマンドは全て上述したPython2.7へシンボリックリンクが張られている-
python3
コマンドはシンボリックリンクではなく直接置かれているバイナリを呼んでいるだけ
-
$ ls -la /usr/bin/python*
lrwxr-xr-x 1 root wheel 75 10 8 2019 /usr/bin/python -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
lrwxr-xr-x 1 root wheel 82 10 8 2019 /usr/bin/python-config -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7-config
lrwxr-xr-x 1 root wheel 75 10 8 2019 /usr/bin/python2 -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
lrwxr-xr-x 1 root wheel 75 10 8 2019 /usr/bin/python2.7 -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
lrwxr-xr-x 1 root wheel 82 10 8 2019 /usr/bin/python2.7-config -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7-config
lrwxr-xr-x 1 root wheel 76 10 8 2019 /usr/bin/pythonw -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/pythonw2.7
lrwxr-xr-x 1 root wheel 76 10 8 2019 /usr/bin/pythonw2.7 -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/pythonw2.7
-rwxr-xr-x 1 root wheel 31488 3 18 00:42 /usr/bin/python3
- ちなみに
pip
についてはpip3
しか入っていない模様
$ ls -la /usr/bin/pip*
-rwxr-xr-x 1 root wheel 31488 3 18 00:42 /usr/bin/pip3
-
~/Library/Python
にもPython関連のファイルがあるが、ここにはpip
でインストールしたライブラリが入っている
読書ノート
Flaskの特徴・設計思想
-
Werkzeug・Jinja2に基づくPython用のマイクロフレームワークで、非常に軽量
- Werkzeug(ヴェルクツォイク):シンプルなWSGIユーティリティライブラリ
- WSGI(ウィスキー):PythonにおいてWebサーバとWebアプリを接続するためのI/Fライブラリ
- Jinja2:PythonのWeb開発で良く使われるテンプレートエンジンライブラリ
- Werkzeug(ヴェルクツォイク):シンプルなWSGIユーティリティライブラリ
-
ユーザのリクエストを受けて結果を返すというコア機能だけ実装されている
- デフォルトでは上記2つのライブラリしか持たないのでDBや認証周りなど余計なものが入っていない
-
拡張機能を組み合わせることでスケーラブルなアプリ作成も可能(カスタマイズ性が高い)
-
DjangoだとRDBがセットになるが、FlaskだとNoSQLなども利用できる
-
マイクロサービスとの親和性が高い
-
Flaskを使っているサービスの例:Netflix、Lyft、Linkedin、Mailgun、Pinterest
Djangoの特徴・設計思想
-
Web開発に必要なほとんどの機能が入っているフルスタックフレームワーク
-
型に従ったクリーンな開発が可能
-
Djangoを使っているサービスの例:Instagram、Bitbucket、Udemy、Dropbox、Spotify、Youtube
Flask全般
- FlaskはMTVフレームワーク(Model・Template・View)
- 主な処理の流れ
- ユーザが特定URLにアクセス(リクエスト)
- アクセスされたURLを読み取り、URLに紐付いた処理を実行する(View)
- 上記の処理中で、Modelオブジェクトを通してDBにアクセスする(Model)
- 処理の最後に、ユーザに表示するHTM等のテンプレートを返す(Template)
- ブラウザに返されたHTMLが表示される
- 主な処理の流れ
ビュー・テンプレート
-
ビューでテンプレートを表示(render_template)する際、パスに「/templates」を含める必要はない
- FlaskではHTMLファイルはtemplatesフォルダ以下に作成するのがルール
-
ルーティング設定にて
methods
を指定した場合、そのURLに対して許可するHTTPメソッドを制限できる- 何も指定しない場合はGETのみ許可される
-
FlaskでHTMLをレンダリングする際はJinja2を使っているため、HTML内での条件分岐やビューから受け取った変数の使用等が可能
- 例:
{% if not session.logged_in %}
- 例:
-
ユーザにメッセージを表示する際は
flash
を使う- ビュー:
flash('メッセージ')
- テンプレート:
get_flashed_messages()
- ビュー:
-
url_for
を使うと、リンク名とメソッドを自動的に紐付けてくれるので、リンク先が変わってもコード修正が不要になる- 当然ビュー側だけでなくテンプレート側のコードにも記述可能
-
return render_template('entries.html', entries=entries)
のようにすると、テンプレートに引数を渡せる -
url_for('メソッド名', id=entry.id)
のようにすると、ビューのメソッドに引数を渡せる -
app.route('/entries/<id>')
のようにすると、url_for
で渡された引数を受け取れる- 受け取る引数の型を制限したい場合は
<int:id>
のようにする(それ以外の型の場合はエラーになる)
- 受け取る引数の型を制限したい場合は
-
redirectとrender_templateの使い分け
モデル
-
ModelはPythonにおけるclassとして定義する
-
def __init__()
でModelが作成されたときの標準動作を定義する -
def __repr__(self)
でModelが参照されたときのコンソールの出力形式を記述する(なくても良い) -
Modelを定義したらDBに反映させる必要がある(主に以下の2通り)
- Modelの定義をコンソールで実行して反映する方法
- スクリプトを作成して反映する方法
-
ModelごとにViewを用意し1対1で紐付けてファイルを作成すると良い
セッション
- Flaskでは
session
という変数でセッション情報を扱える- 設定:
session['セッション名'] = True
- 確認:
if not session.get('セッション名'): (処理)
- 破棄:
session.pop('セッション名', None)
- 第2引数:既に破棄済みだった場合に返す値(特にない場合は
None
を指定しておく)
- 第2引数:既に破棄済みだった場合に返す値(特にない場合は
- 暗号化:アプリ本体に
SECRET_KEY = '秘密鍵'
と設定すると自動的にセッション情報を暗号化してくれる
- 設定:
DB
-
Flaskで簡単にDBを設定し使いたい場合は
Flask-SQLAlchemy
ライブラリを使うと良い -
FlaskはMTVフレームワークなのでModelを定義すればORMを使って簡単にDB操作が可能
デコレータ
- 繰り返し登場するView内の処理はデコレータを使うと良い(ライブラリで拡張する)
- 例:ログインしているかどうかのセッション判定を共通化する
Blueprint
- 大きくなってきたアプリの機能を分割する場合はBlueprintを使うと良い(ライブラリで拡張する)
- アプリ中に複数の機能がある時、機能を小さなアプリとして独立させて構成できる
- 例えば、ブログであれば記事関連の機能とコメント関連の機能をそれぞれ独立したアプリとして構成できる
- アプリごとにView・Template・staticファイルをひとまとめとして独立させる(divisionalな構造化)
- 例えば、ブログであれば記事関連の機能とコメント関連の機能をそれぞれ独立したアプリとして構成できる
- Templateやstaticファイルは各アプリで共通で、Viewだけ分けることも可能(functionalな構造化)
- Blueprintを使ってアプリケーションを登録する際はURLにprefixを付与することも可能
- アプリ中に複数の機能がある時、機能を小さなアプリとして独立させて構成できる
エラーハンドリング
-
@app.errorhandler(エラー時のステータスコード)
でエラーのステータスコードごとに処理を定義できる- Blueprintを使う場合は
@(アプリ名).app_errorhandler(エラー時のステータスコード)
とする
- Blueprintを使う場合は
Flaskコマンドライン
- flaskコマンドラインも使える
- 起動用のpyファイルを使用せずにアプリが起動できるようになる
- flaskコマンドを使用する前提のライブラリ(Flask-Migrateなど)が使えるようになる
- 環境変数の設定が必要
-
$ export FLASK_APP=(__init__.pyのあるディレクトリのパス)
:永続化する場合は適宜シェルの設定ファイルに追記する -
$ export FLASK_ENV=development
:デバッグモードで起動する場合(未設定の場合は本番モード)
-
アプリケーションファクトリ
- アプリケーションファクトリを使うと、グローバルではなく関数内でアプリを作成できる
- これを使って作成したアプリは外部から直接参照できなくなるので、
current_app
メソッドを利用して呼び出す
- これを使って作成したアプリは外部から直接参照できなくなるので、
テスト
-
Pythonのテストライブラリにも色々ある(今回はPython標準のunittestを使う)
- テスト用のDB設定はアプリケーションの本体ファイルに記述して、テスト用のconfigを読み込めるようにする
-
def setup(self)
:テスト実行時に最初に実行されるメソッド -
def tearDown(self)
:テスト終了直前に実行されるメソッド -
def test_...()
:テストメソッド本体
-
テストのカバレッジは
coverage
ライブラリで計測可能$ pipenv install coverage
-
.coveragerc
を作って以下の記述をしてテスト対象のフォルダを指定する[run] source = ./(パス)
$ coverage run -m unittest
-
$ coverage report -m
:カバレッジの計測 -
$ coverage html
:カバレッジレポートの作成
その他
-
static
ディレクトリ以下は自動的にCSSやJS等の静的ファイルを置く場所として認識される- 使用例:
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
- 使用例:
-
jQueryのCDNから
jquery-3.2.1.slim.min.js
をインポートする記述があるが、現時点では3.2.1を3.5.1に書き換える必要あり