設定の誤字を既定値として扱わない
目標
厳密な設定のパース・秘密情報の除去・アプリごとのスナップショットをテストします。
なぜ重要なのか
文字列のfalseをboolに変換したら、Trueになりました。本番でデバッグのレスポンスが有効になり、ステータスページには、設定の辞書全体が出力されました。環境変数は文字列なので、型の宣言だけでは、安全な値になりません。設定を読む時点と、公開する範囲も、アプリケーションの契約です。
ステップ
/root/work/fa-config-lab/service.pyで、parse_bool(value)は、大文字と小文字を区別しないtrueまたはfalseだけを、boolとして返します。空白が付いているか、文字列でなければ、ValueErrorです。
最初に一度だけ準備してください。既存のファイルは上書きしません。
mkdir -p /root/work/fa-config-lab
test -e /root/work/fa-config-lab/service.py || cp /opt/fixtures/ten_labs/fa-config-lab/service.py /root/work/fa-config-lab/service.py
cd /root/work/fa-config-lab
-
/root/work/fa-config-lab/service.pyで、parse_port(value)は、ASCIIの数字だけがある文字列をintに変換して、1–65535なら返します。それ以外は、ValueErrorです。 -
/root/work/fa-config-lab/service.pyで、parse_timeout(value)は、文字列をfloatに変換して、0より大きく30以下の有限の値だけを返します。それ以外は、ValueErrorです。 -
/root/work/fa-config-lab/service.pyで、required_token(env)は、TOKENが文字列で、stripしたあとに空でないときに、stripした値を返します。ないか、空の値は、ValueErrorです。 -
/root/work/fa-config-lab/service.pyで、load_settings(env)は、service=envのSERVICE、または欠落時は'api'、debug=parse_bool(DEBUGの欠落時は'false')、port=parse_port(PORTの欠落時は'8000')、timeout=parse_timeout(TIMEOUTの欠落時は'5')、token=required_tokenの辞書です。空のSERVICEは、ValueErrorです。 -
/root/work/fa-config-lab/service.pyで、public_settings(settings)は、serviceとdebugだけを持つ新しい辞書です。元のデータは変更しません。 -
/root/work/fa-config-lab/service.pyで、snapshot(env)は、load_settingsの結果を返します。呼び出したあとにenvを変更しても、返された設定は変わりません。 -
/root/work/fa-config-lab/service.pyで、create_app(env)は、snapshotをすぐに読み、不正な設定ならValueErrorでアプリの作成を失敗させます。GET /infoは、public_settingsだけを返します。別のenvで作ったアプリ同士で、設定を共有しません。
参考
- インターネットやパッケージのインストールなしで、既存のlab-dev環境で行います。
- 各ステップは、45秒の採点バジェットの中で実行されます。実際のsleepやネットワーク呼び出しを追加しないでください。
- 採点は、提出されたモジュールを新しく読み込んで、独立した入力と一時的なDBで検査します。期待値を定数で返す代わりに、契約を実装してください。
- FastAPI公式ドキュメント・pytest公式ドキュメント・Python sqlite3
- 限界: 通常の辞書で環境を注入するので、実際のプロセスのグローバルな環境には依存しません。暗号化された秘密情報のストア、キーのローテーション、動的な再読み込みまで実装する例ではありません。トークンの文字列は学習用の入力で、実際の本番のキーを、ラボのPodに入れてはいけません。
真偽値を明示的にパースする
/root/work/fa-config-lab/service.pyで、parse_bool(value)は、大文字と小文字を区別しないtrueまたはfalseだけを、boolとして返します。空白が付いているか、文字列でなければ、ValueErrorです。
最初に一度だけ準備してください。既存のファイルは上書きしません。
mkdir -p /root/work/fa-config-lab
test -e /root/work/fa-config-lab/service.py || cp /opt/fixtures/ten_labs/fa-config-lab/service.py /root/work/fa-config-lab/service.py
cd /root/work/fa-config-lab
bool('false')はTrueです。許可する2つの文字列を、直接比較してください。
保存したら、bash /opt/lab/checks/fa-config-lab/01-contract.shで確認してください。
ポートの範囲を検査する
/root/work/fa-config-lab/service.pyで、parse_port(value)は、ASCIIの数字だけがある文字列をintに変換して、1–65535なら返します。それ以外は、ValueErrorです。
整数への変換が成功しても、有効なポートの範囲であるという意味ではありません。
保存したら、bash /opt/lab/checks/fa-config-lab/02-contract.shで確認してください。
タイムアウトを有限の値にする
/root/work/fa-config-lab/service.pyで、parse_timeout(value)は、文字列をfloatに変換して、0より大きく30以下の有限の値だけを返します。それ以外は、ValueErrorです。
NaNは、通常の比較で予想と違う動作をするので、isfiniteを確認します。
保存したら、bash /opt/lab/checks/fa-config-lab/03-contract.shで確認してください。
必須の秘密情報の欠落を拒否する
/root/work/fa-config-lab/service.pyで、required_token(env)は、TOKENが文字列で、stripしたあとに空でないときに、stripした値を返します。ないか、空の値は、ValueErrorです。
欠落した必須の秘密情報を、例の既定値で置き換えません。
保存したら、bash /opt/lab/checks/fa-config-lab/04-contract.shで確認してください。
欠落に対してだけ既定値を適用する
/root/work/fa-config-lab/service.pyで、load_settings(env)は、service=envのSERVICE、または欠落時は'api'、debug=parse_bool(DEBUGの欠落時は'false')、port=parse_port(PORTの欠落時は'8000')、timeout=parse_timeout(TIMEOUTの欠落時は'5')、token=required_tokenの辞書です。空のSERVICEは、ValueErrorです。
getの既定値と、orで既定値に切り替える書き方は、空文字列の扱いが違います。
保存したら、bash /opt/lab/checks/fa-config-lab/05-contract.shで確認してください。
公開する設定から秘密情報を取り除く
/root/work/fa-config-lab/service.pyで、public_settings(settings)は、serviceとdebugだけを持つ新しい辞書です。元のデータは変更しません。
トークンの値の一部をマスキングするよりも、フィールドそのものを公開しない契約を使います。
保存したら、bash /opt/lab/checks/fa-config-lab/06-contract.shで確認してください。
外部の変更と設定を分離する
/root/work/fa-config-lab/service.pyで、snapshot(env)は、load_settingsの結果を返します。呼び出したあとにenvを変更しても、返された設定は変わりません。
アプリの起動時点の設定を、あとで変わる入力の辞書から分離します。
保存したら、bash /opt/lab/checks/fa-config-lab/07-contract.shで確認してください。
起動の失敗と公開レスポンスを確認する
/root/work/fa-config-lab/service.pyで、create_app(env)は、snapshotをすぐに読み、不正な設定ならValueErrorでアプリの作成を失敗させます。GET /infoは、public_settingsだけを返します。別のenvで作ったアプリ同士で、設定を共有しません。
サーバーが起動したあと、最初のリクエストで設定エラーが表に出ないように、作成時に検証します。
保存したら、bash /opt/lab/checks/fa-config-lab/08-contract.shで確認してください。