2020年12月16日水曜日

flask でリクエストのコンテキストに独自の変数を格納する方法

概要

一番簡単なのは flask.g を使うことです
リクエストを跨いで参照することはできないのでリクエスト単位で値を保存したい場合に便利です

環境

  • macOS 10.15.7
  • Python 3.8.5
    • flask 1.1.2

サンプルコード

  • vim app.py
from lib.profile import get_profile

from flask import Flask
from flask import g

app = Flask(__name__)

@app.route("/")
def index():
    set_profile()
    name, age, time = get_profile()
    return "{} - {} - {}".format(name, age, time)

@app.teardown_appcontext
def teardown_profile(exception):
    name = g.pop('name', None)
    age = g.pop('age', None)
    time = g.pop('time', None)
    address = g.pop('address', None)
    print("{} - {} - {} - {}".format(name, age, time, address))
  • vim lib/profile.py
import datetime
from flask import g

def set_profile(name='hawksnowlog', age=10, time=None):
    if 'name' not in g:
        g.name = name 
    if 'age' not in g:
        g.age = age
    if 'time' not in g:
        g.time = datetime.datetime.now().isoformat()

def get_profile():
    return g.name, g.age, g.time

解説

命名規則は get_X/set_X という感じで X にリソース名を指定します
そうすることで teardown_X も使えるようになります
これは teardown はリクエストコンテキストのスコープがなくなる直前にコールされるシグナルになります


値を取得するときも値を保存するときも from flask import g をするだけで OK です

動作確認

  • FLASK_APP=app.py pipenv run flask run

注意点

グローバル変数になるので Flask の Extension なども使えます
なので X のリソース名の部分が被ったり g.name のように name の部分が被ることがあります
基本は被らないように注意する感じですがアプリのコンテキスト

参考サイト

0 件のコメント:

コメントを投稿