Showing results for 
Search instead for 
Did you mean: 

Five APIC-EM API to improve network engineer productivity – part 5

Cisco Employee

Welcome to part 4 of the "APIC-EM API productivity series" for network engineers getting started in API and scripting.

Earlier blogs on APIC-EM covered

  1. /network-device – all attributes of network-devices
  2. /interface/network-device – all interfaces  (and hosts) on a network-device e.g. a switch
  3. /license-info - all licencing information for a network-device
  4. /host?hostMac and /host?hostIP – parameterised search for an host by either MAC address or IP address.

By this stage of the blog series, I am going to assume you are familiar with swagger (API documentation tool) and the location of the github repository where I have shared the code samples (the GitHub location is at the bottom of the post).

#5 path trace

Path trace traces a path through the network from host A to host B.  You can also provide TCP/UDP port information and the controller will look at points in the network where there is multiple paths and let you know which of the possible paths will be used for this flow.

path trace.png

In addition you can get device and interface statistics along the active path.  In release 1.2 this was been expanded to include performance monitor stats and ACL tracing.


It is also possible to run a path trace through swagger.  It is a little more complex than earlier examples as there are three steps involved.

  The first big difference is that this requires a POST.  We send data to APIC-EM to describe the path trace parameters, in this case just source and dest IP along with the "run stats commands". I am going to use the payload from the sample python script in the next section.  You will need to paste in the following text into the text box shown in a red rectangle.

{"destIP": "", "inclusions": ["INTERFACE-STATS", "DEVICE-STATS"], "sourceIP": "", "periodicRefresh": false}

swagger 1.png

Then press "Try it Out"


Notice the "taskId" 7cde3eee-17fd-40e5-b339-4ae365ad1037, this will be unique for each instance of path trace.  This task needs to be polled until it completes.  It should only take a few seconds.

To poll the task, use the /task/{taskId} GET request.  Paste in the taskId (yours will be different), and press "Try it out"


You will get a result similar to the following:


This shows the task is complete (it has an endTime), and has no errors (isError is false).  The flowAnalysisId is in the "progress" attribute. The final step is to GET /flow-analysis/{flowAnalysisId}.


Use the flowAnalysisId from the task (yours will be different, unique to your system).  Press "Try it out" and you will see the output from the request.


NOTE:  You will notice that the flowAnalysisId returned by the task, is the same one that was returned by the initial POST in step #1. You are probably asking "Why not just poll the flowAnalysisId"?  You are correct, you could do that in this case. The reason for showing you is, this is the general pattern that POST/PUT/DELETE calls use on APIC-EM.  It is good to understand how it works for other use cases.


All of these steps can be automated in a script.

The script requires two arguments at a minimum.   The source and destination IP address of the hosts. NOTE: these can also be addresses of interfaces on network-devices as well.  It is optional to supply source and destination ports as well as ask for statistics (--stats)

./ --srcip --dstip --stats

{"destIP": "", "inclusions": ["INTERFACE-STATS", "DEVICE-STATS"], "sourceIP": "", "periodicRefresh": false}

Waiting for Task db190241-ed5b-4868-9be6-d8ec70c6cc24

Task=db190241-ed5b-4868-9be6-d8ec70c6cc24 has not completed yet. Sleeping 2 seconds...

Task=db190241-ed5b-4868-9be6-d8ec70c6cc24 has not completed yet. Sleeping 2 seconds...

