<jupyter_start><jupyter_text>Jinja Templating for Data Science Sarah <NAME> TBD  Why use templating?* need to scale up your reporting efforts* need automated, customizable output as html, pdf, or .docx* generating reports for clients using jupyter notebook alone isn't cutting it InspirationThis post: http://pbpython.com/pdf-reports.html  What makes Jinja great?* good documentation  Installpip install Jinja2  Basic API OverviewThe most basic way to create a template and render it is through Template. This however is not the recommended way to work with it if your templates are not loaded from strings but the file system or another data source:<jupyter_code>from jinja2 import Template

template = Template('Hello {{ name }}!')
template.render(name='<NAME>')<jupyter_output><empty_output><jupyter_text>The dict or keywords arguments passed to the template are the so-called “context” of the template. What you can see here is that Jinja2 is using unicode internally and the return value is an unicode string. So make sure that your application is indeed using unicode internally. Jinja2 uses a central object called the template Environment. Instances of this class are used to store the configuration and global objects, and are used to load templates from the file system or other locations.Most applications will create one Environment object on application initialization and use that to load templates.This will create a template environment with the default settings and a loader that looks up the templates in the templates folder inside the yourapplication python package.<jupyter_code>from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(
    loader=PackageLoader('yourapplication', 'templates'),
    autoescape=select_autoescape(['html', 'xml'])
)<jupyter_output><empty_output><jupyter_text>To load a template from this environment you just have to call the get_template() method which then returns the loaded Template:template = env.get_template('mytemplate.html')To render it with some variables, just call the render() method:print template.render(the='variables', go='here')TODO: go over these methods  UnicodeFor Jinja2 the default encoding of templates is assumed to be utf-8.To set module encoding add the following comment to the first or second line of the Python module using the Unicode literal: -*- coding: utf-8 -*-  Autoescaping Why is autoescaping important?***autoescaping is not a default in Jinja2, but they are going to change this in the future.It’s recommended to configure a sensible default for autoescaping. This makes it possible to enable and disable autoescaping on a per-template basis (HTML versus text for instance). The enabled_extensions is an iterable of all the extensions that autoescaping should be enabled for. Likewise disabled_extensions is a list of all templates it should be disabled for. If a template is loaded from a string then the default from default_for_string is used. If nothing matches then the initial value of autoescaping is set to the value of default. Example configuration to turn it on at all times except if the template ends with .txt:<jupyter_code>from jinja2 import Environment, select_autoescape
env = Environment(autoescape=select_autoescape(
    disabled_extensions=('txt',),
    default_for_string=True,
    default=True,
))
# TODO: more about autoescaping<jupyter_output><empty_output><jupyter_text>The Context  Loaders  Bytecode Cache  SandboxThe Jinja2 sandbox can be used to evaluate untrusted code. Access to unsafe attributes and methods is prohibited.  Template Designer Overview* A Jinja template is simply a text file* Jinja can generate any text-based format (HTML, XML, CSV, LaTeX, etc.)* A template contains:    * variables and/or expressions, which get replaced with values when a template is rendered    * tags which control the logic of the template. The following example shows the default configuration settings. An application developer can change the syntax configuration from {% foo %} to , or something similar.There are a few kinds of delimiters. The default Jinja delimiters are configured as follows:* {% ... %} for Statements* {{ ... }} for Expressions to print to the template output* { ... } for Comments not included in the template output* $  ... $ for Line Statements  Expressions Literals“Hello World”:Everything between two double or single quotes is a string. 42 / 42.23:Integers and floating point numbers are created by just writing the number down. If a dot is present, the number is a float, otherwise an integer.[‘list’, ‘of’, ‘objects’]:Everything between two brackets is a list.(‘tuple’, ‘of’, ‘values’):Tuples are like lists that cannot be modified (“immutable”). If a tuple only has one item, it must be followed by a comma (('1-tuple',)).{‘dict’: ‘of’, ‘key’: ‘and’, ‘value’: ‘pairs’}:A dict in Python is a structure that combines keys and values. Keys must be unique and always have exactly one value.true / false:true is always true and false is always false. The special constants true, false, and none are indeed lowercase.<jupyter_code>For example, you can easily create a list of links using lists and tuples for (and with) a for loop:

<ul>
{% for href, caption in [('index.html', 'Index'), ('about.html', 'About'),
                         ('downloads.html', 'Downloads')] %}
    <li><a href="{{ href }}">{{ caption }}</a></li>
{% endfor %}
</ul><jupyter_output><empty_output><jupyter_text>A commented-out for loop<jupyter_code>{# note: commented-out template because we no longer use this
    {% for user in users %}
        ...
    {% endfor %}
#}<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07265638844586213, 'fraction_numerical': 0.003189792663476874, 'mean_word_length': 4.978813559322034, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 1}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '57483', 'license': 'Unlicense', 'n_tokens_mistral': 1439, 'n_tokens_neox': 1400, 'n_words': 739, 'path': 'jinja_templating/jinja_for_data_science.ipynb', 'repo_name': 'sbraden/yakity-yak', 'size': '5654'}