Update work/tbx/meraki/sandbox_api.md
This commit is contained in:
@@ -274,4 +274,266 @@ source setup_env.sh
|
||||
python scripts/inventorycsv.py -k $MERAKI_DASHBOARD_API_KEY -o "DeLab" -f DeLab_inventory_list.csv
|
||||
```
|
||||
|
||||
This setup should give you a good starting point for working with the Meraki Dashboard API in a sandbox environment. If you have any further questions or need additional examples, feel free to ask!
|
||||
This setup should give you a good starting point for working with the Meraki Dashboard API in a sandbox environment. If you have any further questions or need additional examples, feel free to ask!
|
||||
|
||||
---
|
||||
|
||||
Certainly! Let's add the retry mechanism to the `get_license.py` and `inventorycsv.py` scripts as well.
|
||||
|
||||
### Updated `get_license.py` Script with Retry Mechanism
|
||||
|
||||
```python
|
||||
import requests
|
||||
import argparse
|
||||
import time
|
||||
|
||||
def get_license_info(api_key, org_name):
|
||||
base_url = 'https://api.meraki.com/api/v1'
|
||||
headers = {
|
||||
'Authorization': f'Bearer {api_key}'
|
||||
}
|
||||
|
||||
def make_request(url):
|
||||
retries = 5
|
||||
for i in range(retries):
|
||||
response = requests.get(url, headers=headers)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
elif response.status_code == 429:
|
||||
print(f"API rate limit exceeded. Retrying in {2 ** i} seconds...")
|
||||
time.sleep(2 ** i)
|
||||
else:
|
||||
print(f"Error: {response.status_code} - {response.text}")
|
||||
return None
|
||||
return None
|
||||
|
||||
# Get the list of organizations
|
||||
orgs = make_request(f'{base_url}/organizations')
|
||||
if orgs is None:
|
||||
return
|
||||
|
||||
# Find the organization ID for the given name
|
||||
org_id = None
|
||||
for org in orgs:
|
||||
if org['name'] == org_name:
|
||||
org_id = org['id']
|
||||
break
|
||||
|
||||
if org_id is None:
|
||||
print(f'Organization {org_name} not found')
|
||||
return
|
||||
|
||||
# Get the license information for the organization
|
||||
license_info = make_request(f'{base_url}/organizations/{org_id}/licenses')
|
||||
if license_info is None:
|
||||
return
|
||||
|
||||
print(f'License info for organization "{org_name}" (ID: {org_id})')
|
||||
print(f'Status: {license_info["status"]}')
|
||||
print(f'Expiration date: {license_info["expirationDate"]}')
|
||||
print('Licensed device counts:')
|
||||
for license in license_info['licenses']:
|
||||
print(f'{license["productType"]}:\t{license["total"]}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Get license info for a Meraki organization')
|
||||
parser.add_argument('-k', '--api_key', required=True, help='Meraki API key')
|
||||
parser.add_argument('-o', '--org_name', required=True, help='Meraki organization name')
|
||||
args = parser.parse_args()
|
||||
get_license_info(args.api_key, args.org_name)
|
||||
```
|
||||
|
||||
### Updated `inventorycsv.py` Script with Retry Mechanism
|
||||
|
||||
```python
|
||||
import requests
|
||||
import csv
|
||||
import argparse
|
||||
import time
|
||||
|
||||
def get_inventory(api_key, org_name, filename):
|
||||
base_url = 'https://api.meraki.com/api/v1'
|
||||
headers = {
|
||||
'Authorization': f'Bearer {api_key}'
|
||||
}
|
||||
|
||||
def make_request(url):
|
||||
retries = 5
|
||||
for i in range(retries):
|
||||
response = requests.get(url, headers=headers)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
elif response.status_code == 429:
|
||||
print(f"API rate limit exceeded. Retrying in {2 ** i} seconds...")
|
||||
time.sleep(2 ** i)
|
||||
else:
|
||||
print(f"Error: {response.status_code} - {response.text}")
|
||||
return None
|
||||
return None
|
||||
|
||||
# Get the list of organizations
|
||||
orgs = make_request(f'{base_url}/organizations')
|
||||
if orgs is None:
|
||||
return
|
||||
|
||||
# Find the organization ID for the given name
|
||||
org_id = None
|
||||
for org in orgs:
|
||||
if org['name'] == org_name:
|
||||
org_id = org['id']
|
||||
break
|
||||
|
||||
if org_id is None:
|
||||
print(f'Organization {org_name} not found')
|
||||
return
|
||||
|
||||
# Get the inventory for the organization
|
||||
inventory = make_request(f'{base_url}/organizations/{org_id}/inventory/devices')
|
||||
if inventory is None:
|
||||
return
|
||||
|
||||
# Write the inventory to a CSV file
|
||||
with open(filename, 'w', newline='') as csvfile:
|
||||
fieldnames = ['serial', 'model', 'networkId', 'mac', 'claimedAt']
|
||||
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
||||
|
||||
writer.writeheader()
|
||||
for device in inventory:
|
||||
writer.writerow(device)
|
||||
|
||||
print(f'Inventory for organization "{org_name}" saved to {filename}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Get inventory for a Meraki organization')
|
||||
parser.add_argument('-k', '--api_key', required=True, help='Meraki API key')
|
||||
parser.add_argument('-o', '--org_name', required=True, help='Meraki organization name')
|
||||
parser.add_argument('-f', '--filename', required=True, help='Output CSV file')
|
||||
args = parser.parse_args()
|
||||
get_inventory(args.api_key, args.org_name, args.filename)
|
||||
```
|
||||
|
||||
### Steps to Run the Updated Scripts
|
||||
|
||||
1. **Ensure your conda environment is activated:**
|
||||
|
||||
```sh
|
||||
conda activate meraki_env
|
||||
```
|
||||
|
||||
2. **Run the updated scripts with the appropriate arguments:**
|
||||
|
||||
- **Get client count:**
|
||||
|
||||
```sh
|
||||
python scripts/clientcount.py -k $MERAKI_DASHBOARD_API_KEY -o "DeLab"
|
||||
```
|
||||
|
||||
- **Get license information:**
|
||||
|
||||
```sh
|
||||
python scripts/get_license.py -k $MERAKI_DASHBOARD_API_KEY -o "DeLab"
|
||||
```
|
||||
|
||||
- **Get inventory list:**
|
||||
|
||||
```sh
|
||||
python scripts/inventorycsv.py -k $MERAKI_DASHBOARD_API_KEY -o "DeLab" -f DeLab_inventory_list.csv
|
||||
```
|
||||
|
||||
By adding the retry mechanism to these scripts, you can handle API rate limits more gracefully and ensure that your scripts can complete their tasks even when faced with temporary API restrictions. If you encounter any other issues or have further questions, please let me know!
|
||||
|
||||
---
|
||||
|
||||
The error message indicates that the API rate limit has been exceeded for your organization. This means that the Meraki API has received too many requests in a short period of time. To handle this, you can implement a retry mechanism with exponential backoff to wait before retrying the request.
|
||||
|
||||
Here is the updated `clientcount.py` script with a retry mechanism:
|
||||
|
||||
### Updated `clientcount.py` with Retry Mechanism
|
||||
|
||||
```python
|
||||
import requests
|
||||
import argparse
|
||||
import time
|
||||
import json
|
||||
|
||||
def get_client_count(api_key, org_name):
|
||||
base_url = 'https://api.meraki.com/api/v1'
|
||||
headers = {
|
||||
'Authorization': f'Bearer {api_key}'
|
||||
}
|
||||
|
||||
def make_request(url):
|
||||
retries = 5
|
||||
for i in range(retries):
|
||||
response = requests.get(url, headers=headers)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
elif response.status_code == 429:
|
||||
print(f"API rate limit exceeded. Retrying in {2 ** i} seconds...")
|
||||
time.sleep(2 ** i)
|
||||
else:
|
||||
print(f"Error: {response.status_code} - {response.text}")
|
||||
return None
|
||||
return None
|
||||
|
||||
# Get the list of organizations
|
||||
orgs = make_request(f'{base_url}/organizations')
|
||||
if orgs is None:
|
||||
return
|
||||
|
||||
# Find the organization ID for the given name
|
||||
org_id = None
|
||||
for org in orgs:
|
||||
if org['name'] == org_name:
|
||||
org_id = org['id']
|
||||
break
|
||||
|
||||
if org_id is None:
|
||||
print(f'Organization {org_name} not found')
|
||||
return
|
||||
|
||||
# Get the list of networks in the organization
|
||||
networks = make_request(f'{base_url}/organizations/{org_id}/networks')
|
||||
if networks is None:
|
||||
return
|
||||
|
||||
# Count the number of unique clients across all networks
|
||||
unique_clients = set()
|
||||
for network in networks:
|
||||
network_id = network['id']
|
||||
clients = make_request(f'{base_url}/networks/{network_id}/clients')
|
||||
if clients is None:
|
||||
continue
|
||||
for client in clients:
|
||||
unique_clients.add(client['mac'])
|
||||
|
||||
print(f'Total unique client MAC addresses across all WLAN APs: {len(unique_clients)}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Get client count for a Meraki organization')
|
||||
parser.add_argument('-k', '--api_key', required=True, help='Meraki API key')
|
||||
parser.add_argument('-o', '--org_name', required=True, help='Meraki organization name')
|
||||
args = parser.parse_args()
|
||||
get_client_count(args.api_key, args.org_name)
|
||||
```
|
||||
|
||||
### Explanation of Changes
|
||||
|
||||
- **Retry Mechanism**: The `make_request` function implements retries with exponential backoff for handling rate limit errors (HTTP 429).
|
||||
- **Modularized API Requests**: The `make_request` function is used to handle all API requests, ensuring consistent error handling and retry logic.
|
||||
|
||||
### Steps to Run the Updated Script
|
||||
|
||||
1. **Ensure your conda environment is activated:**
|
||||
|
||||
```sh
|
||||
conda activate meraki_env
|
||||
```
|
||||
|
||||
2. **Run the updated script with the appropriate arguments:**
|
||||
|
||||
```sh
|
||||
python scripts/clientcount.py -k $MERAKI_DASHBOARD_API_KEY -o "DeLab"
|
||||
```
|
||||
|
||||
This script should now handle API rate limits more gracefully by retrying failed requests with exponential backoff. If you continue to encounter issues, please provide the specific error message for further assistance.
|
||||
Reference in New Issue
Block a user