1

I'm trying to load a yaml file in jinja2 format and "evaluate"/"render" the template. Here, the example:

{% set name = "pyexcel-ezodf" %}
{% set version = "0.3.3" %}

package:
  name: {{ name|lower }}
  version: {{ version }}

I would like to be able to load the yaml file and said yaml['package']['version']=0.3.3

I have to try ruamel YAML but it doesn't evaluate the version only give me a package.

here the python code:

yaml = YAML(typ='jinja2')
yaml.allow_duplicate_keys = True
yaml.explicit_start = True
yaml_content = yaml.load(content)
print (yaml_content['package'])

ypriverol
  • 585
  • 2
  • 8
  • 28

3 Answers3

5

I am not sure what is the full example that you have but here is what i got to make it work. If i get this correctly you want to load a jinja file then get values through ruamel.yaml package

from ruamel.yaml import YAML
from jinja2 import Environment, FileSystemLoader

jinja = Environment(loader = FileSystemLoader('.'), trim_blocks=True, lstrip_blocks=True)
template = jinja.get_template('sample.yml')
yaml=YAML()
yaml.allow_duplicate_keys = True
yaml.explicit_start = True
yaml_content = yaml.load(template.render())
print (yaml_content['package'])
#sample.yml
{% set name = "pyexcel-ezodf" %}
{% set version = "0.3.3" %}

package:
  name: {{ name|lower }}
  version: {{ version }}

Result:

{'name': 'pyexcel-ezodf', 'version': '0.3.3'}

Regarding using typ='jinja2' is not supported by ruamel unless you have some custom settings as it gives the following:

NotImplementedError: typ "jinja2"not recognised (need to install plug-in?)

Mostafa Hussein
  • 11,063
  • 3
  • 36
  • 61
2

Not sure about ruamel.yaml, but you can easily do what you want with the jinja2 package and the pyyaml package:

from jinja2 import Environment, BaseLoader
import yaml

content = '''{% set name = "pyexcel-ezodf" %}
{% set version = "0.3.3" %}

package:
  name: {{ name|lower }}
  version: {{ version }}'''

yaml_content = yaml.safe_load(Environment(loader=BaseLoader()).from_string(content).render())
print(yaml_content['package']['version'])

This outputs:

0.3.3
blhsing
  • 91,368
  • 6
  • 71
  • 106
1

Loading jinja2 templates for YAML with the typ='jinja2' parameter passed to ruamel.yaml' YAML() instance is there in order to make valid YAML out of the template, so you can then modify the template as if it were valid YAML and write it back. It doesn't do any template rendering and doesn't claim to do so anywhere in the documentation.

What you need to do is first render the template using jinja2 and then load the value (for which you can use the fast yaml = YAML(typ='safe') option.

You can e.g. do something like:

from jinja2 import Environment
from ruamel.yaml import YAML

yaml = YAML(typ='safe')
yaml_content = yaml.load(Environment().from_string(content).render())
print(yaml_content['package'])
Anthon
  • 69,918
  • 32
  • 186
  • 246