TypedTemplate
A simple template engine wrapper for Python that uses Pydantic models to validate and type hint the input data.
Installation
Basic installation w/o any extras, you need to include a supported template engine in your project dependencies:
pip install typedtemplate
Installation with Jinja2 support, will install Jinja2 as a dependency:
pip install typedtemplate[jinja2]
Support Template Engines
We currently support the following template engines:
If you'd like to see support for another template engine, please open an issue or a pull request.
Usage
Hello World Example
A basic example using a string template defined in python.
from pydantic import Field
from typedtemplate import TypedTemplate, JinjaTemplateEngine
# Basic engine configuration
# This only supports string templates (no files)
# See examples below for more advanced engine configuration
engine = JinjaTemplateEngine()
class HelloWorldTemplate(TypedTemplate):
# Tells the template what engine to use
template_engine = engine
# The template to render
template_string = "Hello, {{ name }}!"
# The typed input data for this template
name: str = Field(description="The name to say hello to")
# If you don't provide `name` at creation, it will raise a ValidationError
template = HelloWorldTemplate(name="World")
# Model validation is also run when `render` is called
print(template.render()) # "Hello, World!"
Jinja2 File Template Example
This examples shows how to configure Jinja2 to look for templates in a specific directory.
Note, this example also turns debugging on, which will print warnings and errors to console.
The template is specified via the template_file attribute, which is the file name of the template to look for in the configured directories.
import os
from pydantic import Field
from typedtemplate import TypedTemplate, JinjaTemplateEngine
# Create a list of directories to look for templates in
current_directory = os.path.dirname(os.path.abspath(__file__))
test_data_dir = os.path.join(current_directory, "test_data")
dirs = [test_data_dir]
# Configuring Jinja2 to look for templates in a specific directory, "test_data" in this case
engine = JinjaTemplateEngine(dirs=dirs, debug=True)
class HelloWorldFileTemplate(TypedTemplate):
# Tells the template what engine to use
template_engine = engine
# This will look for a file called "hello_world.jinja2" in the "test_data" directory
# Assume the template is the same as the Hello World example above
template_file = "hello_world.jinja2"
# The typed input data for this template
name: str = Field(description="The name to say hello to")
# If you don't provide `name` at creation, it will raise a ValidationError
template = HelloWorldFileTemplate(name="World")
# Model validation is also run when `render` is called
print(template.render()) # "Hello, World!"
Django File Template Example
This examples shows how to configure Django to look for templates in a specific directory.
In most cases, you will only use Django templates with the Django framework.
This example assumes you ARE NOT using the Django framework and calls the settings.configure method to configure Django for you.
If you are using the Django framework, please look at the next example for the subtle difference.
import os
from pydantic import Field
from typedtemplate import TypedTemplate, DjangoTemplateEngine
# Create a list of directories to look for templates in
current_directory = os.path.dirname(os.path.abspath(__file__))
test_data_dir = os.path.join(current_directory, "test_data")
dirs = [test_data_dir]
# Configuring Django to look for templates in a specific directory, "test_data" in this case
# Generally, you shouldn't use the Django templating engine without using the Django framework
# If Django templates are already configured in your django settings, you can drop the `dirs` parameter and set `skip_django_configure` to `True`
engine = DjangoTemplateEngine(dirs=dirs, debug=True, skip_django_configure=False)
class HelloWorldFileTemplate(TypedTemplate):
# Tells the template what engine to use
template_engine = engine
# This will look for a file called "hello_world.txt" in the "test_data" directory
# Assume the template is the same as the Hello World example above
template_file = "hello_world.txt"
# The typed input data for this template
name: str = Field(description="The name to say hello to")
# If you don't provide `name` at creation, it will raise a ValidationError
template = HelloWorldFileTemplate(name="World")
# Model validation is also run when `render` is called
print(template.render()) # "Hello, World!"
Use with the Django Web Framework
This example assume you are using the Django web framework. You should have already configured your Django settings to look for templates in a specific directory. See the Django documentation for more information on template directory configuration https://docs.djangoproject.com/en/5.0/topics/templates/#configuration
import os
from pydantic import Field
from typedtemplate import TypedTemplate, DjangoTemplateEngine
# Tells the engine to use the already configured Django settings
engine = DjangoTemplateEngine(skip_django_configure=True)
class HelloWorldFileTemplate(TypedTemplate):
# Tells the template what engine to use
template_engine = engine
# This will look for a file called "hello_world.txt" in directories configured in your Django settings
# Assume the template is the same as the Hello World example above
template_file = "hello_world.txt"
# The typed input data for this template
name: str = Field(description="The name to say hello to")
# If you don't provide `name` at creation, it will raise a ValidationError
template = HelloWorldFileTemplate(name="World")
# Model validation is also run when `render` is called
print(template.render()) # "Hello, World!"
Advanced Pydantic Model Usage:
from typing import Optional
from pydantic import BaseModel, Field
from typedtemplate import TypedTemplate, JinjaTemplateEngine
# Pydantic Object Model
class User(BaseModel):
first_name: str
last_name: str
age: int
occupation: Optional[str] = None
# Basic engine configuration
engine = JinjaTemplateEngine()
template_str = """
<h1>Users</h1>
<ol>
{% for user in users %}
<li>{{ user.first_name }} {{ user.last_name }} ({{ user.age }} years old){% if user.occupation %}: {{ user.occupation }}{% endif %}</li>
{% endfor %}
</ol>
<p>Total Users: {{ users|length }}</p>
"""
class UserListTemplate(TypedTemplate):
# Tells the template what engine to use
template_engine = engine
# The template to render
template_string = template_str
# The typed input data for this template
users: list[User] = Field(description="A list of users")
users = [
User(first_name="John", last_name="Doe", age=30, occupation="Software Engineer"),
User(first_name="Jane", last_name="Doe", age=28, occupation="Doctor"),
User(first_name="Alice", last_name="Smith", age=25),
]
# If you don't provide `name` at creation, it will raise a ValidationError
template = UserListTemplate(users=users)
# Model validation is also run when `render` is called
print(template.render())
Contributing
We're open to contributions! If you have any ideas, feel free to open an issue or a pull request.
License
This repository is licensed under the MIT license. See LICENSE for details.
Metadata
Release files for typedtemplate 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| typedtemplate-0.2.1.tar.gz | 5.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| typedtemplate-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.1 kB
Release files / typedtemplate-0.2.1.tar.gz
| Download URL | typedtemplate-0.2.1.tar.gz |
|---|---|
| Size | 5.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c6a02fba4ce8d288cb2647a947d6cedc2fadf6322cd3f8596f5cb1fc824cbcc4
|
|
BLAKE2b-256 checksum How to use checksums |
2eaf132218981fb7f697c243edc1bc5861284f5b64297fb5d3f356630ad99dcc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/5.0.0 CPython/3.12.3
|
Release files / typedtemplate-0.2.1-py3-none-any.whl
| Download URL | typedtemplate-0.2.1-py3-none-any.whl |
|---|---|
| Size | 6.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2223d7d6603f6db173667dcfba7e5b103d1ad3c59dede455ef4c22b7bc1f6616
|
|
BLAKE2b-256 checksum How to use checksums |
eaa80182553ee1e35f051f9666701c119c0227d107c81c9ed9f5c8f3ffc54a41
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/5.0.0 CPython/3.12.3
|
Security for typedtemplate 0.2.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.