Commit 9e3291b8 authored by André Anjos's avatar André Anjos 💬

Merge branch 'bob.extension.rc' into 'master'

Automatic injection of bob.extension.rc to jinja variables

Closes #31

See merge request !27
parents 43112b48 271eeb90
Pipeline #29308 passed with stages
in 20 minutes and 15 seconds
...@@ -189,6 +189,16 @@ configuration files and the aggregation would look like the following: ...@@ -189,6 +189,16 @@ configuration files and the aggregation would look like the following:
$ jgen variables.yaml template.py 'output-dir/{{ name }}-{{ version }}.py' run.sh 'output-dir/run.sh' $ jgen variables.yaml template.py 'output-dir/{{ name }}-{{ version }}.py' run.sh 'output-dir/run.sh'
Automatic injection of variables
--------------------------------
Sometimes you want to use variables that are user specific in your jinja templates; For
example, a temp directory that can be different for other users. To allow this, jgen
automatically injects ``bob.extension.rc`` (see :ref:`bob.extension.rc`) into your
variables. Then, you can access ``bob.extension.rc`` using something like:
``rc.variable_name`` to access variables from it in your jinja templates.
.. Place your references here: .. Place your references here:
.. _yaml: https://en.wikipedia.org/wiki/YAML .. _yaml: https://en.wikipedia.org/wiki/YAML
.. _jinja2: http://jinja.pocoo.org/docs/ .. _jinja2: http://jinja.pocoo.org/docs/
...@@ -3,24 +3,24 @@ ...@@ -3,24 +3,24 @@
'''Utilities for generating configurations for running experiments in batch''' '''Utilities for generating configurations for running experiments in batch'''
from bob.extension import rc
import collections import collections
import itertools import itertools
import yaml import yaml
import jinja2 import jinja2
class _OrderedDict(collections.OrderedDict): class dict(collections.OrderedDict):
"""An OrderedDict class that can be compared. """An OrderedDict class that can be compared.
This is to avoid sort errors (in Python 3) that happen in jinja internally. This is to avoid sort errors (in Python 3) that happen in jinja internally.
""" """
def __lt__(self, other): def __lt__(self, other):
return id(self) < id(other) return id(self) < id(other)
def _ordered_load(stream, Loader=yaml.Loader, def _ordered_load(stream, Loader=yaml.Loader,
object_pairs_hook=_OrderedDict): object_pairs_hook=dict):
'''Loads the contents of the YAML stream into :py:class:`collections.OrderedDict`'s '''Loads the contents of the YAML stream into :py:class:`collections.OrderedDict`'s
See: https://stackoverflow.com/questions/5121931/in-python-how-can-you-load-yaml-mappings-as-ordereddicts See: https://stackoverflow.com/questions/5121931/in-python-how-can-you-load-yaml-mappings-as-ordereddicts
...@@ -131,8 +131,8 @@ def expand(data): ...@@ -131,8 +131,8 @@ def expand(data):
# separates "unique" objects from the ones we have to iterate # separates "unique" objects from the ones we have to iterate
# pre-assemble return dictionary # pre-assemble return dictionary
iterables = _OrderedDict() iterables = dict()
unique = _OrderedDict() unique = dict()
for key, value in data.items(): for key, value in data.items():
if isinstance(value, list) and not key.startswith('_'): if isinstance(value, list) and not key.startswith('_'):
iterables[key] = value iterables[key] = value
...@@ -141,7 +141,7 @@ def expand(data): ...@@ -141,7 +141,7 @@ def expand(data):
# generates all possible combinations of iterables # generates all possible combinations of iterables
for values in itertools.product(*iterables.values()): for values in itertools.product(*iterables.values()):
retval = _OrderedDict(unique) retval = dict(unique)
keys = list(iterables.keys()) keys = list(iterables.keys())
retval.update(dict(zip(keys, values))) retval.update(dict(zip(keys, values)))
yield retval yield retval
...@@ -176,6 +176,7 @@ def generate(variables, template): ...@@ -176,6 +176,7 @@ def generate(variables, template):
env = jinja2.Environment(undefined=jinja2.StrictUndefined) env = jinja2.Environment(undefined=jinja2.StrictUndefined)
for c in expand(variables): for c in expand(variables):
c['rc'] = rc
yield env.from_string(template).render(c) yield env.from_string(template).render(c)
...@@ -206,5 +207,5 @@ def aggregate(variables, template): ...@@ -206,5 +207,5 @@ def aggregate(variables, template):
''' '''
env = jinja2.Environment(undefined=jinja2.StrictUndefined) env = jinja2.Environment(undefined=jinja2.StrictUndefined)
d = {'cfgset': list(expand(variables))} d = {'cfgset': list(expand(variables)), 'rc': rc}
return env.from_string(template).render(d) return env.from_string(template).render(d)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment