Python SDK Templating
Filters can be used when defining computed attributes or Jinja2 Transforms within Infrahub.
Execution contexts
Filters are restricted based on the execution context in which a template is rendered:
- CORE — Computed attributes evaluated inside the Infrahub API server. Only fully trusted filters (no I/O, no side effects) are allowed.
- WORKER — Jinja2 transforms executed on Prefect background workers. Trusted filters and Infrahub client-dependent filters are allowed.
- LOCAL — Local CLI rendering and unrestricted usage. All filters are allowed.
The validate() method on Jinja2Template accepts an optional context parameter to enforce these restrictions:
from infrahub_sdk.template import Jinja2Template
from infrahub_sdk.template.filters import ExecutionContext
template = Jinja2Template(template="{{ sid | artifact_content }}")
# Raises JinjaTemplateOperationViolationError — blocked in CORE
template.validate(context=ExecutionContext.CORE)
# Passes — allowed in WORKER
template.validate(context=ExecutionContext.WORKER)
For backward compatibility, validate(restricted=True) maps to CORE and validate(restricted=False) maps to LOCAL.
Builtin Jinja2 filters
The following filters are shipped with Jinja2 and enabled within Infrahub.
| Name | CORE | WORKER | LOCAL |
|---|---|---|---|
| abs | ✅ | ✅ | ✅ |
| attr | ❌ | ❌ | ✅ |
| batch | ❌ | ❌ | ✅ |
| capitalize | ✅ | ✅ | ✅ |
| center | ✅ | ✅ | ✅ |
| count | ✅ | ✅ | ✅ |
| d | ✅ | ✅ | ✅ |
| default | ✅ | ✅ | ✅ |
| dictsort | ❌ | ❌ | ✅ |
| e | ✅ | ✅ | ✅ |
| escape | ✅ | ✅ | ✅ |
| filesizeformat | ✅ | ✅ | ✅ |
| first | ✅ | ✅ | ✅ |
| float | ✅ | ✅ | ✅ |
| forceescape | ✅ | ✅ | ✅ |
| format | ✅ | ✅ | ✅ |
| groupby | ❌ | ❌ | ✅ |
| indent | ✅ | ✅ | ✅ |
| int | ✅ | ✅ | ✅ |
| items | ❌ | ❌ | ✅ |
| join | ✅ | ✅ | ✅ |
| last | ✅ | ✅ | ✅ |
| length | ✅ | ✅ | ✅ |
| list | ✅ | ✅ | ✅ |
| lower | ✅ | ✅ | ✅ |
| map | ❌ | ❌ | ✅ |
| max | ✅ | ✅ | ✅ |
| min | ✅ | ✅ | ✅ |
| pprint | ❌ | ❌ | ✅ |
| random | ❌ | ❌ | ✅ |
| reject | ❌ | ❌ | ✅ |
| rejectattr | ❌ | ❌ | ✅ |
| replace | ✅ | ✅ | ✅ |
| reverse | ✅ | ✅ | ✅ |
| round | ✅ | ✅ | ✅ |
| safe | ❌ | ❌ | ✅ |
| select | ❌ | ❌ | ✅ |
| selectattr | ❌ | ❌ | ✅ |
| slice | ✅ | ✅ | ✅ |
| sort | ❌ | ❌ | ✅ |
| string | ✅ | ✅ | ✅ |
| striptags | ✅ | ✅ | ✅ |
| sum | ✅ | ✅ | ✅ |
| title | ✅ | ✅ | ✅ |
| tojson | ❌ | ❌ | ✅ |
| trim | ✅ | ✅ | ✅ |
| truncate | ✅ | ✅ | ✅ |
| unique | ❌ | ❌ | ✅ |
| upper | ✅ | ✅ | ✅ |
| urlencode | ✅ | ✅ | ✅ |
| urlize | ❌ | ❌ | ✅ |
| wordcount | ✅ | ✅ | ✅ |
| wordwrap | ✅ | ✅ | ✅ |
| xmlattr | ❌ | ❌ | ✅ |
Netutils filters
The following Jinja2 filters from Netutils are included within Infrahub.
| Name | CORE | WORKER | LOCAL |
|---|---|---|---|
| abbreviated_interface_name | ✅ | ✅ | ✅ |
| abbreviated_interface_name_list | ✅ | ✅ | ✅ |
| asn_to_int | ✅ | ✅ | ✅ |
| bits_to_name | ✅ | ✅ | ✅ |
| bytes_to_name | ✅ | ✅ | ✅ |
| canonical_interface_name | ✅ | ✅ | ✅ |
| canonical_interface_name_list | ✅ | ✅ | ✅ |
| cidr_to_netmask | ✅ | ✅ | ✅ |
| cidr_to_netmaskv6 | ✅ | ✅ | ✅ |
| clean_config | ✅ | ✅ | ✅ |
| compare_version_loose | ✅ | ✅ | ✅ |
| compare_version_strict | ✅ | ✅ | ✅ |
| config_compliance | ✅ | ✅ | ✅ |
| config_section_not_parsed | ✅ | ✅ | ✅ |
| delimiter_change | ✅ | ✅ | ✅ |
| diff_network_config | ✅ | ✅ | ✅ |
| feature_compliance | ✅ | ✅ | ✅ |
| find_unordered_cfg_lines | ✅ | ✅ | ✅ |
| fqdn_to_ip | ❌ | ❌ | ✅ |
| get_all_host | ❌ | ❌ | ✅ |
| get_broadcast_address | ✅ | ✅ | ✅ |
| get_first_usable | ✅ | ✅ | ✅ |
| get_ips_sorted | ✅ | ✅ | ✅ |
| get_nist_urls | ✅ | ✅ | ✅ |
| get_nist_vendor_platform_urls | ✅ | ✅ | ✅ |
| get_oui | ✅ | ✅ | ✅ |
| get_peer_ip | ✅ | ✅ | ✅ |
| get_range_ips | ✅ | ✅ | ✅ |
| get_upgrade_path | ✅ | ✅ | ✅ |
| get_usable_range | ✅ | ✅ | ✅ |
| hash_data | ✅ | ✅ | ✅ |
| int_to_asdot | ✅ | ✅ | ✅ |
| interface_range_compress | ✅ | ✅ | ✅ |
| interface_range_expansion | ✅ | ✅ | ✅ |
| ip_addition | ✅ | ✅ | ✅ |
| ip_subtract | ✅ | ✅ | ✅ |
| ip_to_bin | ✅ | ✅ | ✅ |
| ip_to_hex | ✅ | ✅ | ✅ |
| ipaddress_address | ✅ | ✅ | ✅ |
| ipaddress_interface | ✅ | ✅ | ✅ |
| ipaddress_network | ✅ | ✅ | ✅ |
| is_classful | ✅ | ✅ | ✅ |
| is_fqdn_resolvable | ❌ | ❌ | ✅ |
| is_ip | ✅ | ✅ | ✅ |
| is_ip_range | ✅ | ✅ | ✅ |
| is_ip_within | ✅ | ✅ | ✅ |
| is_netmask | ✅ | ✅ | ✅ |
| is_network | ✅ | ✅ | ✅ |
| is_reversible_wildcardmask | ✅ | ✅ | ✅ |
| is_valid_mac | ✅ | ✅ | ✅ |
| longest_prefix_match | ✅ | ✅ | ✅ |
| mac_normalize | ✅ | ✅ | ✅ |
| mac_to_format | ✅ | ✅ | ✅ |
| mac_to_int | ✅ | ✅ | ✅ |
| mac_type | ✅ | ✅ | ✅ |
| name_to_bits | ✅ | ✅ | ✅ |
| name_to_bytes | ✅ | ✅ | ✅ |
| name_to_name | ✅ | ✅ | ✅ |
| netmask_to_cidr | ✅ | ✅ | ✅ |
| netmask_to_wildcardmask | ✅ | ✅ | ✅ |
| normalise_delimiter_caret_c | ✅ | ✅ | ✅ |
| paloalto_panos_brace_to_set | ✅ | ✅ | ✅ |
| paloalto_panos_clean_newlines | ✅ | ✅ | ✅ |
| regex_findall | ❌ | ❌ | ✅ |
| regex_match | ❌ | ❌ | ✅ |
| regex_search | ❌ | ❌ | ✅ |
| regex_split | ❌ | ❌ | ✅ |
| regex_sub | ❌ | ❌ | ✅ |
| sanitize_config | ✅ | ✅ | ✅ |
| section_config | ✅ | ✅ | ✅ |
| sort_interface_list | ✅ | ✅ | ✅ |
| split_interface | ✅ | ✅ | ✅ |
| uptime_seconds_to_string | ✅ | ✅ | ✅ |
| uptime_string_to_seconds | ✅ | ✅ | ✅ |
| version_metadata | ✅ | ✅ | ✅ |
| vlanconfig_to_list | ✅ | ✅ | ✅ |
| vlanlist_to_config | ✅ | ✅ | ✅ |
| wildcardmask_to_netmask | ✅ | ✅ | ✅ |
Infrahub filters
These filters are provided by the Infrahub SDK for artifact and file object content composition.
| Name | CORE | WORKER | LOCAL |
|---|---|---|---|
artifact_content | ❌ | ✅ | ✅ |
file_object_content | ❌ | ✅ | ✅ |
file_object_content_by_hfid | ❌ | ✅ | ✅ |
file_object_content_by_id | ❌ | ✅ | ✅ |
from_json | ✅ | ✅ | ✅ |
from_yaml | ✅ | ✅ | ✅ |
Usage examples
Inline artifact content by storage_id:
{{ artifact.node.storage_id.value | artifact_content }}
Inline file object content:
{# By storage_id #}
{{ file_object.storage_id.value | file_object_content }}
{# By node UUID #}
{{ file_object.id | file_object_content_by_id }}
{# By Human-Friendly ID #}
{{ hfid_components | file_object_content_by_hfid(kind="NetworkCircuitContract") }}
Parse structured content with chaining:
{# JSON artifact → access parsed fields #}
{% set config = artifact.node.storage_id.value | artifact_content | from_json %}
interface {{ config.interface_name }}
ip address {{ config.ip_address }}
{# YAML artifact → iterate parsed data #}
{% set config = artifact.node.storage_id.value | artifact_content | from_yaml %}
{% for route in config.static_routes %}
ip route {{ route.prefix }} {{ route.next_hop }}
{% endfor %}
Client-dependent filters (artifact_content, file_object_content, file_object_content_by_id, file_object_content_by_hfid) require an InfrahubClient to be passed to Jinja2Template:
from infrahub_sdk.template import Jinja2Template
# At construction time
template = Jinja2Template(template=my_template, client=client)
# Or via deferred injection
template = Jinja2Template(template=my_template)
template.set_client(client)
Known issues
Unable to combine the map and sort filters (https://github.com/pallets/jinja/issues/2081)
When using the map filter with the sort filter, you may encounter the following error:
TypeError: 'async_generator' object is not iterable
As a workaround you can use the list filter between map and sort filter.