Skip to main content

Latest Version Supported Python Versions Pre-Commit enabled MyPy checked Code Coverage

Template loader for embedded python runtimes, e.g., PyOxidizer or PyInstaller.

The main problem with the current PackageLoader is that it can only load templates from packages which are installed and materialized as directories. However, when using a bundler from above, the resources, i.e., templates, are embedded into the executable. Thus, the PackageLoader will throw the following exception: The package was not installed in a way that PackageLoader understands.

The EmbeddedPackageLoader from this package fixes this problem and required minimal changes. Under the hood, we utilize the Loader and ResourceReader implementation of the package provided through importlib. Thereby, the EmbeddedPackageLoader will work when the package is normally installed as directory and in an embedded environment.

How to use

Two changes are necessary. First, change PackageLoader to EmbeddedPackageLoader:

from jinja2 import Environment, PackageLoader
from jinja2_embedded import EmbeddedPackageLoader

# before
env = Environment(
    loader=PackageLoader('my_package', 'templates'),
    autoescape=True,
    ...
)

# after
env = Environment(
    loader=EmbeddedPackageLoader('my_package.templates'),
    autoescape=True, # default False, but FastAPI uses True as default
    extensions=[],
)

# with FastAPI
from fastapi.templating import Jinja2Templates
templates = Jinja2Templates(env=env)

Second, declare the templates directory as a module by adding a __init__.py file:

my_package
├── __init__.py
├── main.py
└── templates
    ├── __init__.py # required
    ├── bar
    │   ├── __init__.py # not required
    │   └── test.html.jinja2
    ├── foo
    │   └── test.html
    └── test.html

The subdirectories inside the templates directory can be declared as modules (here my_package.templates.bar), but this is not required. The EmbeddedPackageLoader works with either or mixed configuration.

How it works

The EmbeddedPackageLoader will first try to locate the template with the ResourceReader from my_package.templates. From our example above, the ResourceReader is able to see:

>>> from importlib.util import find_spec
>>> package = 'my_package.templates'
>>> loader = find_spec(package).loader
>>> resource_reader = loader.get_resource_reader(package)
>>> contents = resource_reader.contents()
>>> print(list(contents))
['foo/test.html', 'test.html']

So we can use the provided resource_reader to read either of those files:

>>> with resource_reader.open_resource('foo/test.html') as file:
...    content = file.read()
>>> print(content.decode('utf-8'))
FOO

Since, bar is declared as module (directory contains a __init__.py file), we need to use the ResourceReader of the respective module:

>>> resource_reader = loader.get_resource_reader('my_package.templates.bar')
>>> contents = resource_reader.contents()
>>> print(list(contents))
['test.html.jinja2']

The EmbeddedPackageLoader will first try to find the resource in the ResourceReader of the main package and then fallback to the ResourceReader of the submodule (if it is declared as such).

Development

Install uv, then run uv sync --all-extras. This creates a venv with all necessary dependencies. Run pytest to run all tests.

To run the tests in a embedded Python version created with PyOxidizer, run pyoxidizer run in the root directory. After the executable has been build, the tests will run automatically.

This repository used ruff to enforce style standards. The formatting is automatically done for you via pre-commit. Install pre-commit with pre-commit install.

Metadata

Release files for jinja2-embedded 0.1.5

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-embedded 0.1.5
File Size Uploaded
jinja2_embedded-0.1.5.tar.gz 82.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jinja2-embedded 0.1.5
File Interpreter ABI Platform
jinja2_embedded-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 88.1 kB

Release files / jinja2_embedded-0.1.5.tar.gz

Download URL jinja2_embedded-0.1.5.tar.gz
Size 82.1 kB
Tags Source
SHA-256 checksum
How to use checksums
18e23a70da1e8f857b6e1288682eadb69c34bb038c98cdfcde5f0577950f4786
BLAKE2b-256 checksum
How to use checksums
bf899546c2e790fda4eedfa2adea6615b64f36cdb90c5aa513085f0f88fdaaa8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 27, 2026.

Transparency log

Release files / jinja2_embedded-0.1.5-py3-none-any.whl

Download URL jinja2_embedded-0.1.5-py3-none-any.whl
Size 6.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d234d1158614aa68de187a351f66d644bebf507ec80205bf9f09dcf7886dce48
BLAKE2b-256 checksum
How to use checksums
50c3367123d127d1e5ec80465d9cbb12e11f1a8d5db4cad94465621772b85373
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

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