Chciałbym użyć automatyzacji do stworzenia konfiguracji hocon za pomocą skryptów Pythona 3. Czytałem, że lightbend (https://github.com/lightbend/config) poleca pyhocon (https://github.com/chimpler/pyhocon).
Mam problemy ze zrozumieniem, jak utworzyć obiekt Hocon i zapisać dane do pliku jako hocon. Ważne jest dla mnie, aby w wyniku otrzymano składnię podstawienia.
Na przykład oczekuję, że wynik pliku myconfig.conf będzie wyglądał mniej więcej tak:
{
Environment: "dev"
JobName: ${Environment}"-hello-bob"
}
Więc założyłem, że istnieje sposób na zrobienie czegoś takiego:
config2 = ConfigFactory.parse_string("{}")
config2.put("Environment", "dev")
#Some type of object for references or special syntax for ${Environment}
config2.put("JobName", "${Environment}")
Następnie po utworzeniu wypchanego obiektu powinien być prosty sposób na zapisanie do pliku lub plików:
filename = "myconfig.conf"
print("Write to disk as {}".format(filename))
with open(filename, "w") as fd:
fd.write(config2.to_hocon_str)
Czy ktoś wymyślił sposób, aby to zrobić? Wydaje się dziwne, że biblioteka może być używana tylko do odczytu danych.
2 odpowiedzi
Postanowiłem więc zajrzeć do dokumentacji biblioteki JVM (Java/Scala) (https://github.com/lightbend /config). Po przeczytaniu dokumentacji pojawiła się przejrzysta sekcja dotycząca przykładów hoconów (https://github. com/lightbend/config#examples-of-hocon). W tej dokumentacji skategoryzowali 7 prawidłowych stylów hokonów. Nazywam te style, ponieważ gdybym miał zautomatyzować generowanie tych plików, wybrałbym jeden sposób na pisanie i trzymałby się go.
Wszystko to jest zgodne z HOCON.
1. Zacznij od prawidłowego JSON:
{
"foo" : {
"bar" : 10,
"baz" : 12
}
}
2. Upuść aparat ortodontyczny:
"foo" : {
"bar" : 10,
"baz" : 12
}
3. Upuść cytaty:
foo : {
bar : 10,
baz : 12
}
4.Użyj = i pomiń go przed {:
foo {
bar = 10,
baz = 12
}
5. Usuń przecinki:
foo {
bar = 10
baz = 12
}
6. Użyj notacji z kropkami dla kluczy niecytowanych:
foo.bar=10
foo.baz=12
7. Umieść pola z kropkami w jednym wierszu:
foo.bar=10, foo.baz=12
Ponieważ będę używał biblioteki pyhocon, musiałem poszukać rozwiązań zapisu w bibliotece. Znalazłem pomoc z gita chimplera (https://github.com/chimpler/pyhocon). Odkryłem, że mają dwa style hokonów, które można po prostu napisać. Jeden to json, a drugi to coś, czego nie było na liście, która została opisana powyżej przez lightbend.
Styl 1: czysty JSON, który można zapisać na dwa sposoby:
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 Wynik
{
"Environment": "Dev",
"Test": "${Environment}"
}
LUB Korzystanie z 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))
Korzystanie z json.dump Wynik
{
"Environment": "Dev",
"Test": "${Environment}"
}
Inny styl Pyhocon, nie wymieniony przez lightbend
# 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))
Inny styl Pyhocon, nie wymieniony przez Lightbend Result
Environment = "Dev"
Test = "${Environment}"
Tak więc, aby odpowiedzieć na moje własne pytanie, jedynym niezawodnym sposobem dynamicznego generowania pliku hocon conf przy użyciu pyhocon w Pythonie 3 jest użycie jednej z metod json (konwertera lub zrzutów). Ale to wciąż pozostawia otwarte pytanie. Pytanie brzmi, czy odczytywanie json do obiektu ConfTree pyhocon będzie w stanie wyłuskać podstawienia, gdy są one w json?
Na przykład, jeśli przeczytam plik
{
"Environment": "Dev",
"Test": "${Environment}"
}
Czy obiekt ConfTree otrzyma „Dev” jako wartość dla Testu?
Nie, nie będzie. Oto mój 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))
Wynik testu na ekranie
Reading filejson_coverted.conf
Key:Test Value:${Environment}
Jak więc używać pyhocon z podstawieniami?
Po prostu nie może stąd, nie będę używał żadnej biblioteki do pisania confs. Musi to być proces ręczny, jeśli chcę użyć podstawień. Tak więc używam tej biblioteki tylko do czytania confs.
Prawdopodobnie ten przykład odpowie na Twoje pytanie
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))
Zwroty
Environment = "Dev"
Test = "Dev"
somekey = "somevalue"
Podobne pytania
Nowe pytania
python
Python to wielozadaniowy, wielozadaniowy język programowania dynamicznie typowany. Został zaprojektowany tak, aby był szybki do nauczenia się, zrozumienia i użycia oraz wymuszania czystej i jednolitej składni. Należy pamiętać, że Python 2 oficjalnie nie jest obsługiwany od 01-01-2020. Mimo to, w przypadku pytań Pythona specyficznych dla wersji, dodaj znacznik [python-2.7] lub [python-3.x]. Korzystając z wariantu Pythona (np. Jython, PyPy) lub biblioteki (np. Pandas i NumPy), należy umieścić go w tagach.