Como Usar Filtros Jinja: Exemplos Simples

pDamascenopDamasceno
8 min read

Filtros Jinja2: Guia Completo com Exemplos Práticos

O Jinja2 é uma poderosa biblioteca de templates para Python, amplamente utilizada para manipular dados diretamente em templates. Seus filtros embutidos permitem transformar e formatar dados de maneira eficiente. Este guia explora os filtros mais usados, com explicações detalhadas, exemplos práticos e casos de uso reais, ajudando você a aplicar o Jinja2 em projetos de automação, geração de relatórios ou configurações de rede.

Agrupando Dados com o Filtro batch

Propósito

O filtro batch divide uma sequência em sublistas (ou "lotes") com um número fixo de elementos. É ideal para organizar dados em grupos para exibição ou processamento em blocos.

Sintaxe

batch(value, linecount, fill_with=None)

  • value: Sequência a ser agrupada.

  • linecount: Número máximo de elementos por grupo.

  • fill_with (opcional): Valor para preencher grupos incompletos.

Caso de Uso

Organizar endereços IP em grupos para exibição em interfaces de usuário ou para processamento em lotes, como em scripts de automação de rede.

Exemplo 1: Agrupando Endereços IP

{% for grupo in sflow_boxes|batch(2) %}  
Grupo Sflow {{ loop.index }}: {{ grupo | join(", ") }}  
{% endfor %}

Dados:

sflow_boxes:  
  - 10.180.0.1  
  - 10.180.0.2  
  - 10.180.0.3  
  - 10.180.0.4  
  - 10.180.0.5

Resultado:

Grupo Sflow 1: 10.180.0.1, 10.180.0.2  
Grupo Sflow 2: 10.180.0.3, 10.180.0.4  
Grupo Sflow 3: 10.180.0.5

Exemplo 2: Preenchendo Grupos Incompletos

{% for grupo in sflow_boxes|batch(3, fill_with='N/A') %}  
Grupo Sflow {{ loop.index }}: {{ grupo | join(", ") }}  
{% endfor %}

Resultado:

Grupo Sflow 1: 10.180.0.1, 10.180.0.2, 10.180.0.3  
Grupo Sflow 2: 10.180.0.4, 10.180.0.5, N/A

Definindo Valores Padrão com o Filtro default

Propósito

O filtro default retorna um valor padrão quando a variável está indefinida ou é avaliada como falsa (como None, 0, False ou string vazia). É útil para evitar erros em templates com dados ausentes.

Sintaxe

default(value, default_value='', boolean=False)

  • value: Variável a ser verificada.

  • default_value: Valor retornado se value for indefinido ou falso.

  • boolean (opcional): Se True, considera valores falsos como indefinidos.

Caso de Uso

Atribuir uma VLAN padrão a interfaces de rede quando nenhuma VLAN é especificada.

Exemplo

{% for intf in interfaces %}  
interface {{ intf.name }}  
  switchport mode access  
  switchport access vlan {{ intf.vlan | default('10') }}  
{% endfor %}

Dados:

interfaces:  
  - name: Ethernet1  
    vlan: 50  
  - name: Ethernet2  
  - name: Ethernet3  
    vlan: 60

Resultado:

interface Ethernet1  
  switchport mode access  
  switchport access vlan 50  
interface Ethernet2  
  switchport mode access  
  switchport access vlan 10  
interface Ethernet3  
  switchport mode access  
  switchport access vlan 60

Ordenando Dicionários com o Filtro dictsort

Propósito

O filtro dictsort ordena dicionários por chave ou valor, em ordem crescente ou decrescente, permitindo organizar dados não ordenados por padrão no Python.

Sintaxe

dictsort(value, case_sensitive=False, by='key', reverse=False)

  • value: Dicionário a ser ordenado.

  • case_sensitive: Se True, diferencia maiúsculas de minúsculas.

  • by: Ordenar por 'key' (padrão) ou 'value'.

  • reverse: Se True, ordena em ordem decrescente.

Caso de Uso

Organizar prefixos de rede por nome ou pares BGP por prioridade.

Exemplo 1: Ordenando por Chave

{% for pl_name, pl_lines in prefix_lists | dictsort %}  
ip prefix-list {{ pl_name }}  
  {{ pl_lines | join('\n  ') }}  
{% endfor %}

