支持include和python表达式的yaml格式的增强
metayaml的Python项目详细描述
mata yaml是yaml格式的几个增强功能,允许以下内容:
- 包括另一个yaml文件
- 使用python表达式和文件中的其他字段作为值
包含文件语法
要包含一个或多个文件,请使用“extend”键。例如:
base.yaml:
extend: - file1.yaml - file2.yaml name: base.yaml b: overridden_by_base new: new
file1.yaml:
a: a b: b c: c name: file1.yaml
file2.yaml:
a: aa b: bb d: d name: file2.yaml
文件处理的顺序如下表所示:
Step | Action | Intermediate dict |
---|---|---|
1 | Read base.yaml and extract extend key | ^{pr 4}$ |
2 | Read file1.yaml | ^{pr 5}$ |
3 | Read file2.yaml and merge/override values | ^{pr 6}$ |
4 | Read rest values from base.yaml and merge/override | ^{pr 7}$ |
表达式语法
metayaml支持任何python有效表达式。对于此表达式,应将其括在括号${}或$()中。 第一个括号用于急切的替代,$()用于laze。即$)中的表达式应用于 完全读取文件及其包含文件,但在文件读取期间${}。
可以使用字典语法或“破折号字典语法”从表达式访问其他值。
示例:
base.yaml
extend: - f1.yaml hour: ${60*60} # just simple python expression ${2+2}: four # expression can be in the key delay: ${hour*2} # delay is two hour or 7200 seconds loggers: metayaml: name: metayaml level: debug console: false backend: name: backend level: ${loggers.metayaml.level} console: ${loggers.metayaml.console} ext: ${loggers.metayaml} # copy whole dict from loggers.metayaml this key incorrect: ${delay} ${loggers.ext} # In this case string representation of objects will be concatenated
f1.yaml
run_interval: $(hour*5) # 5 hours. But 'hour' is not defined when this file is processed. # Therefore only $() brackets can be used here.
安装
meta-yaml在pypi中,因此可以使用以下命令直接安装:
$ pip install metayaml
或从比特桶:
$ git clone https://bitbucket.org/atagunov/metayaml $ cd metayaml $ python setup.py install
文件
使用量
from metayaml import read read(["config.yaml", "test.yaml"], {'join': os.path.join, # allows get right os specific path in yaml file 'env': os.environ} # allows use system environments from yaml file )
config.yaml
extend: - ${join(env["HOME"], ".metayaml", "localconfig.yaml")} # added reading local config from $HOME user_name: ${env["USER"]} email: ${user_name + "@example.com"} debug: false
test.yaml
debug: true
替代顺序
替换是按照文件中的值顺序进行的。即,以下示例将失败:
B: ${A+1} <--- A is not defined here AA: ${B} A: 1
但以下结果是可以的:
A: 1 B: ${A+1} AA: ${B}
更改合并行为
默认情况下,可以在dict中添加新键并替换列表。在某些情况下,必须移除 基本文件中的键或向列表中添加一些值。例如
base.yaml:
main: iso_3166: China: CN Honduras: HN Madagascar: MG country_codes: - CN - HN - MG country_codes_3: - CHN - HND - MDG
last.yaml:
extend: - base.yaml main: iso_3166: ${__del__}: China # key 'China' will be removed from the result Liberia: LR # add new key country_codes: - LR # after merge country_codes contains only one element. country_codes_3: ${__extend__}: - LBR # the result list is ["CHN", "HND", "MDG", "LBR"]
代码的结果:
d = read("last.yaml") print d { "main": { "iso_3166": { "Honduras": "HN", "Madagascar": "MG", "Liberia": "LR" }, "country_codes": [ "LR" ], "country_codes_3": [ "CHN", "HND", "MDG", "LBR" ] } }
复制方法
有一个方法“cp”可以复制dict/list并扩展:
cron: daily: min: 0 hour: 0 monthly: min: 0 hour: 0 day: 1 schedule: nighttask: ${cp(cron.daily, min=5)} # min will be replaced to 5 # min: 5 # hour: 0 daytask: ${cp(cron.daily, min=7, hour=13)} # min and hour are replaced # min: 7 # hour: 13 monthtask: ${cp(cron.monthly, day=2)} # min: 0 # hour: 0 # day: 2 deploy: subnets: - 1.1.1.1 - 2.2.2.2 base_elb: - 4.4.4.4 - 5.5.5.5 elb: ${cp(deploy.subnets, "3.3.3.3", *deploy.base_elb)} # - 1.1.1.1 # - 2.2.2.2 # - 3.3.3.3 # - 4.4.4.4 # - 5.5.5.5
继承方法
< >复制现有的DICT并更新一些字段:foo: bar: baz: 1 buz: 2 foobar: 3 foobar: [4, 5] bar: ${__inherit__}: foo.bar # bar will be replaces by content of for.bar buz: 33 # the result value of 'bar' will be # baz: 1 # buz: 33 # foobar: 3
许可证
Metayaml是在麻省理工学院的许可下发布的。