07-05-2022 09:15 AM
Hi Guys,
Do you agree with this statement :
Does YAML or JSON offers better control on datas you pass to Jinja2 in opposition to a simple Python dictionary ?
While writing this question i realized that we could consider of coding this control in the python script itself (beside the dictionary creation).
Thanks for your answer !
Jerems
Solved! Go to Solution.
07-05-2022 02:34 PM - edited 07-05-2022 03:15 PM
Hello Jerems,
Using Json/Yaml or python dict for me will not offer a better controls. It depends on what you are trying to achieve.
For example, let's see you want to generate a configuration that you have to push on 10 differents interface. You can choose whatever you want but you will still be able to use a wrong interface name like "TOTO1/0/2".
Jinja is a template engine that allow us to use some data as input and a template in order to render the final document that you want to get.
The question is you have to think about what you are trying to modelize. Is it a list of string for example or a dict or a list of dictionnary.
For example ,if you want to push the same configuration in x interfaces . The best way would be a list . So then in order to use this list you can do it using two way in your python using the list directly or use a dict that contains the list.
Here an example
from jinja2 import Template
template_str = """
{% for intf in interface_list %}
interface {{ intf }}
mtu 4000
{% endfor %}
"""
template = Template(template_str)
interface_list = ["TenGigE0/3/0/0","TenGigE0/3/0/1"]
# if you want to modify more element ==> You have add to , variable_name = value and so on . So if you are using a lot of variable
print("Rendering first version", template.render(interface_list=interface_list))
# if you want to modify more element ==> You have just to add in the dict
data_to_render = {"interface_list":interface_list}
print("Rendering second version", template.render(data_to_render))
Here the output that i got
Rendering first version
interface TenGigE0/3/0/0
mtu 4000
interface TenGigE0/3/0/1
mtu 4000
Rendering second version
interface TenGigE0/3/0/0
mtu 4000
interface TenGigE0/3/0/1
mtu 4000
You can also store your data in a json or yaml that you will load in your code then pass it to the template.
Here an example to convert a python object to yaml or dict. In the example, i used a dict.
import json
import yaml
interface_list = ["TenGigE0/3/0/0","TenGigE0/3/0/1"]
data_to_render = {"interface_list":interface_list}
print("Yaml : \n", yaml.dump(data_to_render))
print("Json : \n", json.dumps(data_to_render))
The output that i got
Yaml :
interface_list:
- TenGigE0/3/0/0
- TenGigE0/3/0/1
Json :
{"interface_list": ["TenGigE0/3/0/0", "TenGigE0/3/0/1"]}
07-06-2022 05:50 AM
payload_list = [ ["5", "vlan5_1.1.1.0_24"], ["7", "vlan7_7.1.1.0_24"], ["10", "vlan10_10.1.1.0_24"], ]and its corresponding jinja2 template:
! Layer 2 Vlan Template ! using a List of Lists {% for line in mylistvar %} vlan {{ line[0] }} name {{ line[1] }} {% endfor %}If your list has one item or many items you will get:
--- Template Rendering with a List of Lists Configuration Payload ! Layer 2 Vlan Template ! using a List of Lists vlan 5 name vlan5_1.1.1.0_24 vlan 7 name vlan7_7.1.1.0_24 vlan 10 name vlan10_10.1.1.0_24
! Layer 2 Vlan Template ! using a List of Dictionaries for improved readability {% for line in mylistvar %} vlan {{ line['vlan'] }} name {{ line['name'] }} {% endfor %}This not an idea example because of its simplicity but I hope you can see that given a far more complicated configuration referring to values by their keys makes for a much more readable template and will shortcut the inevitable time spent trying to figure out what you did 6 months ago.
[ { "vlan": "5", "name": "vlan5_1.1.1.0_24" }, { "vlan": "7", "name": "vlan7_7.1.1.0_24" }, { "vlan": "10", "name": "vlan10_10.1.1.0_24" } ]
07-05-2022 02:34 PM - edited 07-05-2022 03:15 PM
Hello Jerems,
Using Json/Yaml or python dict for me will not offer a better controls. It depends on what you are trying to achieve.
For example, let's see you want to generate a configuration that you have to push on 10 differents interface. You can choose whatever you want but you will still be able to use a wrong interface name like "TOTO1/0/2".
Jinja is a template engine that allow us to use some data as input and a template in order to render the final document that you want to get.
The question is you have to think about what you are trying to modelize. Is it a list of string for example or a dict or a list of dictionnary.
For example ,if you want to push the same configuration in x interfaces . The best way would be a list . So then in order to use this list you can do it using two way in your python using the list directly or use a dict that contains the list.
Here an example
from jinja2 import Template
template_str = """
{% for intf in interface_list %}
interface {{ intf }}
mtu 4000
{% endfor %}
"""
template = Template(template_str)
interface_list = ["TenGigE0/3/0/0","TenGigE0/3/0/1"]
# if you want to modify more element ==> You have add to , variable_name = value and so on . So if you are using a lot of variable
print("Rendering first version", template.render(interface_list=interface_list))
# if you want to modify more element ==> You have just to add in the dict
data_to_render = {"interface_list":interface_list}
print("Rendering second version", template.render(data_to_render))
Here the output that i got
Rendering first version
interface TenGigE0/3/0/0
mtu 4000
interface TenGigE0/3/0/1
mtu 4000
Rendering second version
interface TenGigE0/3/0/0
mtu 4000
interface TenGigE0/3/0/1
mtu 4000
You can also store your data in a json or yaml that you will load in your code then pass it to the template.
Here an example to convert a python object to yaml or dict. In the example, i used a dict.
import json
import yaml
interface_list = ["TenGigE0/3/0/0","TenGigE0/3/0/1"]
data_to_render = {"interface_list":interface_list}
print("Yaml : \n", yaml.dump(data_to_render))
print("Json : \n", json.dumps(data_to_render))
The output that i got
Yaml :
interface_list:
- TenGigE0/3/0/0
- TenGigE0/3/0/1
Json :
{"interface_list": ["TenGigE0/3/0/0", "TenGigE0/3/0/1"]}
07-06-2022 05:50 AM
payload_list = [ ["5", "vlan5_1.1.1.0_24"], ["7", "vlan7_7.1.1.0_24"], ["10", "vlan10_10.1.1.0_24"], ]and its corresponding jinja2 template:
! Layer 2 Vlan Template ! using a List of Lists {% for line in mylistvar %} vlan {{ line[0] }} name {{ line[1] }} {% endfor %}If your list has one item or many items you will get:
--- Template Rendering with a List of Lists Configuration Payload ! Layer 2 Vlan Template ! using a List of Lists vlan 5 name vlan5_1.1.1.0_24 vlan 7 name vlan7_7.1.1.0_24 vlan 10 name vlan10_10.1.1.0_24
! Layer 2 Vlan Template ! using a List of Dictionaries for improved readability {% for line in mylistvar %} vlan {{ line['vlan'] }} name {{ line['name'] }} {% endfor %}This not an idea example because of its simplicity but I hope you can see that given a far more complicated configuration referring to values by their keys makes for a much more readable template and will shortcut the inevitable time spent trying to figure out what you did 6 months ago.
[ { "vlan": "5", "name": "vlan5_1.1.1.0_24" }, { "vlan": "7", "name": "vlan7_7.1.1.0_24" }, { "vlan": "10", "name": "vlan10_10.1.1.0_24" } ]
07-06-2022 06:49 AM
Thousand thanks to both of you !
Cheers,
Jerems
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide