Динамически изменять yaml и сохранять все форматирование и комментарии — python

У меня есть такой файл config.yml:

# CONFIGURATION FILE
# COMMENT 1 blah 
# COMMENT 2 blah blah
# COMMENT 3 blah blah blah

NAME: Fruits

# CONFIGURATION FILE
# COMMENT 4 blah 
# COMMENT 5 blah blah
# COMMENT 6 blah blah blah

fruit_list:
  - "apple-01:9100"

Я хочу динамически изменять файл fruit_list. Я хочу добавить введенные пользователем данные из веб-формы фляги. Ниже приведен код, который я пробовал, я могу изменить и добавить только одну строку с этим кодом.

import ruamel.yaml
from ruamel.yaml import YAML

yaml = YAML()
conf_file = pathlib.Path('configs/config.yml')
conf_key = yaml.load(conf_file)
conf_key['Fruits'] = form.bsa.data
conf_key['fruit_list'] = form.fqdn.data + ':9100'
yaml.dump(conf_key, conf_file)

Приведенный выше код позволяет мне изменить/добавить только одну строку в fruit_list. Кроме того, он не сохраняет форматирование. Комментарии сохраняются, но пробелы беспорядочны и продолжают увеличиваться. См. вывод ниже:

# CONFIGURATION FILE

# COMMENT 1 blah 

# COMMENT 2 blah blah

# COMMENT 3 blah blah blah

NAME: Fruits

# CONFIGURATION FILE
# COMMENT 4 blah 
# COMMENT 5 blah blah
# COMMENT 6 blah blah blah

fruit_list: apple-01:9100

Желаемый результат будет следующим:

# CONFIGURATION FILE
# COMMENT 1 blah 
# COMMENT 2 blah blah
# COMMENT 3 blah blah blah

NAME: Fruits

# CONFIGURATION FILE
# COMMENT 4 blah 
# COMMENT 5 blah blah
# COMMENT 6 blah blah blah

fruit_list:
  - "apple-01:9100"
  - "orange-01:9100"
  - "pear-01:9100"
  - "grape-01:9100"

Я также хотел бы, чтобы добавление в fruit_list было динамическим в зависимости от того, сколько fruits ввел пользователь.


person Bharath    schedule 07.02.2020    source источник


Ответы (1)


Я думаю, что что-то не так с вашим вводом YAML (помимо использования расширения .yml, с 2006 года рекомендуемое расширение для файлов YAML было .yaml ). Я подозреваю, что в вашем вводе есть какие-то дополнительные возвраты кариеса или что-то еще, поэтому убедитесь, что вы проверили это, выполнив print(repr(conf_key)) и, возможно,

conf_key = conf_key.replace('\r', '\n')

или подобное, чтобы очистить вещи. Как показано ниже, я не могу воспроизвести получение дополнительных новых строк

Что касается добавления к последовательности YAML, если вы хотите, вы должны добавить соответствующий список в Python. И не назначать новое значение, не входящее в список, ключу родительского словаря:

import sys
import pathlib
import ruamel.yaml

conf_file = pathlib.Path('config.yaml')


conf_file.write_text("""\
# CONFIGURATION FILE
# COMMENT 1 blah 
# COMMENT 2 blah blah
# COMMENT 3 blah blah blah

NAME: Fruits

# CONFIGURATION FILE
# COMMENT 4 blah 
# COMMENT 5 blah blah
# COMMENT 6 blah blah blah

fruit_list:
  - "apple-01:9100"
""")

yaml = ruamel.yaml.YAML()
yaml.indent(sequence=4, offset=2)
conf_key = yaml.load(conf_file)
conf_key['Fruits'] = 'some_data'
conf_key['fruit_list'].append('orange-01:9100')
conf_key['fruit_list'].extend(['pear-01:9100', 'grape-01:9100'])
yaml.dump(conf_key, sys.stdout)

который дает:

# CONFIGURATION FILE
# COMMENT 1 blah 
# COMMENT 2 blah blah
# COMMENT 3 blah blah blah

NAME: Fruits

# CONFIGURATION FILE
# COMMENT 4 blah 
# COMMENT 5 blah blah
# COMMENT 6 blah blah blah

fruit_list:
  - apple-01:9100
  - orange-01:9100
  - pear-01:9100
  - grape-01:9100
Fruits: some_data

С вашим кодом вы также должны ожидать дополнительный ключ Fruits в сопоставлении корневого уровня.

Как правило, при тестировании лучше писать в другой файл или стандартный вывод: нет необходимости восстанавливать исходный ввод.

person Anthon    schedule 08.02.2020
comment
Спасибо @Anthon. Я постараюсь вернуться. - person Bharath; 10.02.2020