Skip to content

copier-org/jinja2-copier-extension

Repository files navigation

Copier's built-in Jinja2 Extension

Tests Python versions PyPI Formatter & Linter: Ruff Type-checker: mypy

Copier's built-in Jinja2 extension, inspired by Ansible, outsourced for you.

Installation

  • With pip:

    pip install jinja2-copier-extension
  • With uv:

    uv add jinja2-copier-extension
  • With poetry:

    poetry add jinja2-copier-extension
  • With pdm:

    pdm add jinja2-copier-extension
  • With pipx (injected into the pipx-managed virtual env of a package):

    pipx inject PACKAGE jinja2-copier-extension
  • With uvx (injected into the uvx-managed virtual env of a package):

    uvx --with jinja2-copier-extension PACKAGE

Usage

Register the extension in your Jinja2 environment to use the provided filters:

from jinja2 import Environment

env = Environment(extensions=["jinja2_copier_extension.CopierExtension"])

# Example:
template = env.from_string("The current time is {{ '%H:%M' | strftime }}")
result = template.render()
print(result)

Filters

The extension provides the following Jinja2 filters:

Base64

b64decode(value: str, encoding: str = "utf-8") → str

Decode a Base64 encoded string.

Example:

Template
{{ 'aGVsbG8gd29ybGQ=' | b64decode }}
Output
"hello world"

b64encode(value: str, encoding: str = "utf-8") → str

Encode a Base64 encoded string.

Example:

Template
{{ 'hello world' | b64encode }}
Output
"YSBzdHJpbmc="

Date/Time

strftime(format: str, second: float | None = None) → str

Convert a Unix timestamp to a date/time string according to a date/time format.

Example:

Template
{{ '%H:%M:%S' | strftime }}
Output
"02:03:04"

to_datetime(string: str, format: str = "%Y-%m-%d %H:%M:%S") → datetime

Convert a string containing date/time information to a datetime object.

Example:

Template
{{ '2016-08-14 20:00:12' | to_datetime }}
Output
datetime.datetime(2016, 8, 14, 20, 0, 12)

Hashing

hash(data: str, algorithm: str = "sha1") → str

Hash data using a configurable algorithm.

Example:

Template
{{ 'hello world' | hash }}
Output
"2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"

md5(data: str) → str

Hash data using the MD5 algorithm.

Example:

Template
{{ 'hello world' | md5 }}
Output
"5eb63bbbe01eeed093cb22bb8f5acdc3"

sha1(data: str) → str

Hash data using the SHA1 algorithm.

Example:

Template
{{ 'hello world' | sha1 }}
Output
"2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"

JSON

from_json(data: str, /, **kwargs: Any) → Any

Deserialize JSON data.

Example:

Template
{% filter from_json %}
{
  "name": "Jane",
  "age": 30
}
{% endfilter %}
Output
{"name": "Jane", "age": 30}

to_json(obj: Any, /, **kwargs: Any) → str

Serialize an object as JSON.

Example:

Template
{{ {'name': 'Jane', 'age': 30} | to_json }}
Output
{"name": "Jane", "age": 30}

to_nice_json(obj: Any, /, **kwargs: Any) → str

Serialize an object as JSON with nice formatting.

Example:

Template
{{ {'name': 'Jane', 'age': 30} | to_nice_json }}
Output
{
    "age": 30,
    "name": "Jane"
}

Filesystem

basename(path: str) → str

Get the final component of a path.

Example:

Template
{{ '/etc/asdf/foo.txt' | basename }}
Output
"foo.txt"

dirname(path: str) → str

Get the directory component of a path.

Example:

Template
{{ '/etc/asdf/foo.txt' | basename }}
Output
"/etc/asdf"

expanduser(path: str) → str

Expand a path with the ~ and ~user constructions.

Example:

Template
{{ '~/path/to/foo.txt' | expanduser }}
Output
"/home/<user>/path/to/foo.txt"    # Linux
"/Users/<user>/path/to/foo.txt"   # macOS
"C:/Users/<user>/path/to/foo.txt" # Windows

expandvars(path: str) → str

Expand a path with the shell variables of form $var and ${var}.

Example:

Template
{{ '$HOME/path/to/foo.txt' | expandvars }}
Output
"/home/<user>/path/to/foo.txt"    # Linux
"/Users/<user>/path/to/foo.txt"   # macOS
"C:/Users/<user>/path/to/foo.txt" # Windows

fileglob(pattern: str) → list[str]

Get all files in a filesystem subtree according to a glob pattern.

Example:

Filesystem
📁 .
├── 📄 a.txt
├── 📄 b.csv
└── 📁 c
    ├── 📄 d.txt
    └── 📄 e.json
Template
{{ '**/*.txt' | fileglob() | sort }}
Output
["a.txt", "c/d.txt"]

realpath(path: str) → str

Get the canonical form of a path.

Example:

Filesystem
📁 .
└── 📁 a
    ├── 📁 b
    │   └── 📄 foo.txt
    └── 📁 c
        └── 📄 bar.txt
Template
{{ 'a/c/../b/foo.txt' | realpath }}
Output
"<cwd>/a/b/foo.txt"

splitext(path: str) → tuple[str, str]

Split the extension of a path.

Example:

Template
{{ 'foo.txt' | splitext }}
Output
("foo", ".txt")

win_basename(path: str) → str

Get the final component of a Windows path.

Example:

Template
{{ 'C:/Temp/asdf/foo.txt' | win_basename }}
Output
"foo.txt"

win_dirname(path: str) → str

Get the directory component of a Windows path.

Example:

Template
{{ 'C:/Temp/asdf/foo.txt' | win_dirname }}
Output
"C:/Temp/asdf"

