Flask でアプリケーションを作る際のメモ(2015 年版)
Flask でアプリケーションを作る際のメモ - Memo の 2015 年版
ディレクトリ構造
. ├── __init__.py ├── app.py ├── configs │ ├── __init__.py │ └── settings.py ├── errors.py ├── extensions │ ├── __init__.py │ ├── injector.py │ └── permission.py ├── forms ├── i18n ├── models │ ├── __init__.py │ ├── db.py │ ├── entities │ └── mappers ├── static │ ├── css │ ├── fonts │ ├── img │ └── js ├── templates │ ├── admin │ └── frontend ├── tests │ ├── __init__.py │ ├── factories │ ├── fixtures │ └── helper.py ├── utils │ ├── __init__.py │ ├── compat.py │ ├── decorators.py │ ├── method_rewrite.py │ └── pagination.py └── views ├── __init__.py ├── admin └── frontend
app.py | アプリケーションファクトリ |
configs | 設定ファイル |
errors.py | アプリケーションが使う例外関連 |
extensions | Flask の拡張ライブラリ |
injector.py | DI 関係(Flask-Injecotr) |
permission.py | 権限管理(Flask-Principal) |
forms | WTForms |
i18n | 国際化関連の翻訳ファイル類 |
models | モデル類(直下はドメインロジック) |
db.py | SQLALchemy のセッション生成等 |
entities | SQLAlchemy のテーブル類 |
mappers | BPMapper(SQLAlchemy のオブジェクトを JSON に変換) |
tests | テスト類 |
factories | factory_boy 関連 |
fixtures | Mock類(外部 Web サービスの JSON 等) |
helper.py | テスト用ヘルパー |
utils | ユーティリティ |
compat.py | Python2, 3 の互換関連(Werkzuig からのコピー) |
decorators.py | デコレータ類 |
method_rewrite.py | HTTP の PUT などを上書き |
pagination.py | Pagenator |
views | View 類 |
アプリケーションの構造は基本的に変らない。
Injector を使いまくってるので、それが増えた。
あとは factory_boy を使うようになったりとか、Python3 に移行したとかが大きな違い。
アプリケーションの起動
app.py は各種 Flask の拡張の初期化や、views(Blueprint)の登録、エラーハンドリングなどを行う。
アプリケーションの起動は Flask-Script 経由で app.py でアプリケーションオブジェクトを生成して起動する。
テストも app.py のアプリケーションオブジェクトを生成して実行する。
セッション周りは元々 Flask-KVSession を使っていて、しばらく Python3 に対応しなかったので、Redis のインタフェースを適当に書いたけど、Flask-KVSession が Python3 に対応したので、元に戻った。
DB 周り
db.py は元々 meta.py とか(Pylons の名残)にしてたけど、直感的じゃないので、db.py にした。
Flask-SQLAlchemy ではなく SQLALchemy を直接使ってるのは、主にマルチデータベース関連のため*1
マイグレーションには Alembic 使ってる。
View と Model の関係
SQLAlchemy のテーブル類は entities というくくりに入れる。
モデルのロジック類は models 直下に入れる。
View からは models 直下のロジックを使う(entities を直接は触らない)。
Flask-Intector が models 以下のロジックを DI で注入してインスタンス化してるので、View から呼び出してテンプレートエンジンにアサインするか、JSON 化して応答する。
リクエストのバリデーションは WTForms か JSON なら jsonschema を使う。
これは View に書いてハンドリングしている。
昔はロジックだからと models のロジックに入れていたが WTForms に依存が出てくるのでやめた。
テスト
factory_boy を使うようになった。
データベースは毎回 setUpClass 内で初期化をしている。
fixtures には Web サービスがあるのなら、それが応答するレスポンスをダミーデータとして mock から使う。
ヘルパーには例えば、ログイン画面の csrf トークンの取得など便利関数があるので、それを使う。
とりあずは小規模なアプリケーションならこれで困っていない。
*1:Flask-SQLAlchemy も対応しているが、意図通り動かなかったため