Python | Web / API:環境変数

Python Python
スポンサーリンク

概要(環境変数は「設定や秘密をコード外で持つための保管場所」)

環境変数は、OSが管理する名前つきの設定値です。Pythonでは os.environ や os.getenv を使って取り出し、APIキーやDB接続文字列などの「環境ごとに変わる値」をコード外で安全に管理できます。重要なのは、取得方法(存在しない時の扱い)、型変換とバリデーション、OS側での設定方法、そして「秘密情報は環境変数から読む」運用です。


基本の使い方(ここが重要)

取得の最短パターン

import os

api_key = os.getenv("API_KEY")              # 無ければ None(デフォルト可)
db_url  = os.environ.get("DATABASE_URL", "")# 無ければ ""(デフォルト指定)
print(api_key, db_url)
Python
  • ポイント: 存在しない時の挙動が違います(getenvはNone、getは第2引数の値)。目的に応じて使い分けます。

必須値は「無ければエラー」にする

import os

def require(name: str) -> str:
    val = os.getenv(name)
    if not val:
        raise RuntimeError(f"環境変数が未設定: {name}")
    return val

API_KEY = require("API_KEY")
Python
  • ポイント: 必須の秘密(APIキーなど)は起動時にチェックして、早期に失敗させた方が安全です。

型変換(bool・int)とバリデーション

import os

timeout = int(os.getenv("TIMEOUT", "5"))
debug   = os.getenv("DEBUG", "0").lower() in {"1", "true", "yes"}
if timeout <= 0:
    raise ValueError("TIMEOUTは正の整数で指定してください")
Python
  • ポイント: 文字列で渡されるため、型変換範囲チェックを必ず入れます。

OSでの設定方法(Windows・macOS/Linux)

一時的に設定して実行(macOS/Linux)

API_KEY=secret123 DATABASE_URL="postgres://..." python app.py
Python
  • ポイント: 先頭に並べる形式は「そのコマンド実行時だけ有効」。使い捨てのテストに便利です。

永続設定(bash系)

# ~/.bashrc や ~/.zshrc に追記
export API_KEY=secret123
export DATABASE_URL="postgres://..."
# 反映
source ~/.bashrc
Python
  • ポイント: シェル起動のたびに有効化。端末ごとの設定がやりやすいです。

Windows(PowerShell)

[Environment]::SetEnvironmentVariable("API_KEY","secret123","User")
[Environment]::SetEnvironmentVariable("DATABASE_URL","postgres://...","User")
Python
  • ポイント: User/Process/Machine のスコープを選べます。再起動や再ログインが必要な場合あり。

.envファイルと読み込み(開発時の定番)

python-dotenv を使った読み込み

# pip install python-dotenv
from dotenv import load_dotenv
import os

load_dotenv()  # .env を読み込む(カレントディレクトリ)
API_KEY = os.getenv("API_KEY")
Python
  • ポイント: .env は「開発時の設定集」。本番では環境変数を直接注入し、.envを使わないのが基本です。

.env の例(Git管理と秘密の扱い)

# .env(Gitに入れない)
API_KEY=secret123
DATABASE_URL=postgres://user:pass@host:5432/db
DEBUG=1
Python
  • ポイント: 秘密をGitに含めない。サンプル用に .env.example を用意して共有すると安全です。

実務の型(設定の階層化・安全運用)

優先順位(安全な上書き設計)

  • 基本:環境変数 > 設定ファイル > コードのデフォルト
    • 理由: 環境変数で最後に上書きできると、デプロイ先ごとの差分管理が楽になります。

秘密情報の扱い

  • 原則: APIキーやトークン、パスワードは環境変数で渡す。コード・YAML・JSONへ直書きしない。
  • 補助: CI/CDやクラウドの「シークレット管理」を使い、デプロイ時に注入。ローカルは .env。

PATH とコマンド解決

  • 理解: PATH は「実行ファイルの探索場所」リスト。PythonやAWS CLIなどが「どこからでも動く」かはPATHに依存。
  • 対策: インストール時にPATH登録、異なるバージョンの競合は「仮想環境」や明示パスで管理。

応用トピック(サブプロセス、辞書化、テスト)

サブプロセスへ渡す環境

import os, subprocess

env = os.environ.copy()
env["API_KEY"] = "temp-key"  # 子プロセスだけ上書き
subprocess.run(["python", "worker.py"], env=env, check=True)
Python
  • ポイント: 親の環境をコピーして必要部分だけ変更すると、影響範囲を限定できます。

まとめて読み取り・辞書にする

import os

CONFIG = {
    "api_key": os.getenv("API_KEY", ""),
    "db_url":  os.getenv("DATABASE_URL", ""),
    "debug":   os.getenv("DEBUG", "0").lower() in {"1", "true", "yes"},
}
Python
  • ポイント: 一箇所に集めて「型変換・検証」を済ませると、以降のコードがシンプルになります。

テスト時の差し替え

import os
from unittest import mock

with mock.patch.dict(os.environ, {"API_KEY": "test-key"}, clear=False):
    # このブロック内だけ API_KEY が差し替わる
    ...
Python
  • ポイント: mock.patch.dict は安全で速い。テストケースごとに環境を切り替えられます。

例題で身につける(定番から実務まで)

例題1:必須チェック+型変換のひな形

import os

def require(name: str) -> str:
    val = os.getenv(name)
    if not val:
        raise RuntimeError(f"環境変数が未設定: {name}")
    return val

CONFIG = {
    "api_key": require("API_KEY"),
    "timeout": int(os.getenv("TIMEOUT", "5")),
    "debug":   os.getenv("DEBUG", "0").lower() in {"1","true","yes"},
}
print(CONFIG)
Python
  • ポイント: 起動直後に失敗させると、原因がわかりやすく安全です。

例題2:.env 読み込み+安全なデフォルト

from dotenv import load_dotenv
import os

load_dotenv()  # .env を読む(開発向け)
API_KEY = os.getenv("API_KEY") or ""
if not API_KEY:
    print("警告: API_KEYが未設定(開発中のみ許容、本番は必須)")
Python
  • ポイント: 開発中は警告で様子を見る、本番は require にして落とす運用が現実的。

例題3:サブプロセスへの一時注入

import os, subprocess

env = os.environ.copy()
env["DEBUG"] = "1"
subprocess.run(["python", "-c", "import os; print(os.getenv('DEBUG'))"], env=env)
Python
  • ポイント: 親プロセスの安全性を保ちつつ、子だけ設定変更できます。

例題4:テストで環境を切り替えて振る舞い確認

import os
from unittest import mock

def is_debug() -> bool:
    return os.getenv("DEBUG", "0") in {"1", "true", "yes"}

with mock.patch.dict(os.environ, {"DEBUG": "1"}):
    assert is_debug() is True

with mock.patch.dict(os.environ, {"DEBUG": "0"}):
    assert is_debug() is False
Python
  • ポイント: 仕様に沿って「値の解釈」を固定すると、後からの変更に強くなります。

まとめ

環境変数は「設定・秘密・動作切り替え」をコード外で安全に管理するための基礎です。取得は os.getenv と os.environ.get を使い分け、必須値は起動時にチェック。文字列で届く前提で型変換とバリデーションを入れ、OS側設定(export・PowerShell・CIのシークレト)と .env を使い分ける。優先順位は「環境変数が最上位」、サブプロセスやテストでは安全に一時差し替え。これらの型を身につければ、初心者でも「安全・柔軟・再現性の高い」設定管理が短いコードで実現できます。

タイトルとURLをコピーしました