win_splitdrive(path: str) → tuple[str, str]

Split a Windows path into a drive and path.

Example:

Template
{{ 'C:/Temp/asdf/foo.txt' | win_splitdrive }}
Output
("C:", "/Temp/asdf/foo.txt")

Random

shuffle[T](seq: Sequence[T], seed: str | None = None) → list[T]

Shuffle a sequence of elements.

Example:

Template
{{ [1, 2, 3] | shuffle(seed=123) }}
Output
[2, 1, 3]

ans_random[T](stop: int | Sequence[T], start: int = 0, step: int = 0, seed: str | None = None) → int | T

Generate a random integer in a range or choose a random element from a sequence.

Example:

Template
{{ 100 | ans_random(seed='123') }}
Output
93

random_mac(prefix: str, seed: str | None = None) → str

Generate a random MAC address given a prefix.

Example:

Template
{{ '52:54' | random_mac(seed='123') }}
Output
"52:54:25:a4:fc:1f"

Regular expressions

regex_escape(pattern: str, re_type: Literal["python", "posix_basic"] = "python") → str

Escape special characters in a regex pattern string.

Example:

Template
{{ '^a.*b(.+)\c?$' | regex_escape }}
Output
r"\^a\.\*b\(\.\+\)\\c\?\$"

regex_findall(string: str, regex: str, multiline: bool = False, ignorecase: bool = False) → list[str] | list[tuple[str, ...]]

Extract non-overlapping regex matches using re.findall.

Example:

Template
{{ 'foo bar' | regex_findall('[a-z]+') }}
Output
["foo", "bar"]

regex_replace(string: str, pattern: str, replacement: str, ignorecase: bool = False, multiline: bool = False) → str

Substitute non-overlapping regex matches using re.sub.

Example:

Template
{{ 'copier' | regex_replace('^(.*)ier$', '\\1y') }}
Output
"copy"

regex_search(string: str, pattern: str, *args: str, ignorecase: bool = False, multiline: bool = False) → str | list[str] | None

Search a string for a regex match using re.search.

Example:

Template
{{ 'foo/bar' | regex_search('[a-z]+') }}
Output
"foo"

Shell

quote(value: str) → str

Shell-escape a string.

Example:

Template
echo {{ 'hello world' | quote }}
Output
"echo 'hello world'"

Types

bool(value: Any) → bool

Parse anything to boolean.

  1. Cast to number. Then: 0 → False; anything else → True.
  2. Find YAML booleans, YAML nulls or "none" in it and use it appropriately.
  3. Cast to boolean using standard Python bool(value).

Example:

Template
{{ 'yes' | bool }}
Output
True

type_debug(obj: object) → str

Get the type name of an object.

Example:

Template
{{ 123 | type_debug }}
Output
"int"

Utilities

ans_groupby[V](value: Iterable[V], attribute: str | int) → list[tuple[str | int, list[V]]]

Group a sequence of objects by an attribute.

Example:

Template
{{ [{'name': 'Jane', 'age': 30}, {'name': 'Alice', 'age': 30}, {'name': 'John', 'age': 20}] | ans_groupby('age') }}
Output
[(20, [{"name": "John", "age": 20}]), (30, [{"name": "Jane", "age": 30}, {"name": "Alice", "age": 30}])]

extract(key: Any, container: Any, morekeys: Any | Sequence[Any] | None = None) → Any | Undefined

Extract a value from a container.

Example:

Template
{{ 'k' | extract({'k': 'v'}) }}
Output
"v"

flatten(seq: Sequence[Any], levels: int | None = None) → list[Any]

Flatten nested sequences, filter out None values.

Example:

Template
{{ [1, [None, [2, None, [3]]]] | flatten }}
Output
[1, 2, 3]

mandatory[T](value: T, msg: str | None = None) → T

Require a value to be defined.

Example:

Template
{{ 'foo' | mandatory }}
Output
"foo"

ternary(condition: bool | None, true_val: Any, false_val: Any, none_val: Any = MISSING) → Any

Return a true/false/none value depending on a condition.

Example:

Template
{{ 'true' | ternary('t', 'f') }}
Output
"t"

UUID

to_uuid(name: str) → str

Generate a UUID v5 string from a name.

The UUID namespace is the DNS namespace https://github.com/copier-org/copier.

Example:

Template
{{ 'foo' | to_uuid }}
Output
"faf9357a-ee2a-58ed-94fd-cc8661984561"

YAML

from_yaml(value: str) → Any

Deserialize YAML data.

Example:

Template
{% filter from_yaml %}
name: Jane
age: 30
{% endfilter %}
Output
{"name": "Jane", "age": 30}

from_yaml_all(value: str) → Iterator[Any]

Deserialize multi-document YAML data.

Example:

Template
{% filter from_yaml | list %}
name: Jane
age: 30
---
name: John
age: 20
{% endfilter %}
Output
[{"name": "Jane", "age": 30}, {"name": "John", "age": 20}]

to_yaml(value: Any, /, **kwargs: Any) → str

Serialize data as YAML.

Example:

Template
{{ [{'name': 'Jane', 'age': 30}] | to_yaml }}
Output
- name: Jane
  age: 30'

to_nice_yaml(value: Any, /, **kwargs: Any) → str

Serialize data as YAML with nice formatting.

Example:

Template
{{ [{'name': 'Jane', 'age': 30}] | to_nice_yaml }}
Output
-   name: Jane
    age: 30

Contributions

Contributions are always welcome via filing issues or submitting pull requests. Please check the contribution guide for more details.

About

Copier's built-in Jinja2 extension, inspired by Ansible, outsourced for you

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages