Skip to content
Advertisement

Adding json value in yml in python changing the format to yml again

I have to fetch json data and paste it in one of the values in yml. But it is converting it to yml format.

{
  "meta": {
    "type": "db",
    "slug": "test",
    "expires": "0001-01-01T00:00:00Z",
    "created": "2016-05-11T22:00:29Z",
    "updated": "2021-11-29T23:36:37Z",
    "createdBy": "Anonymous"
  }
}

apiVersion: integreatly.org/v1alpha1
kind: GrafanaDashboard
metadata:
  name: testname
  labels:
    app: grafana
    type: dashboard
    folder: proj
spec:
  json: >
import json
import yaml

# Load files as dicts
with open("sample.json", "r") as f:
    j = json.load(f)
with open("sample.yaml", "r") as f:
    y = yaml.load(f, Loader=yaml.BaseLoader)
# Assign JSON "Slug" to YAML "name".
y['metadata']['name'] = j['meta']['slug']
y['spec']['json'] = j
print(y)

I want the output as below

apiVersion: integreatly.org/v1alpha1
kind: GrafanaDashboard
metadata:
  name: test
  labels:
    app: grafana
    type: dashboard
    folder: proj
spec:
  json: >
    "meta": {
    "type": "db",
    "slug": "test",
    "expires": "0001-01-01T00:00:00Z",
    "created": "2016-05-11T22:00:29Z",
    "updated": "2021-11-29T23:36:37Z",
    "createdBy": "Anonymous"
  }

but with the above script it is showing all the data in dictionary format format. I would like to replace the sampleyaml with the added changes.

Please help me.

Advertisement

Answer

What you have at the end of your YAML document, indicated by >, is called a folded scalar string (and in your input file it is empty). So you want to assign the contents of the JSON file as a string and not as a data structure, and use a more modern library than PyYAML that can easily output/preserve such strings out of the box.

Since you also parse the contents of the JSON file for the slug value, you should read in its contents once in a string and parse that:

import sys
from pathlib import Path
import json
import ruamel.yaml


file_in = Path('sample.yaml')
json_in = Path('sample.json')

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True

with json_in.open() as f:
    json_str = f.read()

j = json.loads(json_str)

y = yaml.load(file_in)
y['metadata']['name'] = j['meta']['slug']
# preserve the type folded scalar type
y['spec']['json'] = type(y['spec']['json'])(json_str)

yaml.dump(y, sys.stdout)

which gives:

apiVersion: integreatly.org/v1alpha1
kind: GrafanaDashboard
metadata:
  name: test
  labels:
    app: grafana
    type: dashboard
    folder: proj
spec:
  json: >
    {
      "meta": {
        "type": "db",
        "slug": "test",
        "expires": "0001-01-01T00:00:00Z",
        "created": "2016-05-11T22:00:29Z",
        "updated": "2021-11-29T23:36:37Z",
        "createdBy": "Anonymous"
      }
    }
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement