はじめに
いまさらながら Flask について整理していきます。「Flaskとかいうやつを使って、試しにアプリ開発にトライしてみたい」くらいの感覚の人を対象にしています。
Flaskのバージョンは 0.12.2 です。
この記事では、Flaskアプリケーションの設定方法や切り替え方について紹介します。その他のFlaskまとめシリーズはこちらから。
アプリケーションの設定について
なんらかのアプリケーションを動作させるとき、その環境によって設定を変更したい場合があります。
たとえば、DBの接続情報です。一般的に、開発環境と本番環境で異なるDBに接続します。そうでなければ本番環境のDBにゴミデータを混ぜ込んでしまったり、データを破壊してしまう恐れがあるためです。また、デバッグモードは開発環境ではONにしますが、本番環境では一般的にOFFにします。
小さなアプリケーションであれば、ささっと設定内容をハードコーディングしてしまうのも悪くないかもしれません。しかし、Flaskではハードコーディングする以外の手段も提供しています。
Flaskの設定はどこに保存されるのか
Flaskクラスの config
属性に格納されています。config
はdictionaryを継承した Config
クラスのインスタンスです。
from flask import Flask app = Flask('sample') print(app.config)
上記コードを実行すれば、configの値、つまり、アプリケーションの設定内容を確認できます。すべての設定項目は、 公式のリファレンス をご確認ください。
設定をハードコーディングする場合は、configに値を設定してやれば良いです。以下は、DEBUGモードをONにする場合の例です。
app = Flask('sample') app.config['DEBUG'] = True
configはdictionaryを継承しているので、設定にあたってdictionaryの各種メソッドを使うこともできます。短期的に見るとこの方法がもっとも簡単なのですが、設定項目等が増えてくると長々と設定を記載する羽目になります。これはあまり綺麗な書き方とは言えません。
Flaskの提供する設定方法
Config
クラスが持つ値更新用のメソッドを利用します。
方法 | メソッド名 |
---|---|
名前=値 形式で記載された設定ファイルから読み込む |
from_pyfile |
環境変数に指定されている設定ファイルから読み込む | from_envvar |
専用クラスで定義した値を読み込む | from_object |
json形式の設定ファイルを読み込む | from_json |
辞書型のデータを読み込む | from_mapping |
なお、設定値のキーはすべて大文字にしなければなりません。設定値に小文字を含んでいてもエラーにはなりませんが、すべて無視されます。
configはdictionaryを拡張したものなので、独自の設定値を追加することもできます。守らなければいけないルールは、キーを大文字にするということだけです。
具体例
開発、テスト、本番の3つの環境があるという前提で話を進めます。
from_pyfile
設定ファイルのパスを指定して、読み込みます。
app.config.from_pyfile('development.cfg')
# development.cfg DEBUG=True TESTING=False
from_pyfile
に文字列でファイルパスを設定してしまうと、環境ごとに柔軟に設定ファイルを切り替えるのが難しくなります。そのため、環境変数を使って設定を切り替えることが多いです。
from_envvar
from_envvar
は、環境変数に設定されたファイルパスを元に設定を読み込みます。
$ export FLASK_CONFIG_FILE_PATH=/path/to/development.cfg
app.config.from_envvar('FLASK_CONFIG_FILE_PATH')
この方法であれば、環境変数を設定するだけで読み込む設定ファイルを切り替えることができます。ちなみに、from_envvar
は内部で読み込んだ環境変数の値をもとに from_pyfile
を実行しています。
from_json
こちらはjson形式の設定ファイルを読み込みます。from_envvar
に該当するものはバージョン0.12
の時点ではありません。
app.config.from_json('app_config.json')
{ "DEBUG": true, "TESTING": false }
ここまで紹介した3つの設定読み込み関数の第2引数には silent
というものがあります。デフォルトでは False
であり、True
にすると、ファイルや環境変数が見つからなかった場合に例外を発生させるのではなく、False
を返すようになります。
# return False app.config.from_json('not_exist_config.json', True)
from_object
これまでのファイルから設定値を読み込むのとは異なり、専用クラスで定義した値を読み込みます。以下の例では、本番環境用の設定ファイルを読み込んでいます
app.config.from_object("config.ProductionConfig")
# config.py class Development(object): DEBUG = True DB_URI = "開発環境の設定" class Testing(object): TESTING = True DB_URI = "テスト環境の設定" class Production(object): DB_URI = "本番環境の設定"
instanceフォルダ
設定値に、APIキーなど機密性の高い設定情報を含みたい場合があります。しかし、機密性の高い情報を設定ファイルに直接書くわけにはいきません。うっかり機密性の高い情報を含んだ設定ファイルをGithubにプッシュしてしまったら、全世界に機密情報をばらまくことになってしまいます。Flaskではinstanceフォルダを、そうした機密情報置き場としています。
app_dir/ app.py sample_app/ __init__.py views.py instance/ config.cfg
ただし、instanceをバージョン管理しない設定(.gitignoreへの追加)は自分でしておかなければなりません。 そういったしきたりで扱うというだけで、Flaskが勝手にバージョン管理外のファイルとして扱ってくれるということではありません。
デフォルトのinstanceフォルダは instance/
です。instanceフォルダのパスは自由に設定できます。なお、絶対パスでしか指定できません。
app = Flask(__name__, instance_path='/home/app_dir/custom_instance') print(app.instance_path) # instanceフォルダのパスを出力 app.config.from_pyfile('custom_instance/config.cfg')
instanceフォルダ以下のファイルを読み込む場合は、この記事で紹介した各種メソッドで読み込むことができます。ファイルパスを指定する際に、instanceフォルダを毎回指定するのは手間がかかります。アプリケーションのrootパスではなく、自動的にinstanceフォルダを見るように設定を切り替えることができます。
app = Flask(__name__, instance_relative_config=True) # instance/config.cfg と指定しなくてよい app.config.from_pyfile('config.cfg')
どう使うのが良いのか
まとめると、以下のような方針で設定ファイルを作成するのが良いように思えます。
- 柔軟に設定を切り替えられるように、環境変数を用いる
- 開発環境、テスト環境、本番環境ごとに設定を作る
- 機密性の高い情報は、instance以下に設定ファイルを作成する
app_dir/ app.py config.py sample_app/ __init__.py instance/ sensitive_data.cfg
# app.py import os from flask import Flask config_type = { "development": "config.Development", "testing": "config.Testing", "production": "config.Production" } app = Flask('sample', instance_relative_config=True) app.config.from_object(config_type.get(os.getenv('FLASK_APP_ENV', 'production'))) app.config.from_pyfile('sensitive_data.cfg')
設定ファイルは、from_object
の説明のところに書いてあるものをそのまま使っています。また、instanceフォルダに切り替えているので、 from_pyfile
がinstance以下を見るようになっています。なので、機密性の高い情報以外の設定は、from_object
で読み込むようにしています。
また、環境変数がない場合はデフォルトで production
の設定が反映されるようにしています。Flaskはオプションを設定せずに起動した場合に非デバッグモードで起動します。その挙動と合わせて、デフォルトはproduction
としています。また、環境変数を設定し忘れて、うっかりデバッグモードで実行してしまうことを防げます。