【问题标题】:YAML-serialized data for multiple config files with Jinja2使用 Jinja2 的多个配置文件的 YAML 序列化数据
【发布时间】:2018-05-03 18:10:07
【问题描述】:

我已经能够将 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 脚本中添加它?我也不需要在控制台上设置配置文件,我可以简单地将它们的路径放入脚本中。

【问题讨论】:

    标签: python yaml jinja2 pyyaml


    【解决方案1】:

    由于您要处理多个模板,您需要使您的load_args 能够处理多个--template= 参数/选项。 我调整了您的 load_args 以返回一个带有列表值的字典,但是对允许的参数数量(多个模板、单个 YAML 文件)的检查很粗糙。

    为了处理您的命令行,您应该查看标准的arparse 模块,您可以在其中指出每个参数/选项可以多次出现。

    由于您要重用 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_ARGSprint_usageload_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的变位,没有“分裂”(或“分裂”)这样的东西,即“已经分裂”的东西,)

    【讨论】:

      猜你喜欢
      • 2013-06-25
      • 1970-01-01
      • 2020-06-05
      • 1970-01-01
      • 1970-01-01
      • 2021-05-28
      • 2021-06-03
      • 1970-01-01
      • 2018-03-27
      相关资源
      最近更新 更多