Quickly and easily define, load, render and write Jinja templates.
Project description
CloudMage JinjaUtils Python3 Utility Package
Table of Contents
- Description
- Road Map
- Python Version Support
- Package Installation
- Package Dependencies
- JinjaUtils Class
- ChangeLog
- Contacts and Contributions
Description
This utility package was created to allow quick and easy access method to work with Jinja templates within a python environment. The package will give access to a class that can be imported and instantiated, creating a JinjaUtils instance that will allow the consumer the ability to quickly and easily set jinja options via object properties, load templates including custom templates, render those templates and write the template output to the an output directory/file with little concern around error handling and processing. A few lines of code and a provided template is all that is needed to start producing template driven file creation quickly and easily.
Road Map
Beyond the initial capabilities of this library, new features will be evaluated and could be added with feature requests, or as additional processes that can be simplified are discovered.
Python Version Support
This library is compatible with Python 3.6 and higher. It may work with earlier versions of Python3 but was not tested against anything earlier then 3.6. As Python 2.x is soon to be end of life, backward compatibility was not taken into consideration.
Package Installation
This library has been published to PyPi and can be installed via normal python package manager conventions such as pip or poetry.
pip3 install cloudmage-jinjautils
Package Dependencies
This package installs and imports the following python modules during installation:
- jinja2
- Template
- Environment
- FileSystemLoader
Additionally the package takes advantage of the following built in python modules:
- os
- sys
- json
- inspect
- ntpath
- shutil
- datetime
JinjaUtils Class
The JinjaUtils class has the following described methods, properties and attributes accessable to it upon object instantiation. A few object constructor arguments can be provided at the time that the object is instantiated. Object getter property methods are accessed from the object in standard dot notation Jinja.verbose, Jinja.template_directory, etc.
and Object settter methods are used by assigning a value to the object property Jinja.template_directory = '/path/to/templates
. The class gives the object instance access to the following properties:
JinjaUtils Constructor Arguments
verbose | Enables verbose mode. [true=enable false=disable] |
---|---|
required | false |
type | bool |
default | false (disabled) |
log | Redirects object standard log messaging to provided log object. |
---|---|
required | false |
type | obj |
default | None (log to stdout, stderr if verbose=true) |
JinjaUtils Attributes and Properties
The following attributes/properties are available to an instantiated object instance. Any of the attributes or properties can be accessed with standard object dot notation as in the example: verbose_mode = JinjaUtils.verbose
verbose | Verbose setting that controls logging level within the object class. [true=enabled, false=disabled] |
---|---|
returns | true or false (enabled or disabled) |
type | bool |
instantiated value | false |
trim_blocks | Enables or disables the Jinja trim_blocks setting used when loading templates by the Jinja FileSystemLoader. |
---|---|
returns | true or false (enabled or disabled) |
type | bool |
instantiated value | true |
lstrip_blocks | Enables or disables the Jinja lstrip_blocks setting used when loading templates by the Jinja FileSystemLoader. |
---|---|
returns | true or false (enabled or disabled) |
type | bool |
instantiated value | true |
template_directory | Getter property method that returns the string value of the currently configured Jinja template directory |
---|---|
returns | Jinja template directory -> /jinja/templates |
type | str |
instantiated value | None |
available_templates | Returns a list of available template files that have been loaded by the Jinja FileSystemLoader located in the configured template directory that are available for use. |
---|---|
returns | List of files available in the loaded template library -> ["template1.j2" ,"template2.j2" |
type | list |
instantiated value | None |
load | Returns the file name of the currently loaded Jinja template that is ready for rendering |
---|---|
returns | Loaded template name -> myFile.j2 |
type | str |
instantiated value | None |
rendered | Returns the currently rendered template object, ready to be written to disk |
---|---|
returns | Rendered template object |
type | obj |
instantiated value | None |
write | Returns true or false depending on if the rendered template was successfully written to disk |
---|---|
returns | true or false value signaling a valid write or failed write to disk |
type | bool |
instantiated value | true or false value signaling a valid write or failed write |
log | The class logger. Will either write directly to stdout, stderr, or to a lob object if passed into the object constructor during object instantiation |
---|---|
returns | Log Event Stream |
type | str |
instantiated value | Logs written to stdout, stderr |
JinjaUtils Available Methods
The following methods are available to an instantiated object instance. Some of the methods are simply setter methods that run the logic required to discover and then set one of the above instance properties.
Setter method for verbose
property that enables or disables verbose mode
parameter | type | required | arg info |
---|---|---|---|
verbose | bool | true | True enables verbose logging, False disables it |
Examples:
# Getter method
verbose_setting = JinjaUtils.verbose
# Setter method
JinjaUtils.verbose = True
Setter method for trim_blocks
property that enables or disables the Jinja trim_blocks option during the construction of the Jinja Environment and template loading process via the Jinja FileSystemLoader.
parameter | type | required | arg info |
---|---|---|---|
trim_blocks | bool | true | True enables trim_blocks logging, False disables the option |
Examples:
# Getter method
jinja_trim_blocks_setting = JinjaUtils.trim_blocks
# Setter method
JinjaUtils.trim_blocks = True
Setter method for lstrip_blocks
property that enables or disables the Jinja lstrip_blocks option during the construction of the Jinja Environment and template loading process via the Jinja FileSystemLoader.
parameter | type | required | arg info |
---|---|---|---|
lstrip_blocks | bool | true | True enables lstrip_blocks logging, False disables the option |
Examples:
# Getter method
jinja_lstrip_blocks = JinjaUtils.lstrip_blocks
# Setter method
JinjaUtils.lstrip_blocks = True
Setter method for template_directory
property that is used to specify the location of the Jinja template directory. When this setter method is called, a valid directory path must be provided. The directory path is checked by os.path.exists()
and must be a valid directory location path. The method will search the directory path for any files in the given directory location and automatically instruct the Jinja FileSystemLoader to load the templates into the Environment template library where they can be called by the object consumer at any point to be loaded, rendered and written to on disk. This setter will also set the value of the .available_templates
attribute.
parameter | type | required | arg info |
---|---|---|---|
template_directory | str | true | Provided path must be a valid URL directory path. |
Examples:
# Getter method
jinja_template_directory = JinjaUtils.template_directory
# Setter method
JinjaUtils.template_directory = '/path/to/my/template/directory'
Setter method for load
property. When this method is invoked either a file path argument or template name argument must be provided. If a file name argument is given, the loader will search through the templates that are contained in the currently configured template directory and loaded into the current Jinja Environment by the .template_directory
setter call. To view a list of the available templates a call to the .available_templates
attribute can be made. If a file system path is provided to the loader, then the loader will search the given file path, and if a valid file is found, it will instruct the loader to load the provided file. Once a file has been loaded by the object, it is ready to be rendered with the .render
property.
parameter | type | required | arg info |
---|---|---|---|
template | str | true | Template file name located in the templates directory or valid file path to template file. |
Examples:
# Getter method
jinja_loaded_template = JinjaUtils.load
# Setter method
JinjaUtils.load = '/path/to/my/template/directory/template.j2'
for template in JinjaUtils.available_templates:
print(template)
JinjaUtils.load = 'template.j2'
The render method takes an undermined number of keyword arguments representing the template variables and objects that will supply the values to those variables respectively when rendering the template. The keyword example formats such as variables=dictionaryObject
, people=["tom", "susan", tonya"]
would be mapped to the template at the time of render and made available to the template. In the given examples, the template may require a dictionary named variables that it will iterate through, or a variable named people that is an expected list that it will use to populate template sections. When the render
method is called, Jinja will attempt to render the currently loaded template and supply any of keyword arguments that were passed as method arguments at the time that the render method was called.
parameter | type | required | arg info |
---|---|---|---|
names=names, values=values, etc=4 | **kwargs | false | Currently loaded template will be rendered. |
Examples:
print(JinjaUtils.load) # template.j2
JinjaUtils.render(names=names, values=values, etc=4)
# This will render the currently loaded template2.j2 and pass the names, values, and etc values to it
Once the template has been rendered, it can be written to disk using the write
method. The write method takes 2 required arguments consisting of the output directory and output file, along with 1 optional argument to turn file backup off. When the write method is used, it will write the currently rendered template to the output directory specified as the output file name specified. If during the write operation it discovers an existing file with the same name in the target directory, by default instead of just overwriting the file callously, the write method will take a copy of the existing file, strip off the original extention to avoid non unique file name conflicts and write the copy appending an extention in the format of _YYYYMMDD_HMS.bak
. This timestamp formatted extention will allow easy identification of when the backup of the file was taken. The default file backup feature can be turned off by passing the backup=False
option to the write command when called. If backup is disabled, then calling the write method will simply just overwrite any existing files in the output directory with the output filename that already exist. Provided output_directory argument value must exist and be valid directory paths, which are validated by os.path.exists()
, and must not be the path to a file. The provided output_file argument value must be a valid file name, and will be stripped of any trailing path.
parameter | type | required | arg info |
---|---|---|---|
output_directory | str | true | Must be valid directory path to existing directory. |
output_file | str | true | Filename only, paths are stripped using only the file basename . |
backup | bool | false | Bool value to enable or disable existing file backups. Default=true |
Examples:
print(str(JinjaUtils.rendered))
JinjaUtils.write(output_directory='/reports', output_file='monthly_report.yaml', backup=True)
Method to enable logging throughout the class. Log messages are sent to the log method providing the log message, the message type being one of [debug, info, warning, error]
, and finally the function or method id that is automatically derived within the function or method using the python inspect module. If a log object such as a logger or an already instantiated log object instance was passed to the class constructor during the objects instantiation, then all logs will be written to the provided log object. If no log object was provided during instantiation then all debug
, info
, and warning
logs will be written to stdout, while any encountered error
log entries will be written to stderr. Note that debug or verbose mode needs to be enabled to receive the event log stream.
arg | type | required | arg info |
---|---|---|---|
log_msg | str | true | The actual message being sent to the log method |
log_type | str | true | The type of message that is being sent to the log method, one of [debug, info, warning, error] |
log_id | str | true | A string value identifying the sender method or function, consisting of the method or function name |
Examples:
def my_function():
__function_id = inspect.stack()[0][3]
JinjaUtils.log(
f"{__function_id} called.",
'info',
__function_id
)
JinjaUtils Class Usage
The following section will show a few examples of how the module can be used to generate documents from available templates quickly and easily.
Basic Usage
from cloudmage.jinjautils import JinjaUtils
# Set template directory, contains weekly_report.j2, monthly_report.j2, annual_report.j2
jinja_template_path = os.path.join(os.getcwd(), 'templates')
jinja_output_path = os.path.join(os.getcwd(), 'monthly_reports')
# Set data variable
monthly_sales = {'week_1': 15000, 'week_2': 1000, 'week_3': 2000, 'week_4': 2500}
sales_team = ['tonya', 'tom', 'billy', 'amanda']
# Instantiate JinjaUtils Object
Jinja = JinjaUtils()
# Set the template directory, this loads all templates into the Jinja Environment
# and constructs the available_templates attribute list value
Jinja.template_directory = jinja_template_path
print(Jinja.available_templates) # prints ['weekly_report.j2', 'monthly_report.j2', 'annual_report.j2']
# Load one of the available templates
Jinja.load = 'monthly_report.j2'
# Render the template
Jinja.render(pnl=monthly_sales, team=sales_team)
# Write the rendered template to disk, Backup of existing files is ENABLED by default, so turn it off
Jinja.write(output_directory=jinja_output_path, output_file='feb_sales.html', backup=False)
Optional Verbose Class Constructor Argument:
When instantiating the class an optionalverbose
argument can be provided. The argument expects a bool value of eitherTrue
orFalse
. By default verbose is set to False. Ifverbose=True
is passed during object instantiation, then debug mode is turned on allowing the class to output DEBUG, INFO, and WARNING messages to stdout, and ERROR messages to stderr.
from cloudmage.jinjautils import JinjaUtils
# Instantiate JinjaUtils Object
Jinja = JinjaUtils(verbose=True)
# Load one of the available templates
Jinja.load = './templates/annual_sales.j2'
# Render the template
Jinja.render(total_sales="25,000")
# Write the rendered template to disk
Jinja.write(output_directory='.', output_file='2019-sales.yaml')
# Class DEBUG, INFO, and WARNING messages will be printed to stdout, and ERROR messages will be printed to stderr
Optional Log Object:
When instantiating the class an optionallog
argument can also be provided. The argument expects an Logger object to be passed as an input. If passed then all DEBUG, INFO, WARNING, and ERROR messages will be printed to the standard log levels (log.debug()
,log.info()
,log.warning()
,log.error()
) and printed to the passed respective logger object method.
from cloudmage.jinjautils import JinjaUtils
# Define test log class
# This is an example log object that simply appends any DEBUG, INFO and ERROR received class messages
# to the respective log level list. Normally this would be a logger or custom log object.
class Log(object):
"""Test Log Object"""
def __init__(self):
"""Class Constructor"""
self.debug_logs = []
self.info_logs = []
self.warning_logs = []
self.error_logs = []
def debug(self, message):
"""Log Debug Messages"""
self.debug_logs.append(message)
def info(self, message):
"""Log Info Messages"""
self.info_logs.append(message)
def warning(self, message):
"""Log Warning Messages"""
self.warning_logs.append(message)
def error(self, message):
"""Log Error Messages"""
self.error_logs.append(message)
# Instantiate test log class
Logger = Log()
# Instantiate JinjaUtils Object
Jinja = JinjaUtils(verbose=True, logs=Logger)
# Disable trim_blocks, lstrip_blocks
Jinja.trim_blocks = False
Jinja.lstrip_blocks = False
# Load one of the available templates
Jinja.load = './templates/team_schedule.j2'
# Render the template
Jinja.render()
# Write the rendered template to disk
Jinja.write(output_directory='/reports', output_file='Feb_Schedule.yaml', backup=True)
for items in Logger.debug_logs:
print(item) # Prints stored debug logs
Changelog
To view the project changelog see: ChangeLog:
Project details
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
Hashes for cloudmage_jinjautils-1.0.7.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | b69ced7c1c7bdb10f1db5196b22dac738c8884192ee208248dd1e509fa909675 |
|
MD5 | 5e56a3f7992592ba24f8dd2dcee8bfe5 |
|
BLAKE2b-256 | 0075d7762e9b2d175347b9e7c405ee34b6ae420f118c8ff9b09b49cc3dfcc728 |
Hashes for cloudmage_jinjautils-1.0.7-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 03a9890730cd7b84596a5c7ee7d9a3abe4b1b137506c5f5ba602c3a4dfca02b3 |
|
MD5 | 74a051bf2817ad56f3b7754b95a90157 |
|
BLAKE2b-256 | d75a87895b235dfc3e03a6923c84e00846e06a739795483b38f8456f86d0a7d5 |