Skip to main content

An experimental Python binding of the Rust MiniJinja template engine.

Project description

MiniJinja for Python: a powerful template engine for Rust and Python

Build Status License Crates.io rustc 1.61.0 Documentation

minijinja-py is an experimental binding of MiniJinja to Python. It has somewhat limited functionality compared to the Rust version. These bindings use maturin and pyo3.

You might want to use MiniJinja instead of Jinja2 when the full feature set of Jinja2 is not required and you want to have the same rendering experience of a data set between Rust and Python.

With these bindings MiniJinja can render some Python objects and values that are passed to templates, but there are clear limitations with regards to what can be done.

To install MiniJinja for Python you can fetch the package from PyPI:

$ pip install minijinja

Basic API

The basic API is hidden behind the Environment object. It behaves almost entirely like in minijinja with some Python specific changes. For instance instead of env.set_debug(True) you use env.debug = True. Additionally instead of using add_template or attaching a source you either pass a dictionary of templates directly to the environment or a loader function.

from minijinja import Environment

env = Environment(templates={
    "template_name": "Template source"
})

To render a template you can use the render_template method:

result = env.render_template('template_name', var1="value 1", var2="value 2")
print(result)

Purpose

MiniJinja attempts a certain level of compatibility with Jinja2, but it does not try to achieve this at all costs. As a result you will notice that quite a few templates will refuse to render with MiniJinja despite the fact that they probably look quite innocent. It is however possible to write templates that render to the same results for both Jinja2 and MiniJinja. This raises the question why you might want to use MiniJinja.

The main benefit would be to achieve the exact same results in both Rust and Python. Additionally MiniJinja has a stronger sandbox than Jinja2 and might perform ever so slightly better in some situations. However you should be aware that due to the marshalling that needs to happen in either direction there is a certain amount of loss of information.

Dynamic Template Loading

MiniJinja's Python bindings inherit the underlying behavior of how MiniJinja loads templates. Templates are loaded on first use and then cached. The templates are loaded via a loader. To trigger a reload you can call env.reload() or alternatively set env.reload_before_render to True.

def my_loader(name):
    segments = []
    for segment in name.split("/"):
        if "\\" in segment or segment in (".", ".."):
            return None
        segments.append(segment)
    try:
        with open(os.path.join(TEMPLATES, *segments)) as f:
            return f.read()
    except (IOError, OSError):
        pass

env = Environment(loader=my_loader)
env.reload_before_render = True
print(env.render_template("index.html"))

Alternatively templates can manually be loaded and unloaded with env.add_template and env.remove_template.

Auto Escaping

The default behavior is to use auto escaping file files ending in .html. You can customize this behavior by overriding the auto_escape_callback:

env = Environment(auto_escape_callback=lambda x: x.endswith((".html", ".foo")))

MiniJinja uses markupsafe if it's available on the Python side. It will honor __html__.

Finalizers

Instead of custom formatters like in MiniJinja, you can define a finalizer instead which is similar to how it works in Jinja2. It's passed a value (or optional also the state as first argument when pass_state is used) and can return a new value. If the special NotImplemented value is returned, the original value is rendered without any modification:

from minijinja import Environment

def finalizer(value):
    if value is None:
	return ""
    return NotImplemented

env = Environment(finalizer=finalizer)
assert env.render_str("{{ none }}") == ""

State Access

Functions passed to the environment such as filters or global functions can optionally have the template state passed by using the pass_state parameter. This is similar to pass_context in Jinja2. It can be used to look at the name of the template or to look up variables in the context.

from minijinja import pass_state

@pass_state
def my_filter(state, value):
    return state.lookup("a_variable") + value

env.add_filter("add_a_variable", my_filter)

Runtime Behavior

MiniJinja uses it's own runtime model which is not matching the Python runtime model. As a result there are clear gaps in behavior between the two and only limited effort is made to bridge them. For instance you will be able to call some methods of types, but for instance builtins such as dicts and lists do not expose their methods on the MiniJinja side. This means that it's very intentional that if you pass a dictionary to MiniJinja, the Python .items() method is unavailable.

Here is what this means for some basic types:

  • Python dictionaries and lists (as well as other objects that behave as sequences) appear in the MiniJinja side as native lists. They do not expose any specific other behavior and when they move back to the Python side they will appear as basic lists. Specifically this means that a tuple (which does not exist in MiniJinja) when moving from Python to MiniJinja turns into a list and will remain a list when it moves back.
  • Python objects are represented in MiniJinja similarly to dicts, but they retain all their meaningful Python APIs. This means they stringify via __str__ and they allow the MiniJinja code to call their non-underscored methods. Note that there is no extra security layer in use at the moment so take care of what you pass there.
  • MiniJinja's python binding understand what __html__ is when it exists on a string subclass. This means that a markupsafe.Markup object will appear as safe string in MiniJinja. This information can also flow back to Python again.