Task=db190241-ed5b-4868-9be6-d8ec70c6cc24 has not completed yet. Sleeping 2 seconds...


  "detailedStatus": {

    "aclTraceCalculation": "SUCCESS"


  "lastUpdate": "Sun Feb 19 15:14:27 UTC 2017",

  "networkElementsInfo": [


      "ip": "",

      "type": "wireless",

      "id": "48cdeb9b-b412-491e-a80c-7ec5bbe98167",

      "linkInformationSource": "Switched"



      "name": "AP7081.059f.19ca",

      "ip": "",

      "role": "ACCESS",

      "linkInformationSource": "Switched",

      "type": "Unified AP",

      "id": "cd6d9b24-839b-4d58-adfe-3fdf781e1782",

      "tunnels": [

        "CAPWAP Tunnel"





The output is quite verbose, as it shows the complete JSON payload as well as a summary.  This shows the summary section

./ --srcip --dstip --stats

{"destIP": "", "inclusions": ["INTERFACE-STATS", "DEVICE-STATS"], "sourceIP": "", "periodicRefresh": false}

Waiting for Task db190241-ed5b-4868-9be6-d8ec70c6cc24

Task=db190241-ed5b-4868-9be6-d8ec70c6cc24 has not completed yet. Sleeping 2 seconds...

Task=db190241-ed5b-4868-9be6-d8ec70c6cc24 has not completed yet. Sleeping 2 seconds...

Task=db190241-ed5b-4868-9be6-d8ec70c6cc24 has not completed yet. Sleeping 2 seconds...



  AP7081.059f.19ca:    Switched


    CAMPUS-Access1:    Switched



      CAMPUS-Dist1:   Switched



   Campus-WLC-5508:    Switched



      CAMPUS-Dist1:   ECMP



      CAMPUS-Core2:    ECMP



    CAMPUS-Router2:     OSPF


           UNKNOWN:UNKNOWN      NetFlow


    Branch-Router2:     CONNECTED



    Branch-Access1:    Switched


Looking at the code

There are three API calls used in this code.

  1. 1) "/flow-analysis" -   a POST API call with a payload containing source and destination IP addresses (at a minimum).  Returns a taskId used in the following step.
  2. 2) "/task/<taskId>"  GET - All POST/PUT/DELETE API calls are asynchronous, meaning that you are given a taskId when you perform these operations, and you need to poll the taskId to find out what happened (and if the task is complete).  The "progress" attribute will contain the UUID of the resource that has been created  (a flowAnalysisId) of the path-trace response.
  3. 3) "/flow-analysis/<flowAnalysisId>" GET  - returns the path-trace information.  The flowAnalysisId is stored in the "progress" attribute of the task.

As in blog #4, the "argparse" library is used to parse the command line options.

The main work is done in the following function.  Not the function post_and_wait, really just waits for the task to complete.   The post_and_wait function polls /task to make sure the task has complete.  In the example above, it was polled a total of 4 times, 2 seconds apart.

def create_path_trace(args):

    data = {

        "sourceIP" : args.srcip,

        "destIP" : args.dstip,

        "periodicRefresh" : False


    if  args.srcport is not None:

        data["sourcePort"] =  args.srcport

    if  args.dstport is not None:

        data["destPort"] =  args.dstport

    if args.stats:

        data["inclusions"]  = ["INTERFACE-STATS","DEVICE-STATS"]


    result = post_and_wait("flow-analysis", data)

    return result['progress']

The next step is to print it out.  There are lots of options here in terms of formatting, I have just dumped the raw JSON, as well as attempted to pretty print a little.

def display_path(pathid):

    path_data = get_url("flow-analysis/%s" % pathid)['response']
    for network_element in path_data['networkElementsInfo']:
        element_type = None
        if 'type' in network_element:
            element_type = network_element['type']


What Next?

This is the final blog in the series.  This blog covered  /flow-analysis, an API to do a path trace between hosts on the network.  /flow-analysis also provides stats on interfaces, QoS, Perfmon and ACL trace.

Take a look at my blog index for other related topics.

In the meantime, if you would like to learn more about APIC-EM, you could visit Cisco Devnet.  All of the code samples can be found in this Github repository.

Thanks for reading



This is terrific documentation, Adam - thanks! 

I'm looking to take the output of the flow-analysis API and graph it in Django, possibly using django-netjsongraph.  Have you had any experience with this or similar graphing tools?

My ultimate goal would be to color the devices red, yellow or green based on CPU and RAM util and color the links based on packetLossPercentage and possibly bandwidth utilization percentage (assuming I can determine link speed somehow to compare it to inputRatebps and outputRatebps.

As a bonus, I'd want to be able to hover over devices and have them show CPU/memory states and hover over links and have them show established link speed, bandwith util (input and output) and error percentage.  While I'm dreaming, maybe the links get thicker as their link speed gets higher.

Have you seen anything capable of this sort of graphing?  I'd like to be able to give my application teams and incident managers access to path trace but not via the APIC-EM console, if at all possible.  It'd be easier for them if I could just give them an API call via Django (and then into APIC-EM) from their existing monitoring tools.  (Yeah, I could let them make calls directly into APIC-EM's API but I don't want to expose the entire API to them for fear they might play around and do some damage.)

Cisco Employee

Thanks Scott

for the feedback, I really appreciate it.  Nice to see that this was of some use.

I have looked a little at graphing tools, but not recently.

Will try to find some time to take a look.

I like the idea of rendering this in a more interesting (graphical) way, that has come up a few other times too.


BTW, not sure if you noticed, but there are a heap of stats available as part of the path-trace too.

Content for Community-Ad

This widget could not be displayed.