Skip to content

Commit 736c26f

Browse files
author
Shiyue Cheng
committed
major revamp of the dashboard API library
1 parent c5b518f commit 736c26f

80 files changed

Lines changed: 7640 additions & 44 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Cisco Systems, Inc. and/or its affiliates
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,51 @@
1-
Python 3.6 module providing all current Meraki [Dashboard API](https://dashboard.meraki.com/api_docs) calls to interface with the Cisco Meraki cloud-managed IT solutions.
2-
Also available via [PIP](https://pypi.python.org/pypi/meraki/).
3-
4-
5-
## Initial Setup
6-
* Enable APIs in your Meraki dashboard and obtain an APIKey: [Instructions](https://documentation.meraki.com/zGeneral_Administration/Other_Topics/The_Cisco_Meraki_Dashboard_API)
7-
* Keep your APIKey safe and secure. It is similar to a password for your dashboard. If publishing your Python programs to a wider audience, please research secure handling of APIKeys.
8-
* Although the Meraki API can be accessed in various ways, this module uses Python3. [Get started with Python](https://wiki.python.org/moin/BeginnersGuide/NonProgrammers)
9-
* After Python is installed, prepare your environment:
10-
* Use pip (or alternative such as easy_install) to install required packages:
11-
* pip install requests meraki
12-
* You are now ready to create your first script:
13-
* create a new file and name it with python extension, e.g., meraki_hello_world.py
14-
* import the meraki api into your script, e.g., from meraki import meraki
15-
* use the meraki API to interact with your dashboard
16-
17-
## Example
18-
19-
```python
20-
from meraki import meraki
21-
22-
apikey = "jkhsfsdhk32424******example*****jlasdfsdfl3245345"
23-
myOrgs = meraki.myorgaccess(apikey)
24-
print(myOrgs)
25-
```
26-
27-
## Useful API calls to get started
28-
29-
```python
30-
myNetworks = meraki.getnetworklist(apikey, orgid)
31-
deviceList = meraki.getnetworkdevices(apikey, networkid)
32-
clientList = meraki.getclients(apikey,serialnum)
33-
```
1+
# Meraki Dashboard API Python Library
2+
3+
The new Meraki Dashboard API Python library provides all current Meraki [Dashboard API](https://api.meraki.com/api_docs) calls to interface with the Cisco Meraki cloud-managed platform. The library is supported on Python 3.6 or above, and you can install it via [PyPI](https://pypi.org/project/meraki/):
4+
5+
pip install meraki
6+
7+
## Features
8+
9+
This library's goal is to refresh and supplant the legacy module (this repository versions 0.34 and prior) as well as the now-deprecated [SDK](https://github.com/meraki/meraki-python-sdk). Here are some of the features in this revamped library:
10+
11+
* Support for all API endpoints, as it uses the [OpenAPI specification](https://api.meraki.com/api/v0/openapiSpec) to generate source code
12+
* Log all API requests made to a local file as well as on-screen console
13+
* Automatic retries upon 429 rate limit errors, using the [`Retry-After` field](https://developer.cisco.com/meraki/api/#/rest/guides/rate-limit-errors) within response headers
14+
* Get all (or a specified number of) pages of data with built-in pagination control
15+
* Tweak settings such as the default base URL (for example, to use with V1 and/or mega-proxy)
16+
* Simulate POST/PUT/DELETE calls to preview first, so that network configuration does not get changed
17+
* Includes the legacy module's functions for backward compatibility
18+
19+
## Setup
20+
21+
1. Enable API access in your Meraki dashboard organization and obtain an API key ([instructions](https://documentation.meraki.com/zGeneral_Administration/Other_Topics/The_Cisco_Meraki_Dashboard_API))
22+
23+
2. Keep your API key safe and secure, as it is similar to a password for your dashboard. If publishing your Python code to a wider audience, please research secure handling of API keys.
24+
25+
3. Although the Meraki dashboard API, as a REST API, can be accessed in various ways, this library uses Python 3.6+. ([get started with Python](https://wiki.python.org/moin/BeginnersGuide/NonProgrammers))
26+
27+
4. After Python 3 is installed, use _pip_ (or an alternative such as _easy_install_) to install the library:
28+
* `pip install meraki`
29+
* If you have both Python3 and Python2 installed, you may need to use `pip3 install meraki`
30+
31+
## Usage
32+
1. Export your API key as an [environment variable](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html), for example:
33+
34+
`export MERAKI_DASHBOARD_API_KEY=093b24e85df15a3e66f1fc359f4c48493eaa1b73`
35+
36+
2. Alternatively, define your API key as a variable in your source code; this method is not recommended due to its inherent insecurity.
37+
38+
3. Single line of code to import and use the library goes at the top of your script:
39+
40+
`import meraki`
41+
42+
4. Instantiate the client (API consumer class), optionally specifying any of the parameters available to set:
43+
44+
`dashboard = meraki.DashboardAPI()`
45+
46+
5. Make dashboard API calls in your source code, using the format _client.section.operation_, where _client_ is the name you defined in the previous step (**dashboard** above), _section_ is the corresponding group (or tag from the OpenAPI spec) from the [API docs](https://developer.cisco.com/meraki/api/#/rest), and _operation_ is the name (or operation ID from OpenAPI) of the API endpoint. For example, to make a call to get the list of organizations accessible by the API key defined in step 1, use this function call:
47+
48+
`my_orgs = dashboard.organizations.getOrganizations()`
49+
50+
51+
For a full working script that demos this library, please see and run the **org_wide_clients.py** file included (in **examples** folder). That code collects the clients of all networks, in all orgs to which the key has access. No changes are made, since only GET endpoints are called, and the data is written to local CSV output files.

examples/org_wide_clients.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import csv
2+
from datetime import datetime
3+
import os
4+
5+
import meraki
6+
7+
# Either input your API key below by uncommenting line 10 and changing line 15 to api_key=api_key,
8+
# or set an environment variable (preferred) to define your API key. The former is insecure and not recommended.
9+
# For example, in Linux/macOS: export MERAKI_DASHBOARD_API_KEY=093b24e85df15a3e66f1fc359f4c48493eaa1b73
10+
# api_key = '093b24e85df15a3e66f1fc359f4c48493eaa1b73'
11+
12+
13+
def main():
14+
# Instantiate a Meraki dashboard API session
15+
dashboard = meraki.DashboardAPI(api_key=None, base_url='https://api.meraki.com/api/v0/', log_file_prefix=__file__[:-3], print_console=False)
16+
17+
# Get list of organizations to which API key has access
18+
organizations = dashboard.organizations.getOrganizations()
19+
20+
# Iterate through list of orgs
21+
for org in organizations:
22+
print(f'\nAnalyzing organization {org["name"]}:')
23+
org_id = org['id']
24+
25+
# Get list of networks in organization
26+
try:
27+
networks = dashboard.networks.getOrganizationNetworks(org_id)
28+
except meraki.APIError as e:
29+
print(f'Meraki API error: {e}')
30+
continue
31+
except Exception as e:
32+
print(f'some other error: {e}')
33+
continue
34+
35+
# Create local folder
36+
todays_date = f'{datetime.now():%Y-%m-%d}'
37+
folder_name = f'Org {org_id} clients {todays_date}'
38+
if folder_name not in os.listdir():
39+
os.mkdir(folder_name)
40+
41+
# Iterate through networks
42+
total = len(networks)
43+
counter = 1
44+
print(f' - iterating through {total} networks in organization {org_id}')
45+
for net in networks:
46+
print(f'Finding clients in network {net["name"]} ({counter} of {total})')
47+
try:
48+
# Get list of clients on network, filtering on timespan of last 14 days
49+
clients = dashboard.clients.getNetworkClients(net['id'], timespan=60*60*24*14, perPage=1000, total_pages='all')
50+
except meraki.APIError as e:
51+
print(f'Meraki API error: {e}')
52+
except Exception as e:
53+
print(f'some other error: {e}')
54+
else:
55+
if clients:
56+
# Write to file
57+
file_name = f'{net["name"]}.csv'
58+
output_file = open(f'{folder_name}/{file_name}', mode='w', newline='\n')
59+
field_names = clients[0].keys()
60+
csv_writer = csv.DictWriter(output_file, field_names, delimiter=',', quotechar='"',
61+
quoting=csv.QUOTE_ALL)
62+
csv_writer.writeheader()
63+
csv_writer.writerows(clients)
64+
output_file.close()
65+
print(f' - found {len(clients)}')
66+
67+
counter += 1
68+
69+
# Stitch together one consolidated CSV per org
70+
output_file = open(f'{folder_name}.csv', mode='w', newline='\n')
71+
field_names = list(field_names)
72+
field_names.insert(0, 'Network Name')
73+
field_names.insert(1, 'Network ID')
74+
csv_writer = csv.DictWriter(output_file, field_names, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
75+
csv_writer.writeheader()
76+
for net in networks:
77+
file_name = f'{net["name"]}.csv'
78+
if file_name in os.listdir(folder_name):
79+
with open(f'{folder_name}/{file_name}') as input_file:
80+
csv_reader = csv.DictReader(input_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
81+
next(csv_reader)
82+
for row in csv_reader:
83+
row['Network Name'] = net['name']
84+
row['Network ID'] = net['id']
85+
csv_writer.writerow(row)
86+
87+
88+
if __name__ == '__main__':
89+
start_time = datetime.now()
90+
main()
91+
end_time = datetime.now()
92+
print(f'\nScript complete, total runtime {end_time - start_time}')

0 commit comments

Comments
 (0)