<p>I have a task. I need to write python code to generate a yaml file for kubernetes. So far I have been using pyyaml and it works fine. Here is my generated yaml file:</p>
<pre><code>apiVersion: v1
kind: ConfigMap
data:
  info: 
    name: hostname.com
    aio-max-nr: 262144
    cpu:
      cpuLogicalCores: 4
    memory:
      memTotal: 33567170560
    net.core.somaxconn: 1024
    ...
</code></pre>
<p>However, when I try to create this configMap the error is that info expects a string() but not a map. So I explored a bit and it seem the easiest way to resolve this is to add a pipe after info like this:</p>
<pre><code>apiVersion: v1
kind: ConfigMap
data:
  info: | # this will translate everything in data into a string but still keep the format in yaml file for readability
    name: hostname.com
    aio-max-nr: 262144
    cpu:
      cpuLogicalCores: 4
    memory:
      memTotal: 33567170560
    net.core.somaxconn: 1024
    ...
</code></pre>
<p>This way, my configmap is created successfully. My struggling is I dont know how to add that pipe bar from python code. Here I manually added it, but I want to automate this whole process.</p>
<p>part of the python code I wrote is, pretend data is a dict():</p>
<pre><code>content = dict()
content[&quot;apiVersion&quot;] = &quot;v1&quot;
content[&quot;kind&quot;] = &quot;ConfigMap&quot;
data = {...}
info = {&quot;info&quot;: data}
content[&quot;data&quot;] = info

# Get all contents ready. Now write into a yaml file
fileName = &quot;out.yaml&quot;
with open(fileName, 'w') as outfile:
    yaml.dump(content, outfile, default_flow_style=False)   
</code></pre>
<p>I searched online and found a lot of cases, but none of them fits my needs. Thanks in advance.</p>

<p>The pipe makes the contained values a string. That string is not processed by YAML, even if it contains data with YAML syntax. Consequently, you will need to give a string as value.</p>
<p>Since the string contains data in YAML syntax, you can create the string by processing the contained data with YAML in a previous step. To make PyYAML dump the scalar in literal block style (i.e. with <code>|</code>), you need a custom representer:</p>
<pre class="lang-py prettyprint-override"><code>import yaml, sys
from yaml.resolver import BaseResolver

class AsLiteral(str):
  pass

def represent_literal(dumper, data):
  return dumper.represent_scalar(BaseResolver.DEFAULT_SCALAR_TAG,
      data, style=&quot;|&quot;)

yaml.add_representer(AsLiteral, represent_literal)

info = {
  &quot;name&quot;: &quot;hostname.com&quot;,
  &quot;aio-max-nr&quot;: 262144,
  &quot;cpu&quot;: {
    &quot;cpuLogicalCores&quot;: 4
  }
}

info_str = AsLiteral(yaml.dump(info))

data = {
  &quot;apiVersion&quot;: &quot;v1&quot;,
  &quot;kind&quot;: &quot;ConfigMap&quot;,
  &quot;data&quot;: {
    &quot;info&quot;: info_str
  }
}

yaml.dump(data, sys.stdout)
</code></pre>
<p>By putting the rendered YAML data into the type <code>AsLiteral</code>, the registered custom representer will be called which will set the desired style to <code>|</code>.</p>
