Jinja2-based template rendering engine with streaming support
Project description
Template
Jinja2-based template rendering engine with streaming support for Python.
Purpose
VCollab applications render data into various output formats — HTML reports, chart visualizations, CSV exports, styled tables. The rendering logic is always the same: load a template, pass data, produce output.
vcti-template provides a lightweight engine for this pattern with three
template sources (registry, filesystem, inline), streaming support for
large datasets, and a clean separation between template management and
domain-specific data preparation.
Installation
pip install vcti-template
# Specific version
pip install vcti-template@v1.1.0
From a GitHub release wheel:
pip install vcti-template>=1.1.1
Quick Start
Registry + Manager
from vcti.template import TemplateManager, TemplateRegistry
# Register named templates
registry = TemplateRegistry()
registry.register("greeting", "Hello, {{ name }}!")
registry.register("row", "<tr><td>{{ value }}</td></tr>")
# Create manager with the registry
tm = TemplateManager(registry=registry)
# Render a template
tm.render("greeting", name="World") # "Hello, World!"
Filesystem Templates
from vcti.template import TemplateManager
# Load templates from a directory
tm = TemplateManager(template_dirs=["./templates"])
# Render a file template
tm.render("report.html.jinja2", title="Q1 Report", data=summary)
Inline Rendering
from vcti.template import TemplateManager
tm = TemplateManager()
tm.render_string("{{ x }} + {{ y }} = {{ x + y }}", x=2, y=3)
# "2 + 3 = 5"
Streaming for Large Data
from vcti.template import TemplateManager, TemplateRegistry
registry = TemplateRegistry()
registry.register("header", "<table><tr><th>Name</th></tr>")
registry.register("row", "<tr><td>{{ name }}</td></tr>")
registry.register("footer", "</table>")
tm = TemplateManager(registry=registry)
# Render one chunk at a time — memory stays bounded
chunks = [{"name": row.name} for row in large_dataset.iter_rows()]
with open("output.html", "w") as f:
for fragment in tm.render_streaming(
"row",
chunks,
header_template="header",
header_context={},
footer_template="footer",
footer_context={},
):
f.write(fragment)
Strict Mode
from vcti.template import TemplateManager, TemplateRenderError
# Catch undefined variables instead of rendering empty strings
tm = TemplateManager(strict=True)
tm.render_string("Hello, {{ name }}!", name="World") # OK
try:
tm.render_string("Hello, {{ name }}!") # no name provided
except TemplateRenderError as exc:
print(exc) # 'name' is undefined
Custom Filters and Globals
from vcti.template import TemplateManager
tm = TemplateManager(
filters={"shout": lambda s: s.upper() + "!!!"},
globals={"app_name": "MyApp"},
)
tm.render_string("{{ app_name }}: {{ msg|shout }}", msg="hello")
# "MyApp: HELLO!!!"
Error Handling
All template-specific errors inherit from TemplateError:
from vcti.template import TemplateError, TemplateNotFoundError
try:
tm.render("missing_template")
except TemplateNotFoundError:
... # handle specifically
except TemplateError:
... # catch-all for any template issue
| Exception | When |
|---|---|
TemplateNotFoundError |
Name not in registry or filesystem |
TemplateSyntaxError |
Invalid Jinja2 syntax |
TemplateRenderError |
Render failure (e.g., undefined var in strict mode) |
API Summary
TemplateRegistry
| Method | Description |
|---|---|
register(name, template, *, replace=False) |
Register a template string |
get(name) |
Retrieve a template string |
has(name) |
Check if name is registered |
remove(name) |
Remove a template |
names() |
List all registered names |
templates |
Immutable view of all templates |
TemplateManager
| Method | Description |
|---|---|
render(name, **context) |
Render a named template |
render_string(template, **context) |
Render an inline template string |
render_streaming(name, chunks, ...) |
Yield rendered fragments per chunk |
| Constructor Option | Default | Description |
|---|---|---|
registry |
None |
Template registry instance |
template_dirs |
None |
Filesystem directories to search |
autoescape_extensions |
["html", "xml"] |
Extensions to autoescape |
strict |
False |
Raise on undefined variables |
filters |
None |
Custom Jinja2 filters |
globals |
None |
Variables available in all templates |
Resolution order for render(): registry → filesystem → error.
Dependencies
jinja2— template engine
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vcti_template-1.1.1.tar.gz.
File metadata
- Download URL: vcti_template-1.1.1.tar.gz
- Upload date:
- Size: 12.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e857a3c1be7334f4ef442f7e1628159cf2879cd2293d596769f75df9882be60
|
|
| MD5 |
3c0488a7a1037eeff0a1fe40dd520c80
|
|
| BLAKE2b-256 |
8f9e1ee6342d9082f158acf65d21556692fb82ca54d6e14a09593319df2fbbca
|
Provenance
The following attestation bundles were made for vcti_template-1.1.1.tar.gz:
Publisher:
publish.yml on vcollab/vcti-python-template
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vcti_template-1.1.1.tar.gz -
Subject digest:
1e857a3c1be7334f4ef442f7e1628159cf2879cd2293d596769f75df9882be60 - Sigstore transparency entry: 1155582693
- Sigstore integration time:
-
Permalink:
vcollab/vcti-python-template@0c8d42746a7777d6cabcc260fb0cef606057828d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/vcollab
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0c8d42746a7777d6cabcc260fb0cef606057828d -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file vcti_template-1.1.1-py3-none-any.whl.
File metadata
- Download URL: vcti_template-1.1.1-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7e511dbcdb93880aa0c56469a7993fc502b56a2eda61df1e37ecb6eb19aed0b
|
|
| MD5 |
74c972869f0b682dac5cce6e399deae6
|
|
| BLAKE2b-256 |
2e02812ff3efeb3e3ef74a2b579aeaa85e839562a26a7e110efdc6a6b629fc40
|
Provenance
The following attestation bundles were made for vcti_template-1.1.1-py3-none-any.whl:
Publisher:
publish.yml on vcollab/vcti-python-template
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vcti_template-1.1.1-py3-none-any.whl -
Subject digest:
f7e511dbcdb93880aa0c56469a7993fc502b56a2eda61df1e37ecb6eb19aed0b - Sigstore transparency entry: 1155582695
- Sigstore integration time:
-
Permalink:
vcollab/vcti-python-template@0c8d42746a7777d6cabcc260fb0cef606057828d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/vcollab
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0c8d42746a7777d6cabcc260fb0cef606057828d -
Trigger Event:
workflow_dispatch
-
Statement type: