Python: update_network_device

Solved
PhilipDAth
Kind of a big deal
Kind of a big deal

Python: update_network_device

I'm trying to use update_network_device to update the lat and lng of devices, and I just can't seem to get the API call to work.

 

I'm using something like:

from dotenv import load_dotenv
load_dotenv()
load_dotenv(dotenv_path=os.path.join(os.path.expanduser("~"),".meraki.env"))

from meraki_sdk.meraki_sdk_client import MerakiSdkClient
from meraki_sdk.exceptions.api_exception import APIException
from meraki_sdk.models.update_network_device_model import UpdateNetworkDeviceModel

meraki = MerakiSdkClient(os.getenv("x_cisco_meraki_api_key"))
meraki.config.base_uri='https://api-mp.meraki.com/api/v0'

...

        device=UpdateNetworkDeviceModel()
        device.lat=lat;
        device.lng=long;

        try:
                meraki.devices.update_network_device({'network_id':netId,'serial':serial,'update_network_device':device})
        except APIException as e:
                print(e)

 

I just get back a "HTTP response not OK.".  All other API calls work up to this point.  So I'm confident the API key is correct.  The API key belongs to an account that has sufficient rights to make the change.

1 Accepted Solution
PhilipDAth
Kind of a big deal
Kind of a big deal

Thanks @chengineer .  I had been delaying using that library in production thinking it was more still in beta.

 

However that library ("pip3 install meraki") works perfectly.  Sample working code:

 

 

import gpsd,os,argparse,meraki

from dotenv import load_dotenv
load_dotenv()
load_dotenv(dotenv_path=os.path.join(os.path.expanduser("~"),".meraki.env"))

dashboard = meraki.DashboardAPI(
        api_key=os.getenv("x_cisco_meraki_api_key"),
        base_url='https://api-mp.meraki.com/api/v0/',
        print_console=False
)

...

        dashboard.devices.updateNetworkDevice(netId,serial,lat=lat,lng=long)

 

View solution in original post

8 Replies 8
boomi
Getting noticed

Yea this isn't working for me either. Same result. Oddly, Postman receives a 200 but does not change anything. Tried changing device name, no change either.

 

Postman raw body:

 

{
"lat": XX.XXXXXX, 
"lng": -YY.YYYYY,
}
boomi
Getting noticed

Think I figured it out, UpdateNetworkDeviceModel does not behave properly.

 

name = dictionary.get('name')
        tags = dictionary.get('tags')
        lat = dictionary.get('lat')
        lng = dictionary.get('lng')
        address = dictionary.get('address')
        notes = dictionary.get('notes')
        move_map_marker = dictionary.get('moveMapMarker')
        switch_profile_id = dictionary.get('switchProfileId')
        floor_plan_id = dictionary.get('floorPlanId')

 

All possible fields are always returned and sent in the PUT. For values you did not pass, like switch_profile_id, null is returned. The API rejects a null value for this key.

 

Passing the parameters composed by the Python API to curl results in various errors:

 

{"errors":["Device's network must be bound to a configuration template (that supports switches) to allow for switch profile binding"]}

{"errors":["'moveMapMarker' must be a boolean"]}

 

So TL;DR the underlying UpdateNetworkDeviceModel has to be updated with additional logic to not send invalid values when they're not set.

BrechtSchamp
Kind of a big deal

For me it works fine in Postman when just specifying a lng and a lat. But as for you @PhilipDAth it fails with the SDK.

 

After some debuging I found that there are multiple issues.

 

  • First error: "moveMapMarker must be a boolean. So the SDK is putting moveMapMarker as null in the params if you don't specify it. The server is expecting true or false. It shouldn't even be specifying that param imo if you don't. But okay, I put in False in python which is then translated into false further on in the request params. Upon running with that change we arrive at the second error.
  • Second error: "Device's network must be bound to a configuration template (that supports switches) to allow for switch profile binding". Again, even though no switch_profile_id is specified in the device object, the SDK adds it into the parameters with a null value. The server doesn't accept that.

At this point I stopped debugging as there is no sensible value I can put in in the switch_profile_id... None gets translated to null as well so that won't help.

 

This smells like SDK bug.

 

BrechtSchamp
Kind of a big deal

Lol, I should've refreshed before putting the effort for the debugging in. At least we came to the same conclusion @boomi .

boomi
Getting noticed

Haha, every time!

PhilipDAth
Kind of a big deal
Kind of a big deal

Another job for you @chengineer .

chengineer
Meraki Alumni (Retired)
Meraki Alumni (Retired)

We're going to deprecate and remove that SDK entirely, so please transition to using this library instead.

Solutions Architect @ Cisco Meraki | API & Developer Ecosystem
PhilipDAth
Kind of a big deal
Kind of a big deal

Thanks @chengineer .  I had been delaying using that library in production thinking it was more still in beta.

 

However that library ("pip3 install meraki") works perfectly.  Sample working code:

 

 

import gpsd,os,argparse,meraki

from dotenv import load_dotenv
load_dotenv()
load_dotenv(dotenv_path=os.path.join(os.path.expanduser("~"),".meraki.env"))

dashboard = meraki.DashboardAPI(
        api_key=os.getenv("x_cisco_meraki_api_key"),
        base_url='https://api-mp.meraki.com/api/v0/',
        print_console=False
)

...

        dashboard.devices.updateNetworkDevice(netId,serial,lat=lat,lng=long)

 

Get notified when there are additional replies to this discussion.