<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Jinja2 Inputs YAML, JSON or Python dic in Controllers</title>
    <link>https://community.cisco.com/t5/controllers/jinja2-inputs-yaml-json-or-python-dic/m-p/4644621#M1089</link>
    <description>&lt;P&gt;Hello Jerems,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Using Json/Yaml or python dict for me will not offer a better controls. It depends on what you are trying to achieve.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For example, let's see you want to generate a configuration that you&amp;nbsp; have to push on 10 differents interface. You can&amp;nbsp; choose whatever you want but you will still be able to use a wrong interface name like "TOTO1/0/2".&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here an example&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;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 ==&amp;gt; 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 ==&amp;gt; You have just to add in the dict
data_to_render = {"interface_list":interface_list} 
print("Rendering second version", template.render(data_to_render))&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here the output that i got&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;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&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;You can also store your data in a json or yaml that you will load in your code then pass it to the template.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here an example to convert a python object to yaml or dict. In the example, i used a dict.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;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))&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The output that i got&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;Yaml :
 interface_list:
- TenGigE0/3/0/0
- TenGigE0/3/0/1
Json :
 {"interface_list": ["TenGigE0/3/0/0", "TenGigE0/3/0/1"]}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Tue, 05 Jul 2022 22:15:50 GMT</pubDate>
    <dc:creator>Nabsch</dc:creator>
    <dc:date>2022-07-05T22:15:50Z</dc:date>
    <item>
      <title>Jinja2 Inputs YAML, JSON or Python dic</title>
      <link>https://community.cisco.com/t5/controllers/jinja2-inputs-yaml-json-or-python-dic/m-p/4644293#M1088</link>
      <description>&lt;P&gt;Hi Guys,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Do you agree with this statement :&lt;/P&gt;&lt;P&gt;Does YAML or JSON offers better control on datas you pass to Jinja2 in opposition to a simple Python dictionary ?&lt;/P&gt;&lt;P&gt;While writing this question i realized that we could consider of coding this control in the python script itself (beside the dictionary creation).&lt;/P&gt;&lt;P&gt;Thanks for your answer !&lt;/P&gt;&lt;P&gt;Jerems&lt;/P&gt;</description>
      <pubDate>Tue, 05 Jul 2022 16:15:42 GMT</pubDate>
      <guid>https://community.cisco.com/t5/controllers/jinja2-inputs-yaml-json-or-python-dic/m-p/4644293#M1088</guid>
      <dc:creator>Jerems</dc:creator>
      <dc:date>2022-07-05T16:15:42Z</dc:date>
    </item>
    <item>
      <title>Re: Jinja2 Inputs YAML, JSON or Python dic</title>
      <link>https://community.cisco.com/t5/controllers/jinja2-inputs-yaml-json-or-python-dic/m-p/4644621#M1089</link>
      <description>&lt;P&gt;Hello Jerems,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Using Json/Yaml or python dict for me will not offer a better controls. It depends on what you are trying to achieve.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For example, let's see you want to generate a configuration that you&amp;nbsp; have to push on 10 differents interface. You can&amp;nbsp; choose whatever you want but you will still be able to use a wrong interface name like "TOTO1/0/2".&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here an example&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;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 ==&amp;gt; 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 ==&amp;gt; You have just to add in the dict
data_to_render = {"interface_list":interface_list} 
print("Rendering second version", template.render(data_to_render))&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here the output that i got&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;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&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;You can also store your data in a json or yaml that you will load in your code then pass it to the template.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here an example to convert a python object to yaml or dict. In the example, i used a dict.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;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))&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The output that i got&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;Yaml :
 interface_list:
- TenGigE0/3/0/0
- TenGigE0/3/0/1
Json :
 {"interface_list": ["TenGigE0/3/0/0", "TenGigE0/3/0/1"]}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 05 Jul 2022 22:15:50 GMT</pubDate>
      <guid>https://community.cisco.com/t5/controllers/jinja2-inputs-yaml-json-or-python-dic/m-p/4644621#M1089</guid>
      <dc:creator>Nabsch</dc:creator>
      <dc:date>2022-07-05T22:15:50Z</dc:date>
    </item>
    <item>
      <title>Re: Jinja2 Inputs YAML, JSON or Python dic</title>
      <link>https://community.cisco.com/t5/controllers/jinja2-inputs-yaml-json-or-python-dic/m-p/4644999#M1090</link>
      <description>&lt;DIV&gt;&lt;SPAN&gt;Hi&amp;nbsp;,&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;If I'm understanding the statement correctly, I'd have to say I do not agree.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;JSON and YAML are serialization formats or ways to save your programatic data structures (lists, dictionaries, and combinations thereof) &amp;nbsp;to files (that is how I think of them) so they can be saved to storage and then easily and quickly consumed by your scripts.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;At the end of the day you will need to convert your JSON or YAML file into a Python data structure. &amp;nbsp; Now, what is the best data structure for your Jinja2 templating? &amp;nbsp;That is a very interesting question.&lt;BR /&gt;&lt;BR /&gt;Over the years, I have found that a list of dictionaries works best.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;1. A list lets me put for loops in my templates and so if its one thing or more than one thing (list element), my template can handle it.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;2. A list of lists works of course but you have to remember what index for what value which is great when you are "in the zone" for your script but 6 months later its&amp;nbsp;not so great because at least for me, I don't remember.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;3. So a list of&amp;nbsp;dictionaries (lod&lt;/SPAN&gt;) I find works best. &amp;nbsp; I can still iterate over the elements (one or more) and I can call things out specifically by their keys making my template very readable.&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;I put together a little repo to play around.&lt;BR /&gt;&lt;A href="https://github.com/cldeluna/jinja2_example" target="_blank" rel="noopener"&gt;https://github.com/cldeluna/jinja2_example&lt;/A&gt;&lt;BR /&gt;&lt;BR /&gt;You have already seen an example of a list from&amp;nbsp;&lt;a href="https://community.cisco.com/t5/user/viewprofilepage/user-id/1258687"&gt;@Nabsch&lt;/a&gt;.. &amp;nbsp;Eventually you will want to do more (hence 1-3 above) so lets look at a list of lists:&lt;BR /&gt;&lt;PRE&gt;    payload_list = [
     ["5", "vlan5_1.1.1.0_24"],
     ["7", "vlan7_7.1.1.0_24"],
     ["10", "vlan10_10.1.1.0_24"],
    ]&lt;/PRE&gt;and its corresponding jinja2 template:&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;! Layer 2 Vlan Template
! using a List of Lists

{% for line in mylistvar %}
vlan {{ line[0] }}
  name {{ line[1] }}
{% endfor %}&lt;/PRE&gt;If your list has one item or many items you will get:&lt;BR /&gt;&lt;PRE&gt;--- 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&lt;/PRE&gt;&lt;/DIV&gt;&lt;DIV&gt;For something this simple thats just fine but I find this template serves me better when I have to come back to it a few months from now:&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;! Layer 2 Vlan Template
! using a List of Dictionaries for improved readability

{% for line in mylistvar %}
vlan {{ line['vlan'] }}
  name {{ line['name'] }}
{% endfor %}&lt;/PRE&gt;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.&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;In the little example script in the GitHub Repo&amp;nbsp;&lt;STRONG&gt;&lt;EM&gt;j2_payload_comparison.py&lt;/EM&gt;&lt;/STRONG&gt; I conclude with saving the list of dictionaries payload to a JSON file and reading it back in.&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;[
    {
        "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"
    }
]&lt;/PRE&gt;&lt;/DIV&gt;&lt;DIV&gt;JSON and YAML will let you save your Python data structures to a file and easily read those data structures back in&lt;STRONG&gt; as data structures&lt;/STRONG&gt;. &amp;nbsp;That is their value.&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;JSON vs YAML is of course another question. &amp;nbsp;I use YAML if I need to add comments and if I have to share the payload with others who are not very familiar with scripting because its a bit easier to read (less intimidating) if you have not been exposed to this.&lt;BR /&gt;Normally, if I've built out a configuration payload, I will save it to JSON so I have a machine readable snapshot of the payload I used to generate configs or whatever.&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;I will mention that for complicated templates, lets say a full configuration, I will build a dictionary of lists where the key is the config section, say "SVI" and the value of that key is a list of dictionaries holding the configuration data for all of the SVIs for that device.&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;Hopefully I've not made your head hurt too much!&lt;BR /&gt;&lt;BR /&gt;If I have, this little post about "&lt;A title="Decomposing Data Structures" href="https://gratuitous-arp.net/decomposing-complex-json-data-structures/" target="_blank" rel="noopener"&gt;Decomposing Data Structures&lt;/A&gt;" might help.&lt;BR /&gt;&lt;BR /&gt;Hope some of this is useful to you! &amp;nbsp;Happy Templating!&lt;/DIV&gt;</description>
      <pubDate>Wed, 06 Jul 2022 12:50:38 GMT</pubDate>
      <guid>https://community.cisco.com/t5/controllers/jinja2-inputs-yaml-json-or-python-dic/m-p/4644999#M1090</guid>
      <dc:creator>Claudia de Luna</dc:creator>
      <dc:date>2022-07-06T12:50:38Z</dc:date>
    </item>
    <item>
      <title>Re: Jinja2 Inputs YAML, JSON or Python dic</title>
      <link>https://community.cisco.com/t5/controllers/jinja2-inputs-yaml-json-or-python-dic/m-p/4645033#M1091</link>
      <description>&lt;P&gt;Thousand thanks to both of you !&lt;/P&gt;&lt;P&gt;Cheers,&lt;/P&gt;&lt;P&gt;Jerems&lt;/P&gt;</description>
      <pubDate>Wed, 06 Jul 2022 13:49:43 GMT</pubDate>
      <guid>https://community.cisco.com/t5/controllers/jinja2-inputs-yaml-json-or-python-dic/m-p/4645033#M1091</guid>
      <dc:creator>Jerems</dc:creator>
      <dc:date>2022-07-06T13:49:43Z</dc:date>
    </item>
  </channel>
</rss>

