Skip to main content

Templating utilities

Project description

Sonotoria

Sonotoria is a library designed to provide features helping with templating and handling yaml files.

Jinja templating

Sonotoria provides some functions to make the use of jinja2 templating easier.

Note that all the functions presented in this section have the following optional arguments:

  • context: A dictionary used as context for the templating
  • filters: A dictionary of filters usable during the templating
  • tests: A dictionary of tests usable during the templating

Example:

// Context
{'key': 'value'} -> {{ test }} -> value

// Filters
{'twotimes': lambda v: v*2} -> {{ test | twotimes }} -> valuevalue

// Tests
{'big': lambda v: len(v) > 10} -> {{ test is big }} -> false

template_string

Shortcut for templating strings:

>>> from sonotoria import jinja
>>> jinja.template_string('Hello {{ hello }}!', context={'hello': 'world'})
Hello world!

template_file

Shortcut for templating files:

>>> from sonotoria import jinja
>>> jinja.template_file('myfile.j2', 'myfile')

template_folder

Shortcut for templating folders:

>>> from sonotoria import jinja
>>> jinja.template_folder('myfolder', 'mytemplatedfolder')

Note that the folder can contain an optional template configuration in a .template folder. Here you can add config file config.yaml.

The config file should like this:

---

default: # optional default values for the context
  myvar: myvalue

exclude: # an optional list of file path to ignore
  - .git

template: # use this part to provide information regarding the templating of the folders and files' names
  loop: # The loop section concerns files or folder that should be created using a list, one file/folder will be created for each element of the list
    - folder: myfolder # use file for a file, folder for a folder
      var: folders # the variable from the context that contains the list (required)
      item: folder # the name of the variable in the cotext used to hold the list elements' values
      # If the var name end with an 's', then the item is automatically defined with this name without the s
      # Therefore the 'item' definition here would have been added by default
      transform: my_{{ folder }}_looped # explicit how to transform the folder name, by default it will be named using the item value
      loop: # when looping a folder, you can also loop elements within the folder
        - file: myfile
          loop: # looping is obviously not available for a file, this will result in a configuration error
            ...
      filters: # You can choose filters to apply !on the list! before the templating (filters have the least priority)
        - myfilter
      when: # You can choose test to filter out !element of the list! before the templating
        - mytest
      excluded_values: # You can also exclude values directly (excluded_values have the highest priority)
        - myvalue
  rename: # The rename section is for renaming file or folder without looping (you can create create rename section in looped folder as well)
    - folder: myotherfolder
      var: myvar # When renaming, using var is a shortcut for "transform: {{ myvar }}"
      transform: my_{{ folders[0] | single }} # The transform is used to define how to rename the folder/file if var is also defined a warning will be logged and var will be ignored
      # As we can see in this transform, you can use filters and use typical operations such as the dot and the brackets
      loop: # Once again, when renaming a folder you can use a loop for the elements inside the folder
      rename: # ... or a rename
    - folder: dontchangeme # You can also not change a folder just to perform actions on the element inside
      loop:
        - file: changeme
          var: changes

You can also create a default.yaml file to hold default values outside of the configuration file. You can use both the default section and the default file. In that case, the default section (in the config file) will have the priority if a variable is defined twice. (And variables passed to the context of the function have obviously the highest priority). You can also create a vars.yaml to create variables after the context is loaded and use the context in it (using jinja syntax).

Finally you may also add a filters.py and/or a tests.py to add filters and tests that will be loading before templating. All they need is to respectively have a get_filters and get_tests function. Those function must return dictionaries with the filters/tests.

Loading Yaml

Sonotoria lets you load a yaml with variables using jinja2 syntax:

Examples

From a file

Given the file:

# test.yml
---

param: value
param2: {{ param }}

You can load the data:

>>> from sonotoria import jaml
>>> jaml.load('test.yml')
{'param': 'value', 'param2': 'value'}

From a string

You can also load a string directly:

>>> from sonotoria import jaml
>>> jaml.loads('---\nparam: value\nparam2: {{ param }}')
{'param': 'value', 'param2': 'value'}

Using context

Given the file:

# test.yml
---

param2: {{ param }}

You can load the data:

>>> from sonotoria import jaml
>>> jaml.load('test.yml', context={'param': 12})
{'param2': 12}

Using filters

Given the file:

# test.yml
---

param: value
param2: {{ param | doubled }}

You can load the data:

>>> from sonotoria import jaml
>>> jaml.load('test.yml', filters={'doubled': lambda s: s*2})
{'param': 'value', 'param2': 'valuevalue'}

Using tests

Given the file:

# test.yml
---

param: value
param2: {{ param is number }}

You can load the data:

>>> from sonotoria import jaml
>>> jaml.load('test.yml', tests={'number': lambda s: s.isdigit()})
{'param': 'value', 'param2': False}

Using objects

Given the file:

# test.yml
--- !stuff

param: value
param2: {{ param }}

You can load the data:

>>> from sonotoria import jaml
>>> class Stuff:
....    pass
>>> my_stuff = jaml.load('test.yml', types={'stuff': Stuff})
>>> my_stuff.param
value
>>> my_stuff.param2
value

You can add tests, filters and types:

Extractor

Sonotoria lets you extract data from a file using a jinja2 template.

Example

Given this input file:

That is a description

:param test: Looks like a test variable, huh
:param lol: This might be a fun variable
:param plop: Plop might just be the next best variable name
:return: Pretty much nothing, sadly

And this template file:

{{ description }}

{% for param, desc in params.items() %}
:param {{ param }}: {{ desc }}
{% endfor %}{% if return_given %}
:return: {{ return }}{% endif %}{% if rtype_given %}
:rtype: {{ rtype }}{% endif %}

You can extract data this way:

>>> import sonotoria
>>> sonotoria.extract('template.file', 'input.file')
{
    'description': 'That is a description',
    'params': {
        'test': 'Looks like a test variable, huh',
        'lol': 'This might be a fun variable',
        'plop': 'Plop might just be the next best variable name'
    },
    'return': 'Pretty much nothing, sadly',
    'rtype': None,
    'return_given': True,
    'rtype_given': False
}

Contributors

  • Emmanuel Pluot (aka. Neomyte)

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.3.7] - 2022-12-13

Fixed

  • Fix file included in other file name not being handled

[0.3.6] - 2022-11-24

Changed

  • Ensure folders are created when skipping a template

[0.3.5] - 2022-11-24

Changed

  • Files with wrong encoding skipped when templating a folder

[0.3.4] - 2022-10-22

Changed

  • Fix excluded like files being wrongly excluded

[0.3.3] - 2022-10-20

Changed

  • Handle python 3.8

[0.3.2] - 2021-04-25

Changed

  • Fixed template_file failing when no subfolders

[0.3.1] - 2021-04-21

Changed

  • Fixed template_folder failing when no config is found
  • Fixed template folder failing when folder name not templated
  • Fixed template folder not templating when no config found

[0.3.0] - 2021-04-15

Added

  • Local higher priority vars file for folder templating

Changed

  • yaml module renamed jaml (!BREAKING)

[0.2.1] - 2021-04-15

Changed

  • Fix python-benedict dependency

[0.2.0] - 2021-04-15

Added

  • Add doc to template_string
  • Add template_file to jinja
  • Add template_folder to jinja

Changed

  • Enhanced dumping
  • Fixed CI not updating packages

[0.1.9] - 2021-11-30

Changed

  • fixed dump (again :p)

[0.1.8] - 2021-11-30

Changed

  • fixed dump

[0.1.7] - 2021-11-30

Added

  • possibility to give a context to the yaml loader

[0.1.6] - 2021-10-24

Changed

  • removed print statements

[0.1.5] - 2021-10-24

Added

  • Add dumpers for yaml

Changed

  • fixed readme

[0.1.4] - 2021-10-24

Changed

  • fixed readme

[0.1.3] - 2021-10-24

Added

  • ordered
  • yaml.load
  • yaml.loads
  • constructed
  • extractor

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sonotoria-0.3.8.tar.gz (18.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sonotoria-0.3.8-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

Details for the file sonotoria-0.3.8.tar.gz.

File metadata

  • Download URL: sonotoria-0.3.8.tar.gz
  • Upload date:
  • Size: 18.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.1

File hashes

Hashes for sonotoria-0.3.8.tar.gz
Algorithm Hash digest
SHA256 20ed87d3f2056eee9988ab476d9fca0fa7618b5d317bb4110cbf8c405c9eec69
MD5 764655a772cbc734564dc12c02fe972d
BLAKE2b-256 55dbe6c9ee2cd6f980162a2c7c840c9bd3056dfbe5573dbb3aa06c3e814dbf05

See more details on using hashes here.

File details

Details for the file sonotoria-0.3.8-py3-none-any.whl.

File metadata

  • Download URL: sonotoria-0.3.8-py3-none-any.whl
  • Upload date:
  • Size: 19.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.1

File hashes

Hashes for sonotoria-0.3.8-py3-none-any.whl
Algorithm Hash digest
SHA256 1e478b16d0b094455569ef1072dcfab5ef7954cb5b90dfa72e01f746615bcf9f
MD5 9990e32a032eaaf14113f9712e37fa57
BLAKE2b-256 c62a9f9cd933b03d303407d5bf5d2b51e3d1bb28704fdc2fd91e25bb925abb2e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page