Python Flaskフレームワークの基礎と主要機能ガイド

Flaskアプリケーションの構築と基本ルーティング

Flaskを使用して最小限のWebアプリケーションを作成します。以下のコードは、Flaskインスタンスの生成と基本的なルート定義を示しています。

from flask import Flask

web_app = Flask(__name__)

@web_app.route('/greeting')
def display_greeting():
    return 'こんにちは、Flaskの世界へ!'

開発サーバーの起動とデバッグモード

Flaskの開発サーバーを起動するには、環境変数を設定してコマンドラインから実行する方法と、スクリプト内で直接実行する方法があります。開発中はコードの変更を自動的に検知してサーバーを再起動するデバッグモードを有効にすると効率的です。

from flask import Flask

web_app = Flask(__name__)

@web_app.route('/greeting')
def display_greeting():
    return 'こんにちは、Flaskの世界へ!'

if __name__ == '__main__':
    # デバッグモードを有効にしてサーバーを起動
    web_app.run(debug=True, host='127.0.0.1', port=5000)

URL変数とデータ型の検証

URLパス内に動的な変数を埋め込むことができます。Flaskは正規表現を用いてURLをマッチングし、指定されたデータ型に変換します。型が一致しない場合は404エラーとなります。

# デフォルトは文字列型(スラッシュを含まない)
@web_app.route('/member/')
def get_member(member_id):
    return f'メンバーID: {member_id}'

# 整数型への型変換
@web_app.route('/product/')
def get_product(product_id):
    return f'商品ID: {product_id} (型: {type(product_id).__name__})'

# 複数の変数を組み合わせる
@web_app.route('/employee//')
def get_employee(dept, emp_id):
    return f'部署: {dept}, 社員番号: {emp_id}'

URLの末尾スラッシュとリダイレクトの厳密な挙動

FlaskはURLの末尾スラッシュ(/)に対して厳密なルールを適用します。

  • 末尾スラッシュが定義されているルート(例: /articles/): スラッシュなし(/articles)でアクセスされた場合、サーバーは自動的にスラッシュ付きのURLへ301リダイレクトを行います。
  • 末尾スラッシュが定義されていないルート(例: /dashboard): スラッシュあり(/dashboard/)でアクセスされた場合、404 Not Foundエラーを返します。

この挙動は、ブラウザのキャッシュや相対パスの解決に影響を与えるため、ルート定義時には一貫性を持たせることが重要です。また、redirect()関数を使用することで、任意のURLへ明示的にリダイレクトさせることも可能です。

URLの動的生成(url_for)

ハードコードされたURLの代わりに、url_for()関数を使用してエンドポイント名からURLを動的に生成します。これにより、ルート定義が変更されてもリンク切れを防ぐことができます。

from flask import url_for

@web_app.route('/context')
def show_context():
    # エンドポイント名と引数からURLを生成
    target_url = url_for('get_product', product_id=42)
    return f'生成されたURL: {target_url}'

HTTPメソッドの処理(GETとPOST)

デフォルトではルートはGETリクエストのみを受け付けます。POSTリクエストなどを許可するには、methods引数を使用します。リクエストオブジェクトを通じて、メソッドの種類や送信されたデータを取得できます。

from flask import request

@web_app.route('/api/records', methods=['GET', 'POST'])
def handle_records():
    if request.method == 'POST':
        # POSTデータの取得(フォームデータまたはJSON)
        user_name = request.form.get('user_name')
        user_age = request.form.get('user_age')
        return f'登録完了 - 名前: {user_name}, 年齢: {user_age}'
    
    # GETリクエストの場合
    search_query = request.args.get('query', default='', type=str)
    return f'検索クエリ: {search_query}'

ディレクトリ構造とファイル命名規則

Flaskは特定のディレクトリ構造を自動的に認識します。

  • templates: HTMLテンプレートファイルを配置するディレクトリ。render_template()関数を使用してレンダリングします。
  • static: CSS、JavaScript、画像などの静的ファイルを配置するディレクトリ。HTML内ではurl_for('static', filename='...')を使用して参照します。

Cookieとセッションの管理

クライアント側にデータを保存するCookieと、サーバー側で状態を管理するセッションの扱い方を説明します。セッションを使用するには、secret_keyの設定が必須です。

from flask import make_response, session, redirect, url_for
import os

# セッション暗号化のためのシークレットキー設定
web_app.secret_key = os.urandom(24)

@web_app.route('/set_preference')
def set_preference():
    response = make_response('UIテーマを設定しました')
    response.set_cookie('ui_theme', 'dark_mode')
    return response

@web_app.route('/get_preference')
def get_preference():
    theme = request.cookies.get('ui_theme', 'light_mode')
    return f'現在のテーマ: {theme}'

@web_app.route('/login', methods=['POST'])
def login_user():
    session['current_user'] = request.form.get('username')
    return redirect(url_for('show_profile'))

@web_app.route('/profile')
def show_profile():
    user = session.get('current_user', 'ゲスト')
    return f'ようこそ、{user}さん'

フラッシュメッセージによるフィードバック

リダイレクトを挟んでユーザーに一度だけメッセージを表示させる「フラッシュメッセージ」機能です。カテゴリを指定して、テンプレート側でフィルタリングして表示できます。

from flask import flash, render_template

@web_app.route('/submit_data', methods=['POST'])
def submit_data():
    data = request.form.get('input_data')
    if not data:
        flash('データが入力されていません。', 'error')
    else:
        flash('データが正常に保存されました。', 'success')
    return redirect(url_for('index'))

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

アプリケーションロギング

Flaskは標準のPythonロギング機能と統合されています。アプリケーションの動作状況やエラーを記録するためにapp.loggerを使用します。

import logging

# ロギングレベルの設定
logging.basicConfig(level=logging.INFO)
web_app.logger.setLevel(logging.INFO)

@web_app.route('/compute')
def compute_value():
    web_app.logger.info('計算エンドポイントが呼び出されました')
    try:
        result = 100 / 5
        web_app.logger.info(f'計算結果: {result}')
        return '計算成功'
    except Exception as e:
        web_app.logger.error(f'計算エラーが発生: {str(e)}')
        return '内部エラー', 500

タグ: flask Python WebFramework URLRouting HttpRequest

9月26日 23:59 投稿