In this lesson, we will cover:

  • What is Dq?
  • The different Dq usages and installation.
  • The common Dq methods.
  • Using Dq for real-world use cases such as querying IP to MAC, OSPF Neighbor validation and interface errors.

The scripts and code for this lesson can be found within the pyATS repo under the directory: 004_libraries/dq/.

What is Dq?

Dq (Dictionary query) is a PyATS/Genie Python library that provides an easy and simplistic way to query Python dictionaries. It avoids much of the heavy lifting required when dealing with large nested dictionaries such as iteration, looping and specifying the various keys to get to the point in the data structure to collect the value of interest.

For example, let’s say we have obtained the output of show ip ospf neighbor detail via a pyATS Parse and now want to work with the data in Python.

ospf_output = device.parse("show ip ospf neighbor detail")
pprint(ospf_output)
===
{
    "vrf": {
        "default": {
            "address_family": {
                "ipv4": {
                    "instance": {
                        "1": {
                            "areas": {
                                "0.0.0.0": {
                                    "interfaces": {
                                        "GigabitEthernet0/0": {
                                            "neighbors": {
                                                "3.3.3.3": {
                                                    "address": "10.1.1.2",
                                                    "bdr_ip_addr": "10.1.1.2",
                                                    "dbd_options": "0x42",
                                                    "dead_timer": "00:00:35",
                                                    "dr_ip_addr": "10.1.1.1",
                                                    "first": "0x0(0)/0x0(0)/0x0(0)",
                                                    "hello_options": "0x2",
                                                    "index": "1/6/6,",
                                                    "interface": "GigabitEthernet0/0",
                                                    "neighbor_router_id": "3.3.3.3",
                                                    "next": "0x0(0)/0x0(0)/0x0(0)",
                                                    "priority": 1,
                                                    "state": "full",
                                                    "statistics": {
                                                        "last_retrans_max_scan_length": 0,
                                                        "last_retrans_max_scan_time_msec": 0,
                                                        "last_retrans_scan_length": 0,
                                                        "last_retrans_scan_time_msec": 0,
                                                        "nbr_event_count": 6,
                                                        "nbr_retrans_qlen": 0,
                                                        "total_retransmission": 0,
                                                    },
                                                    "uptime": "7w1d",
                                                }
                                            }
                                        },
…

To even get to the interface keys, we would need to perform something along the lines of:

ospf_output['vrf']['default']['address_family']['ipv4']['instance']['1']['areas']
===
['0.0.0.0']['interfaces'].keys()
dict_keys(['GigabitEthernet0/5', 'GigabitEthernet0/4', 'GigabitEthernet0/3', 'GigabitEthernet0/2', 'GigabitEthernet0/1', 'GigabitEthernet0/0'])

I think you can now see the problem! To perform this in Dq we would simply perform the following.

ospf_output.q.get_values('interfaces')
===
['GigabitEthernet0/5', 'GigabitEthernet0/4', 'GigabitEthernet0/3', 'GigabitEthernet0/2', 'GigabitEthernet0/1', 'GigabitEthernet0/0']

Let’s dive into the various options within Dq. Before we do, let's load the testbed file and connect to one of our devices. Like so:

$ export $(cat .env)
$ pyats shell --testbed-file testbeds/testbed.yml 
from pprint import pprint

device = testbed.devices["spine1-nxos"]
device.connect()
Ready to Master Network Automation? Start Your Journey Today!
Our membership provides:
  • Full deep-dive course library (inc. Batfish, pyATS, Netmiko)
  • Code repositories inc. full course code, scripts and examples
  • 24x7 multi-vendor labs (Arista, Cisco, Juniper)
  • Private online community
  • Live monthly tech sessions
  • Access to tech session library

Join Now ➜
Close You've successfully subscribed to Packet Coders.
Close Success! Your account is fully activated, you now have access to all content.
Close Welcome back! You've successfully signed in.
Close Nearly there! To activate your account, please click the link in the email we just sent you.