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)。
- 模块级 Hook (
📦 安装指南
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)
| File | Size | Uploaded | |
|---|---|---|---|
| py_generic_config-0.2.0.tar.gz | 16.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|