Flaskのベストプラクティスの研究

FlaskといえばpythonでさくっとWebアプリをつくれるフレームワークです。

ちょっとしたAPIを公開する分にはすべてを1ファイルに書いてしまって何ら問題ないのですが 複数ファイルに分けたくなるような規模のWebアプリを実装するときにプロジェクト構成がカオスになりがちです。 というか、自分の場合そうなってしまいました..。

そこでプロジェクト構成のベストプラクティス(的なもの)を調べてみました。

参考になった資料

以下がとても参考になりました!

成果物

github.com

今後Flaskアプリを作るときはこれをベースに作っていこうと思います

たどり着いたプロジェクト構成
~/ExampleApp
    |-- manage.py
    |-- config.py
    |-- /app
        |-- __init__.py
        |-- /models
            |-- __init__.py
            |-- entry.py  # model
            |-- user.py   # model
        |-- /views
            |-- __init__.py
            |-- error.py  
            |-- entry.py  # view for model
            |-- user.py   # view for model
        |-- /templates
            |-- layout.html
            |-- /entries
                |-- show_entries.html  # template for view
            |-- /errors
                |-- 400.html
                |-- 404.html
                |-- 500.html
        |-- /static
            |-- style.css
    |-- /tests
        |-- __init__.py
        |-- /models
            |-- test_entry.py
        |-- /views
            |-- test_api.py

ポイント

これさえ守っておけばきれいになると思います。

  • dbインスタンスapp/__init__.py作らない
    • app/models.py もしくは app/models/__init__.py に作る
  • ビューは Blueprint を使う

逆に、このポイントを守らないと次のようになってしまいます。

NGパターン

f:id:sanshonoki:20181108233328p:plain

一見動きそうですが、app/views.py を importしたとき app/views.py 内で参照する appdbインスタンスがこの時点ではまだ存在してないのでエラーになってしまいます。

いちおうOKパターン

f:id:sanshonoki:20181108233758p:plain

動作はします。 ただ、ファイルの最下部で import文を実行する必要があり違和感をぬぐえません。。

推奨パターン

以上を踏まえて推奨パターンを図示します。

f:id:sanshonoki:20181108234016p:plain

import文を慣習通りにファイル冒頭に書くことができ、もちろんエラーもなく動作します。

db が外部のapp/models.py の中に記述されているので app/views.py の最初のimport文でエラーになりません。

また、Blueprintを使っているので app/views.py において appの循環参照が発生しません。 Blueprintを使わず viewの中で app/__init__.pyapp を参照しようとすると(コードで書くとfrom app import app)、循環参照が発生してしまってダメです..