Config ACI
Requests

To this point you have used the request library to peform read operations against the ACI fabric. In this section we are going to perform writes to the fabric. There are many ways to get data that is needed to be pushed into the fabric, yet one seems to be popular amongst network administrators and that is the CSV file or other spreadsheet formats like Excel.

CSV format is popular amongst non-developers since all the data is stored in a simple text file and can be edited easily with many spreasheet software packages like Excel, Numbers and more. It also allows for management inside of a GIT repository due to it's text format. It is still not the best method of structured data, but in a lot of cases it is the most practical for network administrators. The primary impracticality of CSV is that delimiters for fields are defined by the same ASCII structures and can be easily broken by specific characters showing up by mistake in user input. This is why JSON and XML are more popular in the developer community.

Another option in such a situation is to use the excel format, but since it is a binary format it is very bad for version control and is not recommended for use in a development environment. Since the excel format is internally XML, characters inserted by mistake don't have the potential to break structure. Python has libraries like openpyxl that can be used to read and write excel files and a potential solution for data ingestion into these scripts but would have live outside source control like GIT. For the purpose of this lab we will show you how to use CSV files.

Python includes a CSV library that can be used to read and write CSV files. This was added as part of PEP305.

Step 1 - Create python file for CSV read

In the IDE you will create a new file in:


And name the file csv_read.py

Step 2 - Construct the base of the python file

In the IDE you will create a new file in:


import requests, json, os, re, csv, argparse
from aci_auth import get_aci_token

from rich import print_json
from rich.console import Console
from rich.table import Table



if __name__ == "__main__":
    console = Console()

Step 3 - Create function for CSV file read

In this file you are going to create a function that will read the CSV file and return the data. To accomplish this we will be using the csv.DictReader class. This class will read the CSV file and return a list of dictionaries. The keys of the dictionaries will be the column names of the CSV file. This is a very useful way to read CSV files since it allows you to reference the data by the column name instead of the index of the column. This makes the code more readable and easier to maintain.

First part is going to defiune two separate variables csv_data and csv_columns. The purpose of this is that we will separate the columns to print into a nice table and then the csv_data will be returned to the calling function. We are taking advantage of the csv.DictReader since it returns a python object that we can iterate over and get the data from the CSV file easily.

We also show you some best practices to include in your functions for docstrings that will help you and others understand what the function does. This is a good practice to get into as it will help you in the future when you come back to the code and need to understand what the function does.


import requests, json, os, re, csv, argparse
from aci_auth import get_aci_token

from rich import print_json
from rich.console import Console
from rich.table import Table

def read_csv_file(file_name):
    """
    This function reads the CSV file and returns a list of dictionaries from the 
    CSV data. It also prints a table on the console, to display what it has read.

    Paramters:
    file_name (str): Name of the CSV file name
    Returns:
    list: List of dictionaries from CSV file.
    """
    csv_data = []
    csv_columns = []
    with open(file_name, mode='r') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        if csv_reader:
            csv_columns = list(csv_reader.fieldnames)
            for row in csv_reader:
                csv_data.append(row)
        else:
            console.print_exception("CSV Data not read")
            exit()

if __name__ == "__main__":
    console = Console()

Now you are going to use this data to create a nice table using the Rich library. This will allow you to view the data that is about to be sent to the ACI fabric. For your own usage it might be useful to you to see in an easy to comprehend format what is about to be pushed into the fabric.


import requests, json, os, re, csv, argparse
from aci_auth import get_aci_token

from rich import print_json
from rich.console import Console
from rich.table import Table

def read_csv_file(file_name):
    """
    This function reads the CSV file and returns a list of dictionaries from the 
    CSV data. It also prints a table on the console, to display what it has read.

    Paramters:
    file_name (str): Name of the CSV file name
    Returns:
    list: List of dictionaries from CSV file.s
    """
    csv_data = []
    csv_columns = []
    with open(file_name, mode='r') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        if csv_reader:
            csv_columns = list(csv_reader.fieldnames)
            for row in csv_reader:
                csv_data.append(row)
        else:
            console.print_exception("CSV Data not read")
            exit()

    table = Table(title="CSV Data")
    for column in csv_columns:
        table.add_column(column)
    for row in csv_data:
        table_row=[]
        for column in csv_columns:
            table_row.append(row[column])
        table.add_row(*table_row)
    console = Console()
    console.print(table)
    return csv_data

