ルーティングを分ける - Flask

ディレクトリ・ファイル構成

ディレクトリ構成

  • flaskapp
    • controllers
      • myapp.py
    • static
      • javascripts
        • script.js
      • stylesheets
        • style.css
    • templates
      • myapp
        • index.html
      • share
        • layout.html
    • __init__.py
    • app.py

初期ファイルを分ける

Blueprint は Flask をインストールすると Blueprint も合わせてインストールされています。

flaskapp/app.py

from flaskapp import create_app

app = create_app()

if __name__ == '__main__':
    app.run()

「 __init__.py 」にデータベースの設定など初期設定を必要に応じて行います。

flask_app/__init__.py

from flask import Flask
from .controllers.myapp import myapp

def create_app():
    app = Flask(__name__)
    
    app_name = [
        myapp,
    ]

    for i in app_name:
        app.register_blueprint(i)
    
    return app

「 controllers 」ディレクトリを作成し、ルーティングを分けます。

flaskapp/controllers/myapp.py

from flask import Blueprint, render_template, request, redirect

myapp = Blueprint("myapp", __name__, url_prefix='/myapp')

@myapp.route('/')
def index():
    return render_template('myapp/index.html')

上記のBlueprint("myapp", __name__, url_prefix='/myapp')のそれぞれの引数の内容は、以下を参考にしてください。

  • 最初の引数の"myapp"は、Blueprintの名前を表し、Flaskアプリケーション内で Blueprint を識別するために使用されます。
  • 第2引数の__name__(モジュール名)は、Blueprint が定義されている Pythonモジュールの名前を示します。
  • 最後の引数のurl_prefix='/myapp'は、Blueprint に関連するルート(エンドポイント)のURLプレフィックスを設定します。

最後の引数についての補足としては、url_prefix='/myapp' を指定した場合、この Blueprint内で定義されたルートは/myapp のパスでアクセスできます。

Blueprint内で@app.route('/home')を定義すると、最終的なエンドポイントは/myapp/home です。

最後にテンプレートについては、myapp/index.htmlshare/layout.htmlをそれぞれ以下のように記述します。

share/layout.html

<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <title></title>
        <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='stylesheets/style.css') }}" />
        <script src="{{ url_for('static', filename='javascripts/script.js') }}"></script>
    </head>
    <body>
      <div class="content">
        <div id="main">
        {%- block content %} {% endblock %}
        </div>
      </div>
    </body>
</html>

myapp/index.html

{%- extends "./share/layout.html" %}
{%- block content %}
    <h1>myapp/index.html</h1>
{%- endblock %}

アプリの起動

Waitress を使って起動するには、以下のコマンドを実行します。

waitress-serve --listen=127.0.0.1:8000 app:app

ブラウザを開き、以下のアドレスを入力し、ページが表示されれば動作確認は完了です。

http://127.0.0.1:8000/myapp/

ログの出力

Waitressを利用して、各リクエストのログを出力するには、app.pyを以下のように変更します。

flaskapp/app.py

import logging
import datetime
from flask import Flask, request
from waitress import serve
from flaskapp import create_app

# `werkzeug` のロガーを取得
log = logging.getLogger('werkzeug')
log.setLevel(logging.INFO)  # INFOレベルでリクエストを記録
log.addHandler(logging.StreamHandler())  # コンソール出力を有効化

app = create_app()

@app.after_request
def log_response(response):
    current_time = datetime.datetime.now().strftime("%d/%b/%Y %H:%M:%S")
    log_message = f'{request.remote_addr} - - [{current_time}] "{request.method} {request.path} HTTP/1.1" {response.status_code} -'
    log.info(log_message)
    return response

if __name__ == '__main__':
    serve(app, host='127.0.0.1', port=8000)