Skip to main content

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.

Metadata

Release files for jinja2-copier-extension 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jinja2-copier-extension 0.3.0
File Size Uploaded Provenance Actions
jinja2_copier_extension-0.3.0.tar.gz 13.7 kB With provenance Details for jinja2_copier_extension-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for jinja2-copier-extension 0.3.0
File Interpreter ABI Platform Actions
jinja2_copier_extension-0.3.0-py3-none-any.whl Python 3 none any Details for jinja2_copier_extension-0.3.0-py3-none-any.whl

Total release size: 32.1 kB

Release files / jinja2_copier_extension-0.3.0.tar.gz

Download URL jinja2_copier_extension-0.3.0.tar.gz
Size 13.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f4485f034bb4a2997aa1fbc95540400b427cda72429e6e712dc32de8376ac412
BLAKE2b-256 checksum
How to use checksums
86d0dae558e26490487861606364f1aebfafd53b3afebde4e3378e3a79bd3963
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Release files / jinja2_copier_extension-0.3.0-py3-none-any.whl

Download URL jinja2_copier_extension-0.3.0-py3-none-any.whl
Size 18.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6f56cff9b1f6c67d601f1ae40c9fe5352426173dd80c413f4529a6c13ae9874f
BLAKE2b-256 checksum
How to use checksums
12693b3daaf2988611057b72c6b9b392121c97c41359b6cf49b393d5d3877ff7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Security for jinja2-copier-extension 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for jinja2_copier_extension-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page