if __name__ == "__main__":
    console = Console()

Step 4 - Add argparse to enter script invokation parameters

Now that the code to read the CSV is done, you will be adding the argparse library to allow you to pass the CSV file name as a parameter to the script. This will allow you to run the script from the command line when we invoke this script directly.


import requests, json, os, re, csv, argparse
from aci_auth import get_aci_token

from rich import print_json
from rich.console import Console
from rich.table import Table

def read_csv_file(file_name):
    """
    This function reads the CSV file and returns a list of dictionaries from the 
    CSV data. It also prints a table on the console, to display what it has read.

    Paramters:
    file_name (str): Name of the CSV file name
    Returns:
    list: List of dictionaries from CSV file.s
    """
    csv_data = []
    csv_columns = []
    with open(file_name, mode='r') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        if csv_reader:
            csv_columns = list(csv_reader.fieldnames)
            for row in csv_reader:
                csv_data.append(row)
        else:
            console.print_exception("CSV Data not read")
            exit()

    table = Table(title="CSV Data")
    for column in csv_columns:
        table.add_column(column)
    for row in csv_data:
        table_row=[]
        for column in csv_columns:
            table_row.append(row[column])
        table.add_row(*table_row)
    console = Console()
    console.print(table)
    return csv_data

if __name__ == "__main__":
    console = Console()

    parser = argparse.ArgumentParser(description='Read CSV file and print data')
    parser.add_argument('-c', '--csvfile', required=True, help='Name of the CSV file')
    args = vars(parser.parse_args())

Step 5 - Verify CSV file and parse CSV data

The final part of the script is to verify that the CSV file exists and then call the function to read the CSV file. If the file does not exist, the script will print an error message and exit. This is a good practice to ensure that the script does not continue if the file does not exist.


import requests, json, os, re, csv, argparse
from aci_auth import get_aci_token

from rich import print_json
from rich.console import Console
from rich.table import Table

def read_csv_file(file_name):
    """
    This function reads the CSV file and returns a list of dictionaries from the 
    CSV data. It also prints a table on the console, to display what it has read.

    Paramters:
    file_name (str): Name of the CSV file name
    Returns:
    list: List of dictionaries from CSV file.s
    """
    csv_data = []
    csv_columns = []
    with open(file_name, mode='r') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        if csv_reader:
            csv_columns = list(csv_reader.fieldnames)
            for row in csv_reader:
                csv_data.append(row)
        else:
            console.print_exception("CSV Data not read")
            exit()

    table = Table(title="CSV Data")
    for column in csv_columns:
        table.add_column(column)
    for row in csv_data:
        table_row=[]
        for column in csv_columns:
            table_row.append(row[column])
        table.add_row(*table_row)
    console = Console()
    console.print(table)
    return csv_data

if __name__ == "__main__":
    console = Console()

    parser = argparse.ArgumentParser(description='Read CSV file and print data')
    parser.add_argument('-c', '--csvfile', required=True, help='Name of the CSV file')
    args = vars(parser.parse_args())

    if os.path.isfile(args['csvfile']):
        csv_data = read_csv_file(args['csvfile'])
    else:
        console.print(f"[bold red]File {args['csvfile']} does not exist")
        exit()

Step 6 - Test the CSV read

For this lab we have created a populated CSV file that you can use to test the CSV read function. The file is located at POD04_aci.csv. You can run the script with the following command:


python csv_read.py -c POD04_aci.csv

Which should have an output similar to the following:


                           CSV Data                            
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━━┓
┃ tenant       ┃ app_profile ┃ epg ┃ switch ┃ port   ┃ domain ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━━┩

With the completion of the CSV read, you will now focus on completing a CSV write to the ACI fabric. The CSV write part of this lab is going to now utilize the capability that we created to write to the ACI fabric. The previous code showed you how to read the CSV file data.