Dados:

prefix_lists:  
  pl-ntt-out:  
    - permit 10.0.0.0/23  
  pl-zayo-out:  
    - permit 10.0.1.0/24  
  pl-cogent-out:  
    - permit 10.0.0.0/24

Resultado:

ip prefix-list pl-cogent-out  
  permit 10.0.0.0/24  
ip prefix-list pl-ntt-out  
  permit 10.0.0.0/23  
ip prefix-list pl-zayo-out  
  permit 10.0.1.0/24

Exemplo 2: Ordenando por Valor (Prioridade)

Pares BGP por prioridade:  
{% for peer, priority in peer_priority | dictsort(by='value', reverse=true) %}  
  Par: {{ peer }}; Prioridade: {{ priority }}  
{% endfor %}

Dados:

peer_priority:  
  ntt: 200  
  zayo: 300  
  cogent: 100

Resultado:

Pares BGP por prioridade:  
  Par: zayo; Prioridade: 300  
  Par: ntt; Prioridade: 200  
  Par: cogent; Prioridade: 100

Convertendo para Números com os Filtros float e int

Filtro float

Propósito

Converte um valor em número de ponto flutuante, útil para operações numéricas ou comparações com strings numéricas.

Sintaxe

float(value, default=0.0)

  • value: Valor a ser convertido.

  • default: Valor retornado se a conversão falhar.

Caso de Uso

Comparar versões de software representadas como strings.

Exemplo

{% if eos_ver | float >= 4.22 %}  
Versão EOS {{ eos_ver }}: nova sintaxe de comando.  
{% else %}  
Versão EOS {{ eos_ver }}: sintaxe de comando antiga.  
{% endif %}

Dados:

eos_ver: "4.10"

Resultado:

Versão EOS 4.10: sintaxe de comando antiga.

Filtro int

Propósito

Converte um valor em número inteiro, com suporte para diferentes bases numéricas (como hexadecimal).

Sintaxe

int(value, default=0, base=10)

  • value: Valor a ser convertido.

  • default: Valor retornado se a conversão falhar.

  • base: Base numérica do valor (ex.: 16 para hexadecimal).

Caso de Uso

Converter um Ethertype hexadecimal para decimal.

Exemplo

Ethertype LLDP  
  Hex: {{ lldp_ethertype }}  
  Dec: {{ lldp_ethertype | int(base=16) }}

Dados:

lldp_ethertype: 88CC

Resultado:

Ethertype LLDP  
  Hex: 88CC  
  Dec: 35020

Agrupando por Atributo com o Filtro groupby

Propósito

Agrupa objetos de uma sequência com base em um atributo, ideal para relatórios ou organização de dados.

Sintaxe

groupby(value, attribute)

  • value: Sequência de objetos.

  • attribute: Atributo para agrupamento (suporta notação de ponto, ex.: interface.vlan).

Caso de Uso

Agrupar interfaces de rede por VLAN.

Exemplo

{% for vid, members in interfaces | groupby('vlan') %}  
Interfaces na VLAN {{ vid }}: {{ members | map(attribute='name') | join(", ") }}  
{% endfor %}

Dados:

interfaces:  
  - name: Ethernet1  
    vlan: 50  
  - name: Ethernet2  
    vlan: 50  
  - name: Ethernet3  
    vlan: 60

Resultado:

Interfaces na VLAN 50: Ethernet1, Ethernet2  
Interfaces na VLAN 60: Ethernet3

Concatenando Listas com o Filtro join

Propósito

Une elementos de uma sequência em uma única string, com um delimitador especificado.

Sintaxe

join(value, d='', attribute=None)

  • value: Sequência a ser unida.

  • d: Delimitador (padrão: string vazia).

  • attribute: Atributo a ser extraído, se os elementos forem objetos.

Caso de Uso

Exibir servidores de nomes em uma única linha.

Exemplo

ip name-server {{ name_servers | join(" ") }}

Dados:

name_servers:  
  - 1.1.1.1  
  - 8.8.8.8  
  - 9.9.9.9

Resultado:

ip name-server 1.1.1.1 8.8.8.8 9.9.9.9

Transformando Dados com o Filtro map

Propósito

Aplica um filtro ou extrai um atributo de todos os elementos de uma sequência.

Sintaxe

