Since my last article, Meraki has changed significantly. It evolved so much that my previous scripts are not working. In 2022, Meraki implemented a Dashboard v1, which introduced some changes to the REST API calls. Unfortunately, the previous SDK – meraki_sdk is not compatible with it, but we have not been left behind and Cisco introduced a new SDK – meraki. Let’s take a glance at how we can perform basic operations with it.
Environment
In this article, I’ll use a sandboxed Meraki environment hosted by Cisco.
All we need for the REST API connection is an API key. At the time of writing of this article, it’s – 6bec40cf957de430a6f1f2baa056b99a4fac9ea0
Tools
We will go with Python, but before we dive into the script, we need to install a meraki library. The easiest way to achieve that is using a pip. Just execute pip install meraki
(.venv) garzum@Hellfire:~/labs/ciscomerakiv1$ pip install meraki
Collecting meraki
Downloading meraki-1.43.0-py3-none-any.whl (270 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 270.6/270.6 KB 3.4 MB/s eta 0:00:00
[...]
Using cached urllib3-2.2.1-py3-none-any.whl (121 kB)
Installing collected packages: urllib3, multidict, idna, frozenlist, charset-normalizer, certifi, attrs, async-timeout, yarl, requests, aiosignal, aiohttp, meraki
Successfully installed aiohttp-3.9.3 aiosignal-1.3.1 async-timeout-4.0.3 attrs-23.2.0 certifi-2024.2.2 charset-normalizer-3.3.2 frozenlist-1.4.1 idna-3.6 meraki-1.43.0 multidict-6.0.5 requests-2.31.0 urllib3-2.2.1 yarl-1.9.4
The library has been installed with all the dependencies. From now on, we’re ready to use the SDK.
The code
Let’s take a glance at the code first.
import meraki
API_KEY = "6bec40cf957de430a6f1f2baa056b99a4fac9ea0"
meraki = meraki.DashboardAPI(API_KEY)
organizations = meraki.organizations.getOrganizations()
for organization in organizations:
print(f"ID: {organization['id']}, Name: {organization['name']}")
At the beginning, we’re importing meraki library. For the connection, we will need an API key, which is assigned as a string to the API_KEY variable.
Now, we’re ready to construct a connection handler to the Meraki. We’re creating a DashboardAPI class object by passing API_KEY as an argument. From now on, we can interact with Cisco Meraki using meraki object.
To get organizations, we’re issuing getOrganizations method from the Organizations class. The result is a list of parsed dictionaries, each one representing an organization. In the loop, we’re printing the ID and name of each, but there are more attributes that we can get. Here’s the full dictionary content of the first gathered organization.
{
"id":"463308",
"name":"Hi Cory",
"url":"https://n18.meraki.com/o/vB2D8a/manage/organization/overview",
"api":{
"enabled":true
},
"licensing":{
"model":"per-device"
},
"cloud":{
"region":{
"name":"North America"
}
},
"management":{
"details":[
]
}
}
The complete script output looks like this.
2024-03-28 22:42:31 meraki: INFO > Meraki dashboard API session initialized with these parameters: {'version': '1.43.0', 'api_key': '************************************9ea0', 'base_url': 'https://api.meraki.com/api/v1', 'single_request_timeout': 60, 'certificate_path': '', 'requests_proxy': '', 'wait_on_rate_limit': True, 'nginx_429_retry_wait_time': 60, 'action_batch_retry_wait_time': 60, 'network_delete_retry_wait_time': 240, 'retry_4xx_error': False, 'retry_4xx_error_wait_time': 60, 'maximum_retries': 2, 'simulate': False, 'be_geo_id': None, 'caller': None, 'use_iterator_for_get_pages': False}
2024-03-28 22:42:31 meraki: INFO > GET https://api.meraki.com/api/v1/organizations
2024-03-28 22:42:32 meraki: INFO > organizations, getOrganizations; page 1 - 200 OK
ID: 463308, Name: Hi Cory
ID: 549236, Name: DevNet Sandbox
ID: 681155, Name: DeLab
ID: 865776, Name: MARYDALKO_HOME
ID: 566327653141842188, Name: DevNetAssoc
ID: 573083052582914233, Name: organization with name changed
ID: 573083052582914605, Name: Jacks_test_net
ID: 573083052582915028, Name: New Meraki Org
ID: 573083052582915143, Name: My organization - clone
ID: 573083052582915144, Name: My organization
ID: 573083052582915264, Name: Dashboard - Meraki API
ID: 573083052582915293, Name: AllisTest
ID: 573083052582915413, Name: Vinesett Coffee Inc
ID: 573083052582915424, Name: 100749708's DevNet Organization
ID: 573083052582915444, Name: bobs toing
ID: 573083052582915445, Name: bobs toing
ID: 573083052582915447, Name: bobs toing
ID: 575334852396582684, Name: SVR
ID: 575334852396582738, Name: My organization
ID: 575334852396582755, Name: Your Organization
ID: 575334852396582756, Name: Personal.Lekhnath
ID: 575334852396582973, Name: DevNet Test Org
ID: 575334852396582986, Name: DevNet Test Org
ID: 575334852396583031, Name: My organization
ID: 575334852396583051, Name: Hi Cory
ID: 575334852396583071, Name: Test Ansible
ID: 575334852396583093, Name: DevRelx23
ID: 575334852396583128, Name: gk
ID: 575334852396583131, Name: thienbao
ID: 575334852396583133, Name: MARYDALKO_HOME
ID: 575334852396583134, Name: Wotan
ID: 575334852396583158, Name: abcdefg
ID: 575334852396583197, Name: Sample Org
ID: 575334852396583213, Name: sample_network
ID: 575334852396583237, Name: changetest
ID: 575334852396583264, Name: DevRelations
ID: 575334852396583536, Name: TNF - The Network Factory
ID: 575334852396583708, Name: helloworld
ID: 575334852396583819, Name: MARYDALKO_HOME
ID: 575334852396584260, Name: GGTEST_MyOrg1
ID: 575334852396584266, Name: Wild Willys Org
ID: 575334852396584347, Name: SDTestOrg
ID: 575334852396584365, Name: Test Ansible
ID: 575334852396584390, Name: Test
ID: 575334852396584433, Name: 6bec40cf957de430a6f1f2baa056b99a4fac9ea0
ID: 575334852396584455, Name: dummy
ID: 575334852396584457, Name: DeLab
ID: 575334852396584463, Name: dummy_amp
ID: 575334852396584468, Name: dummy org
ID: 575334852396584506, Name: Ballard Lab
ID: 575334852396584515, Name: neworg from postman collection
ID: 575334852396584543, Name: Nate Org
ID: 575334852396584549, Name: mmeneses-test
ID: 575334852396584594, Name: Vinesett Coffee INC
ID: 575334852396584595, Name: Vinesett Coffee INC
ID: 575334852396584596, Name: Vinesett Coffee INC
ID: 575334852396584637, Name: my org-test
ID: 575334852396584639, Name: Brent
ID: 575334852396584653, Name: 100244336's DevNet Organization
ID: 575334852396584748, Name: 100836639's DevNet Organization
ID: 575334852396584753, Name: 100633530's DevNet Organization
ID: 575334852396584754, Name: 100633530's DevNet Organization
ID: 575334852396584767, Name: Raj test organization
ID: 575334852396584768, Name: 100789295's DevNET Organization
ID: 575334852396584769, Name: 100722959's DevNet Organization
ID: 575334852396584775, Name: 100818159's DevNet Organization
ID: 575334852396584783, Name: 100828318's DevNet Organization
ID: 575334852396584794, Name: 100839804's DevNet Organization
ID: 575334852396584803, Name: 100339628's DevNet Organization
ID: 575334852396584807, Name: 100339628's DevNet Organization
ID: 575334852396584808, Name: 100339628's DevNet Organization
ID: 575334852396584809, Name: 100339628's DevNet Organization
ID: 575334852396584810, Name: 100339628's DevNet Organization
ID: 575334852396584811, Name: 100339628's DevNet Organization
ID: 575334852396584812, Name: 100339628's DevNet Organization
ID: 575334852396584813, Name: 100339628's DevNet Organization
ID: 575334852396584817, Name: 100339628's DevNet Organization
ID: 575334852396584818, Name: 100339628's DevNet Organization
ID: 575334852396584819, Name: 100339628's DevNet Organization
ID: 575334852396584820, Name: 100339628's DevNet Organization
ID: 575334852396584821, Name: 100339628's DevNet Organization
ID: 575334852396584830, Name: 100749708's DevNet Organization
ID: 575334852396584833, Name: 100822649's DevNet Organization
ID: 575334852396584839, Name: 100820990's DevNet Organization
ID: 575334852396584840, Name: 100820990's DevNet Organization
ID: 575334852396584848, Name: 100782310's DevNet Organization
ID: 575334852396584849, Name: 100782310's DevNet Organization
ID: 575334852396584868, Name: 100788523's DevNet Organization
ID: 575334852396584869, Name: 100834904's DevNet Organization
ID: 575334852396584878, Name: 100780419s DevNet Organization
ID: 575334852396584879, Name: 100777126's DevNet Organization
ID: 575334852396584884, Name: 100824197's DevNet Organization
ID: 575334852396584892, Name: 100753982's DevNet Organization
ID: 575334852396584893, Name: 100787529's DevNet Organization
ID: 575334852396584902, Name: 100752618's DevNet Organization
ID: 575334852396584906, Name: 100780496's DevNet Organization
ID: 575334852396584917, Name: 100802442's DevNet Organization
ID: 575334852396584918, Name: 100783547's DevNet Organization
ID: 575334852396584920, Name: 100783547's DevNet Organization
ID: 575334852396584959, Name: 100789133's DevNet Organization
ID: 575334852396584968, Name: 100785950's DevNet Organization
ID: 575334852396584969, Name: 100743306's DevNet Organization
ID: 575334852396584978, Name: 100816275's DevNet Organization
ID: 575334852396584983, Name: 100802049's DevNet Organization
ID: 575334852396584986, Name: Josh's organization
ID: 575334852396584989, Name: 100750430's DevNet Organization
ID: 575334852396584990, Name: 100781356's DevNet Organization
ID: 575334852396584991, Name: 100802438's DevNet Organization
ID: 575334852396584992, Name: 100780131's DevNet Organization
ID: 575334852396585033, Name: 100709841's DevNet Organization
ID: 575334852396585097, Name: Josh's organization
ID: 575334852396585147, Name: bob toing
ID: 575334852396585148, Name: bob toing
ID: 575334852396585149, Name: bob toing
ID: 575334852396585150, Name: bob toing
ID: 575334852396585151, Name: bob toing
ID: 575334852396585152, Name: bob toing
ID: 575334852396585155, Name: bobs toing
ID: 575334852396585156, Name: bob toing
ID: 575334852396585157, Name: bob toing
ID: 575334852396585158, Name: bob toing
ID: 575334852396585165, Name: bobs toing
ID: 575334852396585166, Name: bobs toing
ID: 575334852396585167, Name: bobs toing
ID: 575334852396585168, Name: bobs toing
ID: 575334852396585169, Name: bob's towing
ID: 575334852396585171, Name: bob toing
ID: 575334852396585175, Name: Josh's organization
ID: 575334852396585179, Name: Josh's organization
ID: 575334852396585181, Name: 100824197's DevNet Organization 2
ID: 575334852396585197, Name: bob toing
ID: 575334852396585209, Name: bobs toing
You can find the code in my Cisco Meraki Automation Examples repository.
Summary
SDK is a great way to automate Meraki because it makes our lives easier. Rather than focusing on particular REST API calls, we’re more into high-level operations. The call responses come as parsed Python structures, which reduces the complexity and length of the code, which has a positive effect on the code maintainability.