Как я могу динамически генерировать файл конфигурации Hocon, используя pyhocon в Python 3?

Я хотел бы использовать автоматизацию для создания конфигурации hocon со сценариями Python 3. Я читал, что лайтбенд (https://github.com/lightbend/config) рекомендует pyhocon (https://github.com/chimpler/pyhocon).

У меня проблемы с выяснением того, как создать объект Hocon и записать данные в файл как hocon. Мне важно, чтобы синтаксис подстановки был в результате.

Например, я ожидаю, что вывод файла myconfig.conf будет выглядеть примерно так:

{
   Environment: "dev"
   JobName: ${Environment}"-hello-bob"
}

Итак, я предположил, что есть способ сделать что-то вроде этого:

config2 = ConfigFactory.parse_string("{}")
config2.put("Environment", "dev")
#Some type of object for references or special syntax for ${Environment}  
config2.put("JobName", "${Environment}")

Затем после создания заполненного объекта должен быть простой способ записи в файл или файлы:

filename = "myconfig.conf"
print("Write to disk as {}".format(filename))
with open(filename, "w") as fd:
    fd.write(config2.to_hocon_str)

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


person pitchblack408    schedule 19.12.2019    source источник


Ответы (2)


Итак, я решил посмотреть документацию для библиотеки JVM (Java/Scala) (https://github.com/lightbend/config). После прочтения документации был четкий раздел с примерами hocon (https://github.com/lightbend/config#examples-of-hocon). В этой документации они классифицировали 7 допустимых стилей hocon. Я называю эти стили, потому что если бы мне нужно было автоматизировать создание этих файлов, я бы выбрал один способ записи и придерживался его.

Все они действительны HOCON.

1. Начните с действительного JSON:

{
    "foo" : {
        "bar" : 10,
        "baz" : 12
    }
}

2. Удалите корневые брекеты:

"foo" : {
    "bar" : 10,
    "baz" : 12
}

3.Отбросьте цитаты:

foo : {
    bar : 10,
    baz : 12
}

4. Используйте = и опустите его перед {:

foo {
    bar = 10,
    baz = 12
}

5. Удалите запятые:

foo {
    bar = 10
    baz = 12
}

6. Используйте точечную нотацию для ключей без кавычек:

foo.bar=10
foo.baz=12

7. Поместите поля с точечной записью в одну строку:

foo.bar=10, foo.baz=12

Поскольку я буду использовать библиотеку pyhocon, мне нужно было искать решения для записи в библиотеке. Мне помог git chimpler (https://github.com/chimpler/pyhocon). Я обнаружил, что у них есть два стиля хокон, которые можно просто записать. Один из них — json, а другой — то, чего не было в списке, описанном выше Lightbend.

Стиль 1: чистый JSON, который можно записать двумя способами:

HOCONConverter.to_json

#Using HOCONConverter.to_json
confTree = ConfigFactory.parse_string("{}")
confTree.put("Environment","Dev")
confTree.put("Test","${Environment}")

filename = "./json_coverted.conf"
print("Write to disk as {}".format(filename))
with open(filename, "w") as fd:
    fd.write(HOCONConverter.to_json(confTree))

HOCONConverter.to_json Результат

{
    "Environment": "Dev",
    "Test": "${Environment}"
}

ИЛИ Использование json.dump

#Using json.dump
confTree = ConfigFactory.parse_string("{}")
confTree.put("Environment","Dev")
confTree.put("Test","${Environment}")
filename = "./json_dumped.conf"
print("Write to disk as {}".format(filename))
with open(filename, "w") as fd:
    fd.write(json.dumps(confTree,indent=4))

Использование результата json.dump

{
  "Environment": "Dev",
  "Test": "${Environment}"
}

Другой стиль Пихокона, не указанный магией света.

# HOCONConverter.to_hocon
confTree = ConfigFactory.parse_string("{}")
confTree.put("Environment","Dev")
confTree.put("Test","${Environment}")
filename = "./hocon_coverted.txt"
print("Write to disk as {}".format(filename))
with open(filename, "w") as fd:
    fd.write(HOCONConverter.to_hocon(confTree))

Другой стиль Пихокона, не указанный магией света.

Environment = "Dev"
Test = "${Environment}"

Итак, чтобы ответить на мой собственный вопрос, единственный надежный способ создать файл hocon conf динамически с использованием pyhocon в Python 3 — это использовать один из методов json (преобразователь или дампы). Но это все еще оставляет открытым вопрос. Вопрос в том, сможет ли чтение json в объект pyhocon ConfTree разыменовывать замены, когда они находятся в json?

Например, если я прочитал файл

{
    "Environment": "Dev",
    "Test": "${Environment}"
}

Будет ли объект ConfTree получать "Dev" в качестве значения для Test?
Нет, не будет. Вот мой тест

filename = "json_coverted.conf"
print("Reading file{}".format(filename))
conf = ConfigFactory.parse_file(filename)
key="Test"
value=conf.get(key)
print("Key:{} Value:{}".format(key,value))

Результат теста на экране

Reading filejson_coverted.conf
Key:Test Value:${Environment}

Итак, как же использовать пихокон с заменами?

person pitchblack408    schedule 20.12.2019

Вероятно, этот пример ответит на ваш вопрос

from pyhocon.converter import HOCONConverter
import pyhocon

string = '{"Environment": "Dev","Test": ${Environment}}'
factory = pyhocon.ConfigFactory.parse_string(string, resolve=True)
factory.put('somekey','somevalue')
print(HOCONConverter().to_hocon(factory))

возвращается

Environment = "Dev"
Test = "Dev"
somekey = "somevalue"
person Pozdniakov Filipp    schedule 05.10.2020