Introduction
Jinja is a powerful templating engine for Python, extensively used in APIO workflows to dynamically generate JSON structures, manipulate dictionaries, and format output. This guide introduces key features of Jinja, demonstrates APIO-specific extensions, and provides best practices for leveraging Jinja in dynamic workflows.
Examples and exercises can be executed by the reader using the Template Playground, available under the GUI Help menu/Template playground.
Core Concepts in Jinja Templating
Delimiters
- Used for statements (loops, conditions, etc.):
{% ... %}
- Used to print variables or expressions into the output:
{{ ... }}
Remark
Using -%}
instead of %}
and {%-
instead of {%
helps in whitespace control and better formatting
Use
-%}
when you want to strip trailing whitespace or blank lines after a statement.Use
{%-
when you want to strip leading whitespace before a statement.Use Both: to strip whitespace on both sides of a block or expression for compact output.
Exercise
In the Template Playground, copy paste the following in the Context Panel
{
"context":{
"eid": {"value": "12345"},
"iccid": "",
"profileType": "test"
}
}
In the Template Panel, copy paste the following
{
{% if context.eid %}
"eid": {{ context.eid }}
{% endif %}
}
Click on the “run” button, and check the result. Replace %}
with -%}
and {%
with {%-
and check what is changing.
Dynamic JSON Construction
Jinja allows the conditional inclusion of attributes, ensuring only meaningful data is included. For instance, in the example above, If context.eid
is non-empty, it is included in the JSON output; otherwise, it is omitted.
Exercise
Change the value of the key “eid”: replace {"value": "12345"}
with {}
, ""
, false
or null
and check the result.
Clarifying the Differences Between JSON Objects and Python Dictionaries
JSON objects and Python dictionaries often seem interchangeable in Jinja templates due to their similar structure and use of {} for key-value pairs. However, there are important distinctions that become particularly significant when working with booleans and null values.
JSON Object
A JSON object is a serialized text format designed for data exchange between systems. Its characteristics include:
- Language-Independent: JSON is universally supported and follows strict rules.
- Value Types: JSON values can be:
- Strings, numbers, booleans (
true
/false
), arrays, objects, ornull
. - Booleans: Represented as
true
andfalse
(lowercase). - Null Values: Represented as
null
, indicating the absence of a value (equivalent to Python'sNone
).
- Strings, numbers, booleans (
- Purpose: Used for transmitting data (e.g., APIs, files).
- Parsing Required: JSON objects must be parsed into native data structures (e.g., Python dictionaries) before use in programming.
Dictionary
A dictionary is a native Python data structure stored in memory. It is designed for programming logic and data manipulation:
- Value Types: Python dictionaries can store any Python object as values, including:
- Strings, numbers, booleans (
True
/False
),None
, lists, and other dictionaries. - Booleans: Represented as
True
andFalse
(capitalized). - Null Values: Represented as
None
, a special constant of typeNoneType
that signifies "no value" or "nothing." In conditional statements,None
evaluates toFalse
.
- Strings, numbers, booleans (
- Serialization: Dictionaries can be converted to JSON format using serialization when needed.
- Purpose: Used in Python applications for logic and data manipulation.
Key Difference Between JSON Objects and Dictionaries
Feature | JSON Object | Python Dictionary |
---|---|---|
Format | Serialized text for data exchange. | In-memory Python data structure. |
Boolean Values | true , false (lowercase). | True , False (capitalized). |
Null Values | null . | None . |
Usage | For data transmission (APIs, files). | For in-code programming logic. |
Parsing/Serialization | Requires parsing to become usable. | Directly usable in Python; can be serialized. |
Truthy and Falsy Values in Jinja
In Jinja (based on Python rules), values are evaluated as truthy or falsy:
Falsy Values:
False
(Python boolean) orfalse
(JSON boolean parsed to Python).None
(Python) ornull
(JSON parsed to Python).0
(integer or float).- Empty strings (
""
). - Empty containers (
[]
,{}
,()
).
Truthy Values:
- Everything else, including:
- Non-empty strings (
"hello"
,"1"
). - Non-zero numbers (
42
,-1
). - Non-empty containers (
[1, 2, 3]
,{"key": "value"}
).
- Non-empty strings (
- Everything else, including:
APIO: Handling JSON Objects as Dictionaries
In APIO, JSON objects are automatically parsed into Python dictionaries before being passed to Jinja templates.
Example
Given the JSON object:
{
"context": {
"isActive": true
}
}
This is treated as a Python dictionary in Jinja:
{
"context": {
"isActive": True
}
}
Accessing Dictionary Keys in Jinja
In Jinja, you can directly access dictionary keys using dot notation:
{{ context.isActive }}
- If
context.isActive
holds a truthy value, both{{ context.isActive == True }}
and{{ context.isActive }}
evaluate toTrue
.
Conditional Example
{% if context.isActive %}
isActive is True.
{% else %}
isActive is False.
{% endif %}
If context.isActive
contains any truthy value, the output will be:
isActive is True.
Dynamically Generating JSON Based on Booleans
If you want to dynamically generate JSON based on the value of {{ context.isActive }}
, you can use the | tojson
filter in Jinja. This filter ensures proper serialization of Python booleans (True
, False
) into JSON-compatible booleans (true
, false
).
Example
Input:
{
"context": {
"isActive": true
}
}
Template:
{
"result": {{ context.isActive | tojson }}
}
Output:
{
"result": true
}
How It Works
context.isActive
:- This variable holds a Python boolean (
True
orFalse
) because APIO converts JSON booleans during parsing.
- This variable holds a Python boolean (
| tojson
Filter:- Converts Python
True
to JSONtrue
and PythonFalse
to JSONfalse
, ensuring the output is JSON-compatible.
- Converts Python
Summary
JSON vs Dictionary:
- JSON objects are serialized text formats; dictionaries are in-memory Python structures.
- JSON
true
/false
→ PythonTrue
/False
; JSONnull
→ PythonNone
.
Truthy and Falsy Values:
- Jinja evaluates values based on Python truthiness rules. Non-empty strings, non-zero numbers, and non-empty containers are truthy.
APIO Automatic Parsing:
- APIO converts JSON objects to Python dictionaries, allowing direct access to keys in Jinja templates.
Using
| tojson
for Serialization:- The
| tojson
filter ensures proper conversion of Python booleans to JSON booleans when generating JSON output dynamically.
- The
Key Dictionaries in APIO Workflows
Among the available Dictionaries in APIO, the following are frequently used
context
Used to store dynamic data throughout the workflow
Example: adding new key-value pairs using the Context Setter cell.
request
Contains details of the HTTP request, including
Body
Method
Match_info (information from the URL path)
Content_type
Params (URL parameters)
instance
- Holds metadata about the current workflow instance, including the instance ID