Python Pydantic校验配置文件的示例详解

 更新时间:2026年06月30日 08:26:35   作者:花酒锄作田  
本文详细介绍了如何使用Pydantic对Tom配置文件进行参数校验,替代传统的环境变量配置方式,简化配置管理,提高代码可读性,通过示例代码展示如何构建配置类并实例化获取全局配置,希望对大家有所帮助

前言

最近很多新项目使用环境变量作配置,尤其是部署在k8s上的项目,把 configmap 或者 secret 直接塞到 pod 环境变量里面,再引入pydantic-settings做参数校验,用起来特别方便。但pydantic-settings是环境变量优先的,而对于大一点的项目,配置项可能上百个,我还是比较习惯用配置文件,把相关配置嵌套起来方便管理。

以前写基于文件的配置类的时候,我是先写各种Mixin类,其中取值方法里面写校验逻辑,然后组装成一个Config类。习惯之后觉得也还行,直到今天加一组配置的时候才想起来:不对,既然项目(基于FastAPI)都已经引入pydantic了,我干嘛不直接用pydantic做参数校验?!

本文以toml格式配置文件(其实就是加载toml为字典交给pydantic,换成json和yaml用法是近似的)为例,搭配pydantic实现带有参数校验功能的配置类。

安装依赖

只需要安装pydantic即可,不用安装pydantic-settings。Python 3.11 后标准库自带tomllib用来解析 toml 文件。

uv add -U pydantic
# python -m pip install -U pydantic

配置文件示例

以下为部分配置文件内容,实际项目中肯定会有更多配置项:

[service]
  host = "127.0.0.1"
  port = 8000
  env = "dev"  # dev, prod
[service.log]
  level = "DEBUG"  # DEBUG, INFO, WARNING, ERROR
  output = "BOTH"  # STDOUT, FILE, BOTH
  dir = "logs"
  # file_path = "logs/app.log"
  retention_days = 30  # days
  colorize = true
  diagnose = true
  backtrace = true
[database.postgres]
  host = "127.0.0.1"
  port = 5432
  user = "your_user"
  password = "your_password"
  dbname = "your_dbname"
  channel_name = "task_queue"
  pool_max_size = 10
  pool_min_size = 4

示例代码

配置类作为基础类,我一般设计成只要配置类加载有问题,就直接抛出异常中止服务。而且引入 pydantic 后,配置错误的地方也会很明确的提示出来。

服务自身运行配置和日志配置: pkg/config/service.py

from typing import Annotated, Literal

from pydantic import BaseModel, Field


class ServiceLogConfig(BaseModel):
    level: Annotated[Literal["DEBUG", "INFO", "WARNING", "ERROR"], Field(default="INFO", description="日志级别")]
    dir: Annotated[str, Field(default="logs", description="日志文件目录")]
    output: Annotated[Literal["STDOUT", "FILE", "BOTH"], Field(default="STDOUT", description="日志输出方式")]
    retention_days: Annotated[int, Field(default=7, gt=0, le=30, description="日志文件轮转天数")]
    colorize: Annotated[bool, Field(default=True, description="是否启用颜色日志输出")]
    backtrace: Annotated[bool, Field(default=True, description="是否启用堆栈跟踪日志输出")]
    diagnose: Annotated[bool, Field(default=True, description="是否启用诊断日志输出")]


class ServiceConfig(BaseModel):
    host: Annotated[str, Field(default="127.0.0.1", description="服务监听地址")]
    port: Annotated[int, Field(default=8080, description="服务监听端口")]
    env: Annotated[Literal["dev", "prod"], Field(default="dev", description="服务环境")]
    log: ServiceLogConfig

数据库配置: pkg/config/postgres.py

from typing import Annotated
from urllib.parse import quote_plus

from pydantic import BaseModel, Field


class PostgresConfig(BaseModel):
    host: Annotated[str, Field(..., description="PostgreSQL host")]
    port: Annotated[int, Field(..., description="PostgreSQL port")]
    user: Annotated[str, Field(..., description="PostgreSQL user")]
    password: Annotated[str, Field(..., description="PostgreSQL password")]
    dbname: Annotated[str, Field(..., description="PostgreSQL database name")]
    pool_min_size: Annotated[int, Field(..., description="Minimum size of PostgreSQL connection pool")]
    pool_max_size: Annotated[int, Field(..., description="Maximum size of PostgreSQL connection pool")]

    def get_dsn(self) -> str:
        """Get PostgreSQL connection string (DSN)"""
        user = quote_plus(self.user)
        password = quote_plus(self.password)
        return f"postgresql://{user}:{password}@{self.host}:{self.port}/{self.dbname}"


