【Python】Blueprintを使って大きなFlaskファイルを分割する


はじめに

pythonのwebフレームワークであるFlaskを使ってWEBアプリをつくっていると、Flaskのファイルの行数が多くなってしまいがちなのでファイル分割を検討した。FlaskではBrueprintを使ったファイル分割が一般的なようで、今回Blueprintを使用してファイルを分割した。

ディレクトリ構成

├── main.py
├── COMP_A
│   └── func_A.py
├── COMP_B
│   └── func_B.py
└── templates
    ├── COMP_A
    │   ├── index_A_1.html
    │   └── index_A_2.html
    └── COMP_B
        ├── index_B_1.html
        └── index_B_2.html

メインプログラムはmain.pyとする。またこの他にコンポーネントA、Bがあるものと想定。

各コンポーネント内のfunc_A.py、func_B.pyはそれぞれFlaskを使用するファイル。

flaskでは、template配下にはhtmlファイルを格納するが、今回はtemplate配下にコンポーネントごとのディレクトリを準備して、htmlファイルを格納した。

ソースコード

func_A.py

from flask import render_template
from flask import Blueprint

bpa = Blueprint('bpa', __name__, url_prefix='/A')

@bpa.route('/a1')
def app_a1():
    return render_template('COMP_A/index_A_1.html')
    #return "hello A a1"

@bpa.route('/a2')
def app_a2():
    return render_template('COMP_A/index_A_2.html')
    #return "hello A a2"

func_B.py


from flask import render_template
from flask import Blueprint

bpb = Blueprint('bpb', __name__, url_prefix='/B')

@bpb.route('/b1')
def app_b1():
    return render_template('COMP_B/index_B_1.html')
    #return "hello B b1"

@bpb.route('/b2')
def app_b2():
    return render_template('COMP_B/index_B_2.html')
    #return "hello B b2"

main.py

from flask import Flask

app = Flask(__name__)

from COMP_A.func_A import bpa
from COMP_B.func_B import bpb

@app.route('/')
def index():
    return 'Hello main'

app.register_blueprint(bpa)
app.register_blueprint(bpb)

if __name__ == '__main__':
    app.debug = True
    app.run(host='127.0.0.1',port=60000)

本来、Flask(name)で生成したappに対し、関数を登録していくが、別ファイルの関数の場合には、register_blueprintを使って Brueprintをappに登録していく。

この際、事前に別関数のBrueprintをimportするのを忘れないこと。

呼び出し

URLに以下を指定

127.0.0.1:60000/ #main.py index()
127.0.0.1:60000/A/a1 #func_A.py app_a1()
127.0.0.1:60000/A/a2 #func_A.py app_a2()
127.0.0.1:60000/B/b1 #func_B.py app_b1()
127.0.0.1:60000/B/b2 #func_B.py app_b2()

URLはBrueprint指定時のPrefixと@xxx.route定義時のパスの組み合わせになる点に注意

その他

  • moduleを使ったファイル分割
    flask.moduleを使ってファイル分割を行う方法もある様子。次回検討。

  • redirect
    redirectを行うときにはapp名を指定する必要がある。例えばb2にredirectするには以下のように書く。

return redirect(url_for('bpb.b2'))