Sponsor

If you like the project and find it useful you can become a sponsor.

License and Links

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

minijinja-1.0.16.tar.gz (190.3 kB view details)

Uploaded Source

Built Distributions

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

minijinja-1.0.16-cp38-abi3-win_amd64.whl (697.2 kB view details)

Uploaded CPython 3.8+Windows x86-64

minijinja-1.0.16-cp38-abi3-win32.whl (670.9 kB view details)

Uploaded CPython 3.8+Windows x86

minijinja-1.0.16-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (804.6 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

minijinja-1.0.16-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (761.9 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARMv7l

minijinja-1.0.16-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (771.8 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

minijinja-1.0.16-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl (879.6 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.5+ i686

minijinja-1.0.16-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (1.5 MB view details)

Uploaded CPython 3.8+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file minijinja-1.0.16.tar.gz.

File metadata

  • Download URL: minijinja-1.0.16.tar.gz
  • Upload date:
  • Size: 190.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.1

File hashes

Hashes for minijinja-1.0.16.tar.gz
Algorithm Hash digest
SHA256 57f6e98bc735794eb87648f251e68fbfd9cf50333f6a4053b398751483350826
MD5 179b650b241212fe052b94f9b6830e63
BLAKE2b-256 b69abcd2c658f8c81196e1c958be3a7fbcb2ae5f3a77afeddf5522c43839e062

See more details on using hashes here.

File details

Details for the file minijinja-1.0.16-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: minijinja-1.0.16-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 697.2 kB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.1

File hashes

Hashes for minijinja-1.0.16-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 0a41541c28fd7ce64b38ddc60974930f81c163440c348393bd5143debeb309b3
MD5 06bf9ece364f4715d55aff76853cb826
BLAKE2b-256 8a43e044bf6fa4c6f1e6e514ca25d48d8942f78d567f3cea7ea78fc36564388c

See more details on using hashes here.

File details

Details for the file minijinja-1.0.16-cp38-abi3-win32.whl.

File metadata

  • Download URL: minijinja-1.0.16-cp38-abi3-win32.whl
  • Upload date:
  • Size: 670.9 kB
  • Tags: CPython 3.8+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.1

File hashes

Hashes for minijinja-1.0.16-cp38-abi3-win32.whl
Algorithm Hash digest
SHA256 f7f0da6c0d2b78bce9aa0f2bbfebc0ece18cdf8dae9430b4001055b8eb77911c
MD5 db813cf6790c0c1985356456628cbb3b
BLAKE2b-256 4804dc4295268dd05499cef2307f9b9b2d5ab4effbe9c3236ad8c3abda1a21ca

See more details on using hashes here.

File details

Details for the file minijinja-1.0.16-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for minijinja-1.0.16-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 beeb7fd7552e351b071b1d01fa80600a332b364c83f0f4a5c96b96d74d162434
MD5 4d395e52c82862b3bf8cb2ca5df9061d
BLAKE2b-256 347351050688e7b1a4446e174a0bf3430dfc0f9b88dd9bc969c37c37f5e60c4f

See more details on using hashes here.

File details

Details for the file minijinja-1.0.16-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for minijinja-1.0.16-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 87c61c94c014c3a6d2ef83ee2f67229ee23b13b3586c8d4d3a7d090ba19f1b6c
MD5 9cc50f01e0371e460ed0b60fd7a3f36d
BLAKE2b-256 4a2d27af85b3da81085b35ef02f927db6b6729e08772d8b7baedb63a3569a160

See more details on using hashes here.

File details

Details for the file minijinja-1.0.16-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for minijinja-1.0.16-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f83ca4a37d73b57b87cee4d50f7ce2ade2d6c04fbede49faabc37f7244161bd6
MD5 15667a3e4d94a5b56abea386fbb1b41a
BLAKE2b-256 a07bce0c38b4b3e4ff5efc197632ee040e7427b5ea9d57c2336d035453b7a414

See more details on using hashes here.

File details

Details for the file minijinja-1.0.16-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl.

File metadata

File hashes

Hashes for minijinja-1.0.16-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm Hash digest
SHA256 38cc378dd256bd3766f1c83754c9a4407356b6d992defc725eab8a7c203e07b9
MD5 a05418eaa5f7c85dde1e07903da2fa9f
BLAKE2b-256 d5bb2fbe18975ecab6663128f9a45db89b3185319532d5f3c35eb1fd52916a7c

See more details on using hashes here.

File details

Details for the file minijinja-1.0.16-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for minijinja-1.0.16-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 b7c1640d23ad719da999ab434fd58e895125e067d310d512c9a45ec7e7f301dc
MD5 5a68e720bc388b1a17541a37bb9a3ac4
BLAKE2b-256 ce660e98b4d2903a4591e168b973ade3df7450566872b72bb13209f3d698455f

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