class DatabaseConfig(BaseModel):
    postgres: PostgresConfig

组合成总的配置类:

from pathlib import Path
import tomllib

from pydantic import BaseModel, ValidationError

from .agent import AgentConfig
from .postgres import DatabaseConfig


class Config(BaseModel):
    service: ServiceConfig
    database: DatabaseConfig


def get_config() -> Config:
    """Get the global configuration instance."""
    config_file = Path(__file__).parent.parent.parent / "conf" / "config.toml"

    with open(config_file, "rb") as f:
        raw_config = tomllib.load(f)

    try:
        # pydantic v2中推荐用 model_validate 实现严格校验
        return Config.model_validate(raw_config)
    except ValidationError as e:
        raise RuntimeError(f"Failed to validate config: {e}") from e

pkg/config/__init__.py中实例化获取全局单例

from .config import get_config


cfg = get_config()

__all__ = ["cfg"]

调用方使用配置类对象:

from pkg.config import cfg

dsn = cfg.database.postgres.get_dsn()

补充

校验失败示例

假设我在配置文件中把 database.postgres.port5432 改成 "5432qwer", 而模型类对该字段声明的是int类型,那么启动就会直接失败,错误提示如下,其中很清晰地提示了database.postgres.port的入参校验失败。

RuntimeError: Failed to validate config: 1 validation error for Config
database.postgres.port
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='5432qwer', input_type=str]
For further information visit https://errors.pydantic.dev/2.13/v/int_parsing

到此这篇关于Python Pydantic校验配置文件的示例详解的文章就介绍到这了,更多相关Pydantic校验配置文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python用WxPython库实现无边框窗体和透明窗体实现方法详解

    python用WxPython库实现无边框窗体和透明窗体实现方法详解

    这篇文章主要介绍了python用WxPython库实现无边框窗体和透明窗体实现方法详解,需要的朋友可以参考下
    2020-02-02
  • python采集天气数据并做数据可视化

    python采集天气数据并做数据可视化

    本文主要介绍了python采集天气数据并做数据可视化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Python跨平台读取 .doc格式文件的方法

    Python跨平台读取 .doc格式文件的方法

    在跨平台的开发环境中,处理不同文件格式是一个常见问题,尤其是老旧的 .doc 格式,在这篇博客中,我们将介绍一种基于 Python 的跨平台方案,使用 LibreOffice 将 .doc 文件转换为 .docx 格式,之后再通过 docx2txt 进一步处理文档内容,需要的朋友可以参考下
    2025-02-02
  • VTK与Python实现机械臂三维模型可视化详解

    VTK与Python实现机械臂三维模型可视化详解

    这篇文章主要介绍了VTK与Python实现机械臂三维模型可视化详解,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • Python获取列表值的方法小结

    Python获取列表值的方法小结

    在 Python 编程中,列表(list)是一种非常常见且强大的数据结构,本文将通过简洁明了的方式,结合代码和案例,介绍如何获取列表中的值,需要的可以了解下
    2024-11-11
  • 解决.ui文件生成的.py文件运行不出现界面的方法

    解决.ui文件生成的.py文件运行不出现界面的方法

    今天小编就为大家分享一篇解决.ui文件生成的.py文件运行不出现界面的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • Python循环取数组的值的方法实现

    Python循环取数组的值的方法实现

    本文主要介绍了两种Python中遍历数组的方法,for循环和索引,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-12-12
  • 基于Python实现人脸自动戴口罩系统

    基于Python实现人脸自动戴口罩系统

    2019年新型冠状病毒感染的肺炎疫情发生以来,牵动人心,举国哀痛,口罩、酒精、消毒液奇货可居。这篇文章主要介绍了基于Python的人脸自动戴口罩系统,需要的朋友可以参考下
    2020-02-02
  • 超级详细实用的pycharm常用快捷键

    超级详细实用的pycharm常用快捷键

    本文详细总结了Pycharm的常用快捷键,下文介绍使用方法和场景, 并不需要记忆这些快捷键, 你只需要知道有这些快捷键, 再需要用的时候查看一下, 用的多了自然也就记住了,需要的朋友可以参考下
    2021-05-05
  • pandas如何将DataFrame 转为txt文本去除引号

    pandas如何将DataFrame 转为txt文本去除引号

    这篇文章主要介绍了pandas如何将DataFrame 转为txt文本去除引号,文中补充介绍了DataFrame导CSV txt || 每行有双引号的原因及解决办法,感兴趣的朋友跟随小编一起看看吧
    2024-01-01

最新评论