Python 配置加载与校验库:Pydantic-settings

介绍

pydantic-settings 是 Pydantic V2 官方拆分出的配置管理专用库,核心是 BaseSettings,用于多源配置加载、类型安全、自动校验,替代 V1 内置的 BaseSettings。

核心能力

  • ✅ 从环境变量 / .env 文件 / 命令行 / 初始化参数加载配置
  • ✅ 类型注解+自动校验,自动类型转换
  • ✅ 配置优先级可控,支持多环境隔离
  • ✅ 支持嵌套模型、别名、密钥、动态导入

安装

# 独立安装(推荐,Pydantic V2 必备)
pip install pydantic-settings

# 若已装 pydantic>=2.0,可直接用
pip install pydantic>=2.0

快速入门

1. 项目结构

your_project/
├── .env          # 环境变量文件
└── config.py     # 配置类

2. .env 文件

# .env
APP_NAME=MyFastAPI
DEBUG=true
DB_URL=postgres://user:pass@localhost:5432/mydb
API_KEY=abc123

3. 定义配置类(config.py)

from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
    # 1. 直接定义字段+类型+默认值
    app_name: str = "DefaultApp"
    debug: bool = False
    db_url: str
    api_key: str

    # 2. 配置项(关键)
    model_config = SettingsConfigDict(
        env_file=".env",        # 加载 .env 文件
        env_file_encoding="utf-8",
        case_sensitive=False,   # 环境变量不区分大小写
        extra="forbid"           # 禁止未定义字段
    )

# 4. 实例化(自动加载+校验)
settings = Settings()

4. 使用配置

from config import settings

print(settings.app_name)  # MyFastAPI(来自 .env)
print(settings.debug)     # True(自动转布尔)
print(settings.db_url)    # postgres://...

核心概念详解

1. 配置来源优先级(从高到低)

  1. 初始化参数(代码传参,最高)
  2. 系统环境变量(OS 级)
  3. .env 文件(本地配置)
  4. 字段默认值(最低)

示例:

# 初始化传参覆盖所有
settings = Settings(app_name="Overwritten")
print(settings.app_name)  # Overwritten

2. 环境变量映射规则

  • 默认规则:字段名 → 大写,如 app_name → APP_NAME
  • 前缀控制:env_prefix="APP_" → APP_APP_NAME
  • 自定义别名:用 Field(validation_alias=...)
from pydantic import Field

class Settings(BaseSettings):
    # 映射到环境变量 MY_APP_NAME
    app_name: str = Field(validation_alias="MY_APP_NAME")
    # 多个别名,优先匹配第一个存在的
    db_host: str = Field(validation_alias=AliasChoices("DB_HOST", "DATABASE_HOST"))

    model_config = SettingsConfigDict(env_prefix="APP_")

3. model_config 常用配置项

model_config = SettingsConfigDict(
    # .env 文件
    env_file=".env",                # 单个文件
    env_file=[".env", ".env.local"],# 多个文件(按顺序加载)
    env_file_encoding="utf-8",

    # 环境变量
    env_prefix="APP_",              # 全局前缀
    case_sensitive=False,           # 不区分大小写
    env_ignore_empty=True,          # 忽略空值环境变量

    # 校验
    extra="forbid",                  # forbid/ignore/allow
    validate_default=True,           # 校验默认值(默认 True)

    # 其他
    cli_parse_args=True,             # 启用命令行参数解析
)

4. 嵌套配置模型

支持复杂分层配置:

from pydantic import BaseModel
from pydantic_settings import BaseSettings

# 子模型
class DBSettings(BaseModel):
    host: str = "localhost"
    port: int = 5432
    user: str
    password: str

class RedisSettings(BaseModel):
    dsn: str = "redis://localhost:6379/0"

# 主配置
class Settings(BaseSettings):
    app_name: str
    debug: bool = False
    db: DBSettings       # 嵌套
    redis: RedisSettings # 嵌套

    model_config = SettingsConfigDict(env_file=".env")

对应 .env:

APP_NAME=MyApp
DEBUG=true
DB_HOST=localhost
DB_PORT=5432
DB_USER=admin
DB_PASSWORD=secret
REDIS_DSN=redis://localhost:6379/1

5. 多环境配置(dev/test/prod)

动态加载不同 .env 文件:

from enum import Enum
from pydantic_settings import BaseSettings, SettingsConfigDict

class Env(str, Enum):
    DEV = "dev"
    TEST = "test"
    PROD = "prod"

class Settings(BaseSettings):
    env: Env = Env.DEV
    app_name: str = "MyApp"

    model_config = SettingsConfigDict(
        # 根据 env 选择文件
        env_file=f".env.{env.value}",
        env_prefix="APP_"
    )

文件:.env.dev、.env.test、.env.prod

6. 敏感配置(密钥)

  • 不要硬编码,用环境变量或 .env(本地)
  • 生产环境用系统环境变量或密钥管理服务(如 AWS Secrets Manager)
class Settings(BaseSettings):
    secret_key: str
    api_key: str

    model_config = SettingsConfigDict(env_file=".env")

7. 命令行参数支持

启用 cli_parse_args=True 后,可通过命令行覆盖:

python main.py --app-name CLI_APP --debug true

高级特性

1. 动态导入(ImportString)

从字符串导入类/函数:

from pydantic import ImportString

class Settings(BaseSettings):
    # 环境变量值为 "module:Class"
    processor: ImportString

2. 别名选择(AliasChoices)

单个字段匹配多个环境变量:

from pydantic import AliasChoices

class Settings(BaseSettings):
    db_url: str = Field(validation_alias=AliasChoices("DB_URL", "DATABASE_URL", "POSTGRES_URL"))

3. 自定义配置源

可扩展加载 JSON/YAML/consul 等:

from pydantic_settings import BaseSettings, SettingsSource

class CustomSource(SettingsSource):
    def __call__(self, settings_cls):
        # 自定义加载逻辑
        return {"app_name": "CustomApp"}

class Settings(BaseSettings):
    app_name: str

    @classmethod
    def settings_customise_sources(cls, settings_cls, init, env, file):
        # 调整优先级:自定义源 > 环境变量 > 文件
        return (init, CustomSource(), env, file)

使用建议

  1. 配置分离:配置与代码分离,不同环境用不同 .env
  2. 类型严格:所有字段指定类型,利用 Pydantic 校验
  3. 敏感信息:生产环境不用 .env,用环境变量或密钥服务
  4. 默认值合理:非敏感字段设默认值,便于本地开发
  5. 配置单一实例:全局只实例化一次 Settings()

常见问题

Q:V1 的 BaseSettings 还能用吗?

A:V2 已移至 pydantic-settings,推荐迁移。

Q:.env 文件不生效?

A:检查路径(默认当前目录)、文件名、编码、是否被 gitignore。

Q:布尔值解析错误?

A:Pydantic 自动解析 true/false/1/0 为布尔。


原文出处:/show_1GW3MYVwFGkm.html