map(*args, **kwargs)

  • *args: Nome de um filtro (ex.: "lower") ou atributo a extrair (ex.: attribute='name').

Caso de Uso 1: Normalizando Nomes

Dispositivos:  
{{ devices | map('lower') | join('\n') }}

Dados:

devices:  
  - Core-rtr-warsaw-01  
  - DIST-Rtr-Prague-01

Resultado:

Dispositivos:  
core-rtr-warsaw-01  
dist-rtr-prague-01

Caso de Uso 2: Extraindo Atributos

Interfaces:  
{{ interfaces | map(attribute='name') | join('\n') }}

Dados:

interfaces:  
  - name: Ethernet1  
    mode: switched  
  - name: Ethernet2  
    mode: routed

Resultado:

Interfaces:  
Ethernet1  
Ethernet2

Filtrando Dados com os Filtros select e reject

Filtro select

Propósito

Mantém elementos de uma sequência que passam em um teste Jinja2.

Sintaxe

select(*args, **kwargs)

  • *args: Nome do teste (ex.: "gt").

  • **kwargs: Argumentos adicionais para o teste.

Caso de Uso

Listar apenas números de AS BGP privados (>64495).

Exemplo

AS BGP privados:  
{% for as_no in as_numbers | select('gt', 64495) %}  
{{ as_no }}  
{% endfor %}

Dados:

as_numbers:  
  - 1794  
  - 65203  
  - 65099

Resultado:

AS BGP privados:  
65203  
65099

Filtro reject

Propósito

Remove elementos de uma sequência que passam em um teste Jinja2.

Caso de Uso

Listar apenas números de AS BGP públicos (≤64495).

Exemplo

AS BGP públicos:  
{% for as_no in as_numbers | reject('gt', 64495) %}  
{{ as_no }}  
{% endfor %}

Resultado:

AS BGP públicos:  
1794

Filtrando Atributos com o Filtro rejectattr

Propósito

Remove objetos de uma sequência cujo atributo passa em um teste específico.

Sintaxe

rejectattr(*args, **kwargs)

  • *args: Atributo e nome do teste (ex.: "mode", "eq").

  • **kwargs: Argumentos adicionais.

Caso de Uso

Listar apenas interfaces roteadas, excluindo as no modo "switched".

Exemplo

Interfaces roteadas:  
{% for intf in interfaces | rejectattr('mode', 'eq', 'switched') %}  
{{ intf.name }}  
{% endfor %}

Dados:

interfaces:  
  - name: Ethernet1  
    mode: switched  
  - name: Ethernet2  
    mode: routed

Resultado:

Interfaces roteadas:  
Ethernet2

Convertendo para JSON com o Filtro tojson

Propósito

Converte uma estrutura de dados Python em uma string JSON, útil para APIs ou depuração.

Sintaxe

tojson(value, indent=None)

  • value: Estrutura de dados a ser convertida.

  • indent: Número de espaços para indentação.

Caso de Uso

Gerar uma representação JSON de interfaces para uma API.

Exemplo

{{ interfaces | tojson(indent=2) }}

Dados:

interfaces:  
  - name: Ethernet1  
    vlan: 50  
  - name: Ethernet2  
    vlan: 60

Resultado:

[
  {
    "name": "Ethernet1",
    "vlan": 50
  },
  {
    "name": "Ethernet2",
    "vlan": 60
  }
]

Extraindo Valores Únicos com o Filtro unique

Propósito

Retorna valores únicos de uma coleção, frequentemente usado com map para extrair atributos distintos.

Sintaxe

unique(value, case_sensitive=False, attribute=None)

  • value: Coleção de dados.

  • case_sensitive: Se True, diferencia maiúsculas de minúsculas.

  • attribute: Atributo para extrair valores únicos.

Caso de Uso

Listar VLANs de acesso únicas em uso.

Exemplo

VLANs em uso: {{ interfaces | map(attribute='vlan') | unique | join(", ") }}

Dados:

interfaces:  
  - name: Ethernet1  
    vlan: 50  
  - name: Ethernet2  
    vlan: 50  
  - name: Ethernet3  
    vlan: 60

Resultado:

VLANs em uso: 50, 60

Referências

0
Subscribe to my newsletter

Read articles from pDamasceno directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

pDamasceno
pDamasceno