Skip to main content

py-generic-config

py-generic-config 是一个通用的 Python 配置管理库。它提供了本地 YAML 解析环境变量插值面向对象类型安全配置类 (@configclass)远程配置中心接入 (Nacos 等) 以及 双层配置热更新监听能力。


✨ 核心特性

  • 🛠 双源加载:支持本地 settings.yaml + 远程配置中心(Nacos/自定义 Provider)双重加载与覆盖。
  • 🔍 环境变量自动替换:支持 ${ENV_VAR:default_value} 语法自动解析与默认值兜底。
  • 🛡 类型安全配置类:通过 @configclass 装饰器与 Annotated[T, Value(...)] 实现配置项自动类型转换、默认值与深层嵌套。
  • 🔄 解耦配置源 (Provider 模式):内置 Nacos 2.x 配置源,同时支持轻松扩展 Consul、Apollo、Etcd 或自定义配置源。
  • 🔔 双层热更新监听机制
    • 模块级 Hook (register_reload_hook):配置变更时,一键自动重新加载所有配置类或重连数据库。
    • Key 级 Watcher (watch/unwatch):精确监听指定 key(如 database.host)的值变更,获取 (new_val, old_val)

📦 安装指南

1. 基础安装(仅本地 YAML 配置)

pip install .

2. 带有 Nacos 远程配置中心支持的安装

pip install .[nacos]
# 或直接安装 SDK
pip install v2nacos

🚀 快速上手

1. 准备本地配置文件

在项目根目录创建 settings.yaml(或使用CONFIG_PATH环境变量指定路径):

app:
  name: "my-service"
  debug: ${APP_DEBUG:true}
  database:
    host: ${DB_HOST:127.0.0.1}
    port: 3306
    username: "root"
    password: "${DB_PWD:123456}"

2. 定义类型安全的配置类

使用 @configclass 装饰器定义 Python 配置类,属性将自动映射并类型转换:

from typing import Annotated
from py_generic_config import configclass, Value

# @configclass("database") 加不加这个无所谓,默认按照变量名映射
class DBConfig:
    host: Annotated[str, Value("host", "localhost")]
    port: Annotated[int, Value("port", 3306)]
    username: Annotated[str, Value("username")]
    password: Annotated[str, Value("password")]
    
@configclass("app")
class AppConfig:
    name: Annotated[str, Value("name")]
    debug: Annotated[bool, Value("debug", False)]
    database: Annotated[DBConfig, Value("database")] # 嵌套配置类(也可以不用Annotated,直接使用DBConfig)

# 获取配置值(支持类型自动转换,如 str -> int/bool)
print(AppConfig.database.host)  # 输出: 127.0.0.1
print(AppConfig.database.port)  # 输出: 3306 (int 类型)

🌐 远程配置接入与热更新 (Nacos)

可以通过 ConfigLoader 接入 Nacos 远程配置中心,并支持配置热更新。

import asyncio
import logging
from py_generic_config import (
    ConfigLoader, 
    NacosConfigProvider, 
    reload_configclass,
    yaml_config
)

logging.basicConfig(level=logging.INFO)

# 1. 实例化 Nacos Provider
nacos_provider = NacosConfigProvider(
    ip="127.0.0.1",
    port=8848,
    namespace="dev-namespace",
    username="nacos",
    password="nacos_password",
    group="DEFAULT_GROUP"
)

# 2. 创建 ConfigLoader 并注入 Provider
loader = ConfigLoader(provider=nacos_provider)

# ==================== 热更新监听设置 ====================

# 🎯 方式 A:注册模块级重载 Hook (全量/配置类刷新)
def on_config_reload():
    reload_configclass(AppConfig)  # 重新刷新配置类属性
    print(f"🔄 配置类已刷新!当前数据库Host: {AppConfig.database.host}")

loader.register_reload_hook(on_config_reload)


# 🎯 方式 B:注册 Key 级细粒度 Watcher (精确监听某个键)
def on_db_host_change(new_val, old_val):
    print(f"📢 数据库 Host 发生了变更: {old_val} -> {new_val}")

loader.watch("database.host", on_db_host_change)

# ========================================================

