I need to do a roundtrip with some Kubernetes Resources to alter it in some way with Python (3.11). Now i have t following ConfigMap-Resource:
apiVersion: v1
kind: ConfigMap
metadata:
name: sample-map
data:
sample.json: |-
[
{
"name": "foo",
"description": "bar"
}
]
After loading it, altering it i want to dump it back, while preserving the former form. Unfortunately, i only get the following output:
apiVersion: v1
kind: ConfigMap
metadata:
name: sample-map
data:
sample.json: "[\n {\n "name": "foo",\n"description": "bar"\n}\n]"
I tried various things, but without any luck e.g with different representer combination as seen in https://github.com/yaml/pyyaml/issues/240 Does anyone have an idea how to do it? Thanks a lot!
Use yaml.add_representer
to indicate the function you want to use to render strings. (The particular representer used here is taken from Issue 240 as well.)
import yaml
def str_presenter(dumper, data):
"""configures yaml for dumping multiline strings
Ref: https://stackoverflow.com/questions/8640959/how-can-i-control-what-scalar-form-pyyaml-uses-for-my-data"""
if data.count('\n') > 0: # check for multiline string
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
return dumper.represent_scalar('tag:yaml.org,2002:str', data)
data = """apiVersion: v1
kind: ConfigMap
metadata:
name: sample-map
data:
sample.json: |-
[
{
"name": "foo",
"description": "bar"
}
]"""
d = yaml.load(data, yaml.Loader)
yaml.add_representer(str, str_presenter)
print(yaml.dump(d))
(Note, though, that this does not preserver the original order of the keys. I don't recall if that's possible, but I think it's outside the scope of this question.)
Output:
$ python3 test.py
apiVersion: v1
data:
sample.json: |-
[
{
"name": "foo",
"description": "bar"
}
]
kind: ConfigMap
metadata:
name: sample-map