针对多个配置源的python项目的类型化、可扩展、无依赖关系的配置读取器,并在ide中运行良好,可获得良好的自动完成性能。
typed-config的Python项目详细描述
键入配置
用于多个配置源的python项目的类型化、可扩展、无依赖关系的配置读取器,在ide中运行良好,可获得良好的自动完成性能。
需要Python3.6或更高版本。 在pycharm和其他ide中,它将识别配置的数据类型并允许您自动完成。再也不记得用绳子把正确的东西拿出来了! 配置总是以两级结构提供的,因此源配置可以有多个部分,每个部分包含多个键/值配置对。例如: 然后,您可以在代码中创建配置层次结构(可以是平面的,也可以是多层的),并在配置源和配置类的属性中提供字符串之间的匹配。 您可以提供一个或多个 这里强调的是所有内容都可以使用类型信息,以便IDE在尝试跨应用程序使用配置时自动完成。 因为您不想硬编码您的机密凭据,所以可以通过环境提供它们。
因此,对于上述配置,环境可能如下所示: 那些在环境中找不到的值将从ini文件中读取,该文件可能如下所示: 注意在此之后, 第一次使用配置值时,将读取这些值。默认情况下,这是惰性求值,因此如果不需要,不会读取所有内容。 首次使用后,它们会被缓存在内存中,以便在再次使用配置值时不再有I/O。 对于Fail Fast行为,以及在应用程序中途读取配置值时停止意外延迟(例如,您的配置可能通过网络),该选项可用于在开始时读取所有配置值。只要打电话 如果找不到任何必需的配置值,这将引发异常,并且还将在下次使用时将所有读取的配置值保留在内存中。如果不使用 使用组键来表示配置的"子配置"。按照上面的说明设置"sub configs",然后创建一个父配置,将它们组合到一个位置。 第一次访问 让我们看看这个: host1和host2都是合法的配置键定义。 在本例中,我们有三种铸造方法: 配置源是您的main 在实例化配置后,将配置源提供给配置,但在之前,尝试从中读取任何数据: 或者您可以直接在构造函数中提供源,如下所示: 下面的做法是错误的,但是如果由于某种原因,您在读取配置源之后添加了其他配置源,或者由于某种原因需要刷新配置,则需要清除任何缓存值,以便强制重新读取配置。您可以通过 这只是从环境变量中读取配置。 它只需要一个可选的输入参数,一个前缀。这有助于避免环境变量中的名称冲突。 这将使用python内置的configparser从ini文件中读取。有关文件结构的详细信息,请阅读 它从字符串而不是文件中读取数据 最基本的源代码,完全在内存中,在编写测试时也很有用。它不区分大小写。 它需要数据类型 这是另一种提供默认值的方法,而不是在定义 提供了一个抽象基类configsource。您应该扩展它并实现方法 例如,这里概述了如何实现从json文件读取配置的源代码。使用 为了保持 以下列出: 欢迎提出新功能和请求。减贫战略必须包括测试。这是用Python3.7开发的,但Travis测试也用V3.6运行。 带着掩护跑 如果没有,您需要 以下是关于将包发布到pypi的好教程。pip安装类型配置
基本用法
# my_app/config.pyfromtypedconfigimportConfig,key,sectionfromtypedconfig.sourceimportEnvironmentConfigSource@section('database')classAppConfig(Config):host=key(cast=str)port=key(cast=int)timeout=key(cast=float)config=AppConfig()config.add_source(EnvironmentConfigSource())config.read()
# my_app/main.pyfrommy_app.configimportconfigprint(config.host)
工作原理
[database]host=127.0.0.1port=2000[algorithm]max_value=10min_value=20
configsource
s,从中可以读取应用程序的配置。例如,您可以提供一个environmentconfigsource
和两个inifileconfigsource在返回到第二个ini文件(可能是所有用户共享的默认配置)之前。如果仍然找不到参数,并且该参数是必需的参数,则会引发错误。
多个数据源
fromtypedconfigimportConfig,key,section,group_keyfromtypedconfig.sourceimportEnvironmentConfigSource,IniFileConfigSource@section('database')classDatabaseConfig(Config):host=key(cast=str)port=key(cast=int)username=key(cast=str)password=key(cast=str)config=DatabaseConfig()config.add_source(EnvironmentConfigSource(prefix="EXAMPLE"))config.add_source(IniFileConfigSource("config.cfg"))# OR provide sources directly to the constructorconfig=DatabaseConfig(sources=[EnvironmentConfigSource(prefix="EXAMPLE"),IniFileConfigSource("config.cfg")])
exportEXAMPLE_DATABASE_USERNAME=my_username
exportEXAMPLE_DATABASE_PASSWORD=my_very_secret_password
exportEXAMPLE_DATABASE_PORT=2001
[database]HOST=db1.mydomain.comPORT=2000
config.port
将等于2001
因为环境中的值优先于ini文件中的值。缓存
config.read()
read
则只有在首次尝试使用有问题的配置键时才会出现异常。分层配置
fromtypedconfigimportConfig,key,section,group_keyfromtypedconfig.sourceimportEnvironmentConfigSource,IniFileConfigSource@section('database')classDatabaseConfig(Config):host=key(cast=str)port=key(cast=int)@section('algorithm')classAlgorithmConfig(Config):max_value=key(cast=float)min_value=key(cast=float)classParentConfig(Config):database=group_key(DatabaseConfig)algorithm=group_key(AlgorithmConfig)description=key(cast=str,section_name="general")config=ParentConfig()config.add_source(EnvironmentConfigSource(prefix="EXAMPLE"))config.add_source(IniFileConfigSource("config.cfg"))config.read()
config.database
或config.algorithm
时(在上述情况下,当调用read()
时),将实例化一个实例。请注意,它是类定义,而不是类的实例,传递给组键
函数。自定义节/键名称、可选参数、默认值
fromtypedconfigimportConfig,key,section@section('database')classAppConfig(Config):host1=key()host2=key(section_name='database',key_name='HOST2',required=True,cast=str,default=None)
节名称
-配置源中应该从中读取此参数的节的名称。这可以按键提供,但如果省略了,则使用@section
装饰程序提供的节名称。如果所有键都提供一个节名,则不需要类装饰器。如果同时提供了section\u name
和decorator,则优先使用section\u name
参数。key_name
-从中读取此参数的配置源中的此密钥的名称。如果没有提供,某些魔术会使用对象属性名作为密钥名。必需
-默认为true。如果为false,并且找不到配置值,则不会抛出错误,并且将使用默认值(如果提供)。如果未提供默认值,则将使用none
。cast
-可能是最重要的输入选项。如果需要自动完成键入支持,则必须指定此项。它只是一个函数,它接受一个字符串作为输入并返回一个已解析的值。有关更多信息,请参见"铸造"部分。如果未提供,则该值将保持为字符串。默认值
-仅当必需值
为false时才适用。当required
为false时,如果找不到值,则使用此值。类型
fromtypedconfigimportConfig,key,sectionfromtypingimportListdefsplit_str(s:str)->List[str]:return[x.strip()forxins.split(",")]@section('database')classAppConfig(Config):host=key()port=key(cast=int)users=key(cast=split_str)zero_based_index=key(cast=lambdax:int(x)-1)config=AppConfig(sources=[...])
str
,但您的ide不会知道,因此如果您想要类型提示,请使用cast=str
int
配置源
config
类知道从哪里获取数据的方式。它们是完全可扩展的,因此您可以从任何您喜欢的地方读取配置—从数据库、从s3、任何您可以为其编写代码的地方。# my_app/config.pyfromtypedconfigimportConfig,key,sectionfromtypedconfig.sourceimportEnvironmentConfigSource@section('database')classAppConfig(Config):host=key(cast=str)port=key(cast=int)timeout=key(cast=float)config=AppConfig()config.add_source(EnvironmentConfigSource())config.read()
0
# my_app/config.pyfromtypedconfigimportConfig,key,sectionfromtypedconfig.sourceimportEnvironmentConfigSource@section('database')classAppConfig(Config):host=key(cast=str)port=key(cast=int)timeout=key(cast=float)config=AppConfig()config.add_source(EnvironmentConfigSource())config.read()
1
# my_app/config.pyfromtypedconfigimportConfig,key,sectionfromtypedconfig.sourceimportEnvironmentConfigSource@section('database')classAppConfig(Config):host=key(cast=str)port=key(cast=int)timeout=key(cast=float)config=AppConfig()config.add_source(EnvironmentConfigSource())config.read()
2
提供的配置源
环境配置源
# my_app/config.pyfromtypedconfigimportConfig,key,sectionfromtypedconfig.sourceimportEnvironmentConfigSource@section('database')classAppConfig(Config):host=key(cast=str)port=key(cast=int)timeout=key(cast=float)config=AppConfig()config.add_source(EnvironmentConfigSource())config.read()
3
{prefix}{section}{key}
,例如export xyz_database\u port=2000
{section}{key}
,例如导出数据库端口=2000
在文件配置源中
configparser的文档。
# my_app/config.pyfromtypedconfigimportConfig,key,sectionfromtypedconfig.sourceimportEnvironmentConfigSource@section('database')classAppConfig(Config):host=key(cast=str)port=key(cast=int)timeout=key(cast=float)config=AppConfig()config.add_source(EnvironmentConfigSource())config.read()
4
编码
是文件的文本编码。configparser
如果未提供,则使用默认值。必须存在
-默认值true
。如果找不到文件,默认情况下将引发错误。设置必须存在
为假
允许文件不存在,在这种情况下,此源将只报告它找不到任何配置值,并且您的配置
类将继续查找下一个配置源
在字符串配置源中
# my_app/config.pyfromtypedconfigimportConfig,key,sectionfromtypedconfig.sourceimportEnvironmentConfigSource@section('database')classAppConfig(Config):host=key(cast=str)port=key(cast=int)timeout=key(cast=float)config=AppConfig()config.add_source(EnvironmentConfigSource())config.read()
5
dictconfigsource
# my_app/config.pyfromtypedconfigimportConfig,key,sectionfromtypedconfig.sourceimportEnvironmentConfigSource@section('database')classAppConfig(Config):host=key(cast=str)port=key(cast=int)timeout=key(cast=float)config=AppConfig()config.add_source(EnvironmentConfigSource())config.read()
6
dict[str,dict[str,str]
,即string\u value=d['section\u name']['key\u name']
。所有数据都应以字符串数据的形式提供,以便以与数据来自文件或其他地方时相同的方式对其进行分析。键时使用
默认值
选项。只需提供一个dictconfigsource
作为最低优先级的源,包含您的默认值即可。编写自己的
configsource
sget_config_value
,如下所示,该方法接受一个节名和键名,并返回一个str
config值,如果找不到该值,则返回none
。如果找不到该值,则不应出错;如果在其任何其他可用源中仍找不到该值,则稍后将引发错误。为了方便用户,请尝试使源代码不区分大小写。\u init\uu方法提供源获取数据所需的任何信息,如文件名、API详细信息等。您可以在
\u init\uuu
方法中执行健全性检查,如果有问题则抛出错误。# my_app/config.pyfromtypedconfigimportConfig,key,sectionfromtypedconfig.sourceimportEnvironmentConfigSource@section('database')classAppConfig(Config):host=key(cast=str)port=key(cast=int)timeout=key(cast=float)config=AppConfig()config.add_source(EnvironmentConfigSource())config.read()
7
其他配置源
键入的配置
不依赖,需要附加依赖项的配置源
位于单独的包中,这些包还将键入的配置
作为依赖项。 < /广告><正文>PIP安装名称
导入名称 说明
键入的配置aws源 键入配置源
使用 boto3
来配置源,例如从s3或dynamodb获取配置
贡献
开发设置
venv/scripts/activate
pip install-r requirements.txt
运行测试
pytest
pytest--cov
部署到pypi
pip安装绳线
。typedconfig/\u version.py中插入版本号
python setup.py sdist bdist_wheel
捆绳检查距离/*
tween upload--repository url https://test.pypi.org/legacy/dist/*
捆绳上传dist/*
推荐PyPI第三方库