使用 Jinja2 的多个配置文件的 YAML 序列化数据
YAML-serialized data for multiple config files with Jinja2
我已经能够将 YAML 文档中的数据加载到配置文件中。
YAML:
id: 1
x: key1
y: key2
Python 脚本:
#Import necessary functions from Jinja2 module
from jinja2 import Environment, FileSystemLoader
#Import YAML module
import yaml
import sys
ALLOWED_ARGS = set(['template', 'data'])
def print_usage():
print('Wrong arguments: Usage: configplate.py --template=<template.jinja> --data=<data.yaml>')
def load_args(args):
out = {}
for arg in args:
if arg == __file__: #ignore the filename argument
continue
args_splited = arg.split('=')
out[args_splited[0].lstrip('-')] = args_splited[1]
if set(out.keys()) != set(ALLOWED_ARGS):
print_usage()
raise ValueError('Required argument not present.')
return out
def make(template, data):
#Load data from YAML into Python dictionary
config_data = yaml.load(open(data))
#Load Jinja2 templates
env = Environment(loader = FileSystemLoader('.'), trim_blocks=True, lstrip_blocks=True)
template = env.get_template(template)
#Render the template with data and print the output
return template.render(config_data)
if __name__ == '__main__':
if len(sys.argv) != 3:
print_usage()
else:
args = load_args(sys.argv)
res = make(args['template'], args['data'])
print(res)
配置文件:
<add name="Cloud" connectionString="{{ x }}" />
我现在面临的问题是我无法将同一个 YAML 加载到多个配置文件。我有第二个配置文件,我想同时填写。
配置文件 2:
<add name="Cloud" connectionString="{{ y }}" />
如何在同一个 python 脚本中添加它?我也不需要在控制台上设置配置文件,我可以简单地将它们的路径放入脚本中。
既然你想处理多个模板,你需要让你的load_args
能够处理多个--template=
arguments/options。
我将您的 load_args
改编为 return 一个包含列表值的字典,但是检查允许的参数数量(多个模板,单个 YAML 文件)是粗略的。
要处理您的命令行,您应该查看标准 arparse 模块,您可以在其中根据 argument/option 指示它可以出现多次。
由于您要重用 YAML 中的数据,因此只在调用之外加载一次 make()
。 没有理由不使用 safe_load()
而不是记录的不安全 load()
.
有:
#Import necessary functions from Jinja2 module
from jinja2 import Environment, FileSystemLoader
#Import YAML module
import yaml
import sys
ALLOWED_ARGS = set(['template', 'data'])
def print_usage():
print('Wrong arguments: Usage: configplate.py --template=<template.jinja> --data=<data.yaml>')
def load_args(args):
out = {}
for arg in args:
if arg == __file__: #ignore the filename argument
continue
args_split = arg.split('=', 1)
out.setdefault(args_split[0].lstrip('-'), []).append(args_split[1])
if (set(out.keys()) != set(ALLOWED_ARGS)) or len(out['data']) != 1:
print_usage()
raise ValueError('Required argument not present.')
return out
def make(template, data):
#Load Jinja2 templates
env = Environment(loader = FileSystemLoader('.'), trim_blocks=True, lstrip_blocks=True)
template = env.get_template(template)
#Render the template with data and print the output
return template.render(data)
sys.argv=[
__file__,
'--template=config1.jinja',
'--template=config2.jinja',
'--data=data.yaml'
]
if __name__ == '__main__':
if len(sys.argv) < 4:
print_usage()
else:
args = load_args(sys.argv)
# Load data from YAML into Python dictionary **once** and **safely**
config_data = yaml.safe_load(open(args['data'][0]))
for template_file in args['template']:
res = make(template_file, config_data)
print(res)
以及您获得的相应文件:
<add name="Cloud" connectionString="key1" />
<add name="Cloud" connectionString="key2" />
当您导入 argparse
时,您可以删除 AllOWED_ARGS
、print_usage
和 load_args
,然后执行以下操作:
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--template', action='append', nargs='+', required=True)
parser.add_argument('--data', required=True)
args = parser.parse_args()
# Load data from YAML into Python dictionary **once** and **safely**
config_data = yaml.safe_load(open(args.data))
for template_file in args.template:
res = make(template_file, config_data)
print(res)
(顺便说一句,查看 to split
的变位,没有 "splited"(或 "splitted")这样的东西,即 "has been split",)
我已经能够将 YAML 文档中的数据加载到配置文件中。
YAML:
id: 1
x: key1
y: key2
Python 脚本:
#Import necessary functions from Jinja2 module
from jinja2 import Environment, FileSystemLoader
#Import YAML module
import yaml
import sys
ALLOWED_ARGS = set(['template', 'data'])
def print_usage():
print('Wrong arguments: Usage: configplate.py --template=<template.jinja> --data=<data.yaml>')
def load_args(args):
out = {}
for arg in args:
if arg == __file__: #ignore the filename argument
continue
args_splited = arg.split('=')
out[args_splited[0].lstrip('-')] = args_splited[1]
if set(out.keys()) != set(ALLOWED_ARGS):
print_usage()
raise ValueError('Required argument not present.')
return out
def make(template, data):
#Load data from YAML into Python dictionary
config_data = yaml.load(open(data))
#Load Jinja2 templates
env = Environment(loader = FileSystemLoader('.'), trim_blocks=True, lstrip_blocks=True)
template = env.get_template(template)
#Render the template with data and print the output
return template.render(config_data)
if __name__ == '__main__':
if len(sys.argv) != 3:
print_usage()
else:
args = load_args(sys.argv)
res = make(args['template'], args['data'])
print(res)
配置文件:
<add name="Cloud" connectionString="{{ x }}" />
我现在面临的问题是我无法将同一个 YAML 加载到多个配置文件。我有第二个配置文件,我想同时填写。
配置文件 2:
<add name="Cloud" connectionString="{{ y }}" />
如何在同一个 python 脚本中添加它?我也不需要在控制台上设置配置文件,我可以简单地将它们的路径放入脚本中。
既然你想处理多个模板,你需要让你的load_args
能够处理多个--template=
arguments/options。
我将您的 load_args
改编为 return 一个包含列表值的字典,但是检查允许的参数数量(多个模板,单个 YAML 文件)是粗略的。
要处理您的命令行,您应该查看标准 arparse 模块,您可以在其中根据 argument/option 指示它可以出现多次。
由于您要重用 YAML 中的数据,因此只在调用之外加载一次 make()
。 没有理由不使用 safe_load()
而不是记录的不安全 load()
.
有:
#Import necessary functions from Jinja2 module
from jinja2 import Environment, FileSystemLoader
#Import YAML module
import yaml
import sys
ALLOWED_ARGS = set(['template', 'data'])
def print_usage():
print('Wrong arguments: Usage: configplate.py --template=<template.jinja> --data=<data.yaml>')
def load_args(args):
out = {}
for arg in args:
if arg == __file__: #ignore the filename argument
continue
args_split = arg.split('=', 1)
out.setdefault(args_split[0].lstrip('-'), []).append(args_split[1])
if (set(out.keys()) != set(ALLOWED_ARGS)) or len(out['data']) != 1:
print_usage()
raise ValueError('Required argument not present.')
return out
def make(template, data):
#Load Jinja2 templates
env = Environment(loader = FileSystemLoader('.'), trim_blocks=True, lstrip_blocks=True)
template = env.get_template(template)
#Render the template with data and print the output
return template.render(data)
sys.argv=[
__file__,
'--template=config1.jinja',
'--template=config2.jinja',
'--data=data.yaml'
]
if __name__ == '__main__':
if len(sys.argv) < 4:
print_usage()
else:
args = load_args(sys.argv)
# Load data from YAML into Python dictionary **once** and **safely**
config_data = yaml.safe_load(open(args['data'][0]))
for template_file in args['template']:
res = make(template_file, config_data)
print(res)
以及您获得的相应文件:
<add name="Cloud" connectionString="key1" />
<add name="Cloud" connectionString="key2" />
当您导入 argparse
时,您可以删除 AllOWED_ARGS
、print_usage
和 load_args
,然后执行以下操作:
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--template', action='append', nargs='+', required=True)
parser.add_argument('--data', required=True)
args = parser.parse_args()
# Load data from YAML into Python dictionary **once** and **safely**
config_data = yaml.safe_load(open(args.data))
for template_file in args.template:
res = make(template_file, config_data)
print(res)
(顺便说一句,查看 to split
的变位,没有 "splited"(或 "splitted")这样的东西,即 "has been split",)