async def main():
    # 3. 初始化 Loader 并拉取远程配置
    await loader.initialize(data_ids=["app_config.yaml"])

    # 4. 获取配置(自动将远程拉取的配置与本地配置合并)
    print("应用名称:", yaml_config.get("app.name"))
    print("数据库 Host:", AppConfig.database.host)

    # 保持程序运行以接收 Nacos 长轮询推送
    try:
        await asyncio.Event().wait()
    finally:
        await loader.close()

if __name__ == "__main__":
    asyncio.run(main())

🛠 进阶用法

1. 扩展自定义配置源 (Custom ConfigProvider)

如果你使用的不是 Nacos,而是 Consul、Apollo、Etcd 或自研配置中心,只需继承 BaseConfigProvider 实现 4 个抽象方法:

from py_generic_config import BaseConfigProvider, ConfigLoader

class MyConsulProvider(BaseConfigProvider):
    async def init(self) -> None:
        # 初始化 Consul 客户端连接
        pass

    async def get_config(self, data_id: str, group: str = "DEFAULT_GROUP") -> str:
        # 从 Consul 获取 YAML/JSON 文本内容
        return "database:\n  host: 10.0.0.1"

    async def add_config_listener(self, data_id: str, listener, group: str = "DEFAULT_GROUP") -> None:
        # 注册 Consul 监听逻辑,当配置改变时调用 listener(data_id, new_content)
        pass

    async def close(self) -> None:
        # 关闭连接
        pass

# 使用自定义 Provider
loader = ConfigLoader(provider=MyConsulProvider())

2. 取消 Key 级监听 (unwatch)

# 注册监听
loader.watch("database.host", on_db_host_change)

# 在不需要时取消监听
loader.unwatch("database.host", on_db_host_change)

3. 本地覆盖文件 (config_overrides.yaml)

库默认支持读取 config_overrides.yaml(路径可通过环境变量 CONFIG_OVERRIDES_PATH 修改),该文件内的配置项优先级高于 settings.yaml,常用于本地开发阶段临时覆盖配置而不污染 Git 仓库。


🏗 架构设计

+-------------------------------------------------------------+
|                       业务代码 (Your App)                     |
|    DBConfig.host  /  yaml_config.get()  /  reload_hooks     |
+------------------------------+------------------------------+
                               |
+------------------------------v------------------------------+
|                     ConfigLoader (加载器)                    |
|   - 依赖注入 Provider                                        |
|   - 监听与 Diff 计算 (_compute_diff)                           |
|   - 触发 ReloadHooks 与 Watchers                            |
+------------------------------+------------------------------+
                               |
       +-----------------------+-----------------------+
       |                                               |
+------v----------------------+             +----------v----------+
|  BaseConfigProvider (抽象源) |             |  YamlConfig (本地)  |
|  - NacosConfigProvider      |             |  - settings.yaml    |
|  - MyCustomProvider         |             |  - ${ENV} 环境变量  |
+-----------------------------+             +---------------------+

📄 许可证

本项目基于 MIT 许可证 协议开源。详细许可内容请参阅项目根目录下的 LICENSE 文件,或参考 MIT 官方开源协议说明

你可以自由地修改、分发和商业化使用本项目,但请保留原有的版权声明和许可声明哦 (๑•̀ㅂ•́)و✧!

Release files for py-generic-config 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for py-generic-config 0.2.0
File Size Uploaded
py_generic_config-0.2.0.tar.gz 16.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for py-generic-config 0.2.0
File Interpreter ABI Platform
py_generic_config-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.0 kB

Release files / py_generic_config-0.2.0.tar.gz

Download URL py_generic_config-0.2.0.tar.gz
Size 16.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f5d4a10357a9cadf86a74aaba6687fc674b90297868d24d9f8e2ae62efab7542
BLAKE2b-256 checksum
How to use checksums
59d6c6bca4d466a30dc91284184e48d4c88aad02bd08fe6122dadd7fc4d65cc0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.0

Release files / py_generic_config-0.2.0-py3-none-any.whl

Download URL py_generic_config-0.2.0-py3-none-any.whl
Size 13.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
700cc2f44d55ca3b844c217abdd23d9b379ed1a4695588e7fc337c5d218623a8
BLAKE2b-256 checksum
How to use checksums
11c06c3cf93826f605a74fa36630af1a90ee4d8f14212e29b4a9405f751279dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.0

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page