Issue using MERAKI APIs /networks/{network_id}/devices and /organizations/{org_id}/devices/statuses

ricardo-rojas
Conversationalist

Issue using MERAKI APIs /networks/{network_id}/devices and /organizations/{org_id}/devices/statuses

Hi all,

 

I have an issue that looks like a bug, when I use any of these two URLs I hit an error trying to get the key "lanIp" others work just fine "mac", "serial".

URL1:  {base_url}/networks/{network_id}/devices

 URL2: {base_url}/organizations/{org_id}/devices/statuses

 

Example1: 

[ERROR] 2023-04-19T18:22:38.905Z 85dfc7d6-c3af-4ade-84b0-24765ba1b00d Exception on / [POST]
Traceback (most recent call last):
File "/var/task/flask/app.py", line 2528, in wsgi_app
response = self.full_dispatch_request()
File "/var/task/flask/app.py", line 1825, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/var/task/flask/app.py", line 1823, in full_dispatch_request
rv = self.dispatch_request()
File "/var/task/flask/app.py", line 1799, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/var/task/c****.py", line 136, in index
msg_reply += f"\n Modelo: {devices['model']} Serial: {devices['serial']} IP: {devices['lanIp']} mac: {devices['mac']}"
KeyError: 'lanIp'

 

Example2: Making a small change, it still doesn't work using key "lanIp" but it works Ok with others like "serial", "mac", etc.

[ERROR] 2023-04-19T18:29:20.123Z 1714224b-b550-43c7-a11b-cd34e4a3408b Exception on / [POST]
Traceback (most recent call last):
File "/var/task/flask/app.py", line 2528, in wsgi_app
response = self.full_dispatch_request()
File "/var/task/flask/app.py", line 1825, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/var/task/flask/app.py", line 1823, in full_dispatch_request
rv = self.dispatch_request()
File "/var/task/flask/app.py", line 1799, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/var/task/c****.py", line 136, in index
msg_reply += f"\n{devices['lanIp']}"
KeyError: 'lanIp'

 

This is the API info and I saw I received the right response, however, I receive the errors shown.

 

https://developer.cisco.com/meraki/api-v1/#!get-network-devices

 

[
    {
        "name": "My AP",
        "lat": 37.4180951010362,
        "lng": -122.098531723022,
        "serial": "Q234-ABCD-5678",
        "mac": "00:11:22:33:44:55",
        "model": "MR34",
        "address": "1600 Pennsylvania Ave",
        "notes": "My AP's note",
        "lanIp": "1.2.3.4",
        "tags": " recently-added ",
        "networkId": "N_24329156",
        "beaconIdParams": {
            "uuid": "00000000-0000-0000-0000-000000000000",
            "major": 5,
            "minor": 3
        },
        "firmware": "wireless-25-14",
        "floorPlanId": "g_1234567"
    }
]

 

https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-statuses

 

{
    "name": "My AP",
    "serial": "Q234-ABCD-5678",
    "mac": "00:11:22:33:44:55",
    "publicIp": "123.123.123.1",
    "networkId": "N_24329156",
    "status": "online",
    "lastReportedAt": "2018-02-11T00:00:00.090210Z",
    "lanIp": "1.2.3.4",
    "gateway": "1.2.3.5",
    "ipType": "dhcp",
    "primaryDns": "8.8.8.8",
    "secondaryDns": "8.8.4.4",
    "productType": "wireless",
    "components": { "powerSupplies": [] },
    "model": "MR34",
    "tags": [ "tag1", "tag2" ]
}

 

Thanks.

 

 

 

 

3 Replies 3
mforman
Here to help

Hi ricardo-rojas,


I use both of these api requests frequently without fail.

 

One thing I will mention, if the device has never been online regardless of its configuration, the value for the key 'lanIp' will be None and give you the KeyError. I believe the same to be true if a device as been down for an extended period of time as well, though I'm not 100% positive about that.


Typically, when I'm trying to get that specific value from the key ['lanIp'] it is an indicator for me that the device is either down or has yet to be provisioned and I create an exception KeyError handler for that situation.

 

This is not the case for the ['serial'] or ['mac'] keys, they will report those values regardless to up/down(online/offline) status.

 

Add a "try:" and "except KeyError:" and have the exception print the whole devices dictionary just to see if that key is giving you a value of None.

 

That's my best guess as to what may be happening with the information you provided.

 

-mforman

 

 

 

Hi mforman,

 

Thank you for your comments, actually if a device is down or not provisioned that's not a reason for the code to break (receive the error message), when a device is down or not provisioned the value is None.

I usually use the "try" and "except" and also "finally", but I did'nt think it was neccesary in this case.

 

I recently found the cause of this issue and the reason is because the info in Meraki APIs website is not accurate, like everyone can check for 

https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-statuses

https://developer.cisco.com/meraki/api-v1/#!get-network-devices

It is indicate in schema definition and the example body that we should receive the key "lanIp", well, that's not true because if the device is a firewall for example we receive:

 

{'lat': -12.*, 'lng': -76.*, 'address': '****', 'serial': 'Q2****', 'mac': '0****', 'wan1Ip': None, 'wan2Ip': '***', 'tags': ['Firewall'],
'url': 'https://n579.meraki**', 'networkId': '***', 'name': 'MX**', 'model': 'MX**', 'firmware': 'wired-18-1-06', 'floorPlanId': None}

 

So there is not a key "lanIp" when the device is a firewall, that's was the root cause.

 

Appreciate your help, see you.

 

ricardo-rojas

 

Not sure how you're running your script or exact end goal.  Assuming it's python, if you bring in Pandas, you can easily take the List of data you receive from the API call, covert that to a pandas dataframe and export that to an excel sheet.  Then you don't have to define each specific returned value as a variable and account for each of them if you are just looking to get data exported quickly into a usable format.  3 lines of code.

 

from datetime import datetime
import pandas as pd
import meraki

<some code not shown for example>

        try:
            devicestatuses = dashboard.organizations.getOrganizationDevicesStatuses(org_id, total_pages='all')

        except meraki.APIError as e:
            print(f'Meraki API error: {e}')
            print(f'status code = {e.status}')
            print(f'reason = {e.reason}')
            print(f'error = {e.message}')
            continue
        except Exception as e:
            print(f'some other error: {e}')
            continue

        # Convert devicestatuses to Dataframe.
        df_devicestatuses = pd.DataFrame(devicestatuses)


    #
    # Variables
    #
    todays_date = f'{datetime.now():%Y-%m-%d}'
    time_of_run = f'{datetime.now():%H-%M-%S}'
    outputfilename = f'Device Statuses - {todays_date}_{time_of_run}.xlsx'

    # Takes output file and creates XLSX file.  index=False removes first index column.
    df_devicestatuses.to_excel(outputfilename, index=False, engine='openpyxl')

 

Get notified when there are additional replies to this discussion.