通过pydantic验证的环境变量配置程序。
umwelt的Python项目详细描述
umwelt
使用dataclasses或pydantic和 以静态类型友好的方式从环境中加载值。
示例
平坦
>>>os.environ["APP_HOSTS"]='["b.org","sky.net"]'>>>os.environ["APP_TOKEN"]="very secret"
fromtypingimportSequencefrompydanticimportSecretStrimportumweltclassMyConfig:hosts:Sequence[str]token:SecretStrreplicas:int=2config=umwelt.new(MyConfig,prefix="app")
>>>dataclasses.is_dataclass(config)True>>>config.hosts["b.org","sky.net"]>>>config.tokenSecretStr('**********')>>>config.replicas2
嵌套
>>>os.environ["APP_DB_PORT"]="32"
from__future__importannotations# for forward-referencesfrompydanticimportUrlStrimportumweltclassMyConfig:db:DbConfighost:UrlStr="http://b.org"@umwelt.subconfigclassDbConfig:port:intdebug:bool=Falseconfig=umwelt.new(MyConfig,prefix="app")
>>>config.host"http://b.org">>>config.db.port32
安装
$ pip install umwelt
功能
Umwelt.新
umwelt.new
需要一个位置参数:要填充的配置类。
umwelt将把它转换成一个dataclass如果它还不是。
umwelt.new
也接受命名参数:
source
(默认情况下os.environ
)是一个Mapping[str, str]
,从中 将提取值。prefix
可以是字符串或可调用的。作为一个字符串,它被预先设置为 配置字段的名称。作为可调用的,它接收配置字段的名称和 其结果是源密钥名。decoder
是可调用的,需要类型和字符串,并返回 该字符串在该类型或pydantic可以转换的类型中的转换 在那种类型。 例如,当使用(List[Set[int]]
调用umwelt的默认decoder
时,"[[1]]"
),它只是从json中解码字符串,然后返回 lists,pydantic将其正确转换为sets的列表。
@子图
@umwelt.subconfig
标记类,以便当它们显示为字段注释时
在另一个配置类中,umwelt.new
不会从单个
source
值,而不是来自每个类字段的一个source
值。
示例:
classPoint:# no @subconfigdef__init__(self,s:str):# string inputself.x,self.y=s.split(",",1)# arbitrary implementationclassMyConf:point:Pointconf=umwelt.new(MyConf,source={"POINT":"1,2"})# one source entryconf.point# <Point at 0x7f07b1d04750>
conf.point
是point的一个实例,通过传递输入值"1,2"
来构建。
直接发送到Point.__new__
。
只有一个source
键:POINT
。
现在与@umwelt.subconfig
:
@umwelt.subconfigclassPoint:x:inty:intclassMyConf:point:Pointconf=umwelt.new(MyConf,source={"POINT_X":"1","POINT_Y":"2"})conf.point# Point(x=1, y=2)
conf.point
仍然是point的实例(point已被
由umwelt生成的数据类,因此是自动的__str__
实现)。
有2个source
键:POINT_X
和POINT_Y
,每个对应于
point类的字段。
与生态学比较
我用Ecological很久了。 今天,Ecologic的大部分代码库实现了已经发现的特性 在较成熟的dataclasses和pydantic中。 我相信生态系统的设计可以大大简化,并通过 严格区分关注点:
- 类脚手架是dataclasses的责任(相比之下
对于元类来说,更简单、更内省,并且附带了诸如
asdict
); - 类型强制和验证是pydantic(它具有 更多功能,如嵌套数据类型、json模式、序列化等);
- 将pydantic架构(配置类)映射到字符串到字符串
dict(like
os.environ
)是umwelt的职责。
一些破坏兼容性的决定阻止在生态环境中执行此操作:
- 不要自动加载配置值,尤其是在类定义时。
相反,只提供一个加载配置的函数(
umwelt.new
) 当它被调用时。 - 不要将变量前缀绑定到配置类,因为这不起作用 以及嵌套配置。