Saya sudah dapat memuat data dari dokumen YAML ke dalam file konfigurasi.

YAML:

id: 1
x: key1
y: key2

Skrip 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)

File konfigurasi:

<add name="Cloud" connectionString="{{ x }}" />

Masalah yang saya hadapi sekarang adalah saya tidak dapat memuat YAML yang sama ke beberapa file konfigurasi. Saya memiliki file konfigurasi kedua yang ingin saya isi secara bersamaan.

File konfigurasi 2:

<add name="Cloud" connectionString="{{ y }}" />

Bagaimana saya bisa menambahkan ini dalam skrip python yang sama? Saya juga tidak perlu mengatur file konfigurasi di konsol, saya cukup memasukkan jalurnya ke dalam skrip.

1
João Amaro 3 Mei 2018, 21:10

1 menjawab

Jawaban Terbaik

Karena Anda ingin memproses beberapa template, Anda harus membuat load_args Anda mampu menangani beberapa argumen/opsi --template=. Saya mengadaptasi load_args Anda untuk mengembalikan dict dengan nilai yang berupa daftar, tetapi pemeriksaan jumlah argumen yang diizinkan (beberapa templat, file YAML tunggal) masih mentah.

Untuk memproses baris perintah Anda, Anda harus melihat modul arparse standar, di mana Anda dapat menunjukkan per argumen/opsi bahwa itu dapat terjadi beberapa kali.

Karena Anda akan menggunakan kembali data dari YAML, muat hanya sekali, di luar panggilan make(). Tidak ada alasan untuk tidak menggunakan safe_load() daripada yang didokumentasikan tidak aman load().

Dengan:

#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)

Dan file yang sesuai yang Anda dapatkan:

<add name="Cloud" connectionString="key1" />
<add name="Cloud" connectionString="key2" />

Saat Anda mengimpor argparse, Anda dapat menghapus AllOWED_ARGS, print_usage, dan load_args, lalu lakukan hal berikut:

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)

(BTW cari konjugasi to split, tidak ada yang namanya "terbelah" (atau "terbelah"), yaitu sesuatu yang "telah dipisah", )

1
Anthon 4 Mei 2018, 05:22