Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions examples/apiData2CSV_v0.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import csv
from datetime import datetime
import os
import json
import argparse
import sys

import meraki

import urllib.parse
import platform

# This example pulls API calls from the passed in org_id from the last timespan
# seconds, where the default timespan is 900 (hint 24 hours = 3600 seconds) and
# generates a CSV file with the data.
#
# Either input your API key below by uncommenting line 10 and changing line 16 to api_key=API_KEY,
# or set an environment variable (preferred) to define your API key. The former is insecure and not recommended.
# For example, in Linux/macOS: export MERAKI_DASHBOARD_API_KEY=093b24e85df15a3e66f1fc359f4c48493eaa1b73
# API_KEY = '093b24e85df15a3e66f1fc359f4c48493eaa1b73'
#
# Optionally, Cisco partners can set their BE GEO ID by using export BE_GEO_ID=XXXXXX
# where XXXXX is a valid BE GEO ID. This is used for metrics collection.
#
# Optionally, a calling application can be set by using export MERAKI_PYTHON_SDK_CALLER=YYYYY
# where YYYYY is a string identifying the application, script, or whatever piece of code
# is callig the Meraki Python SDK


def main(org_id, timespan):
# Instantiate a Meraki dashboard API session
dashboard = meraki.DashboardAPI(
base_url='https://api-mp.meraki.com/api/v0/',
print_console=False,
output_log=False,
)

# Get list of API usage data and start the output csv string
apiUsage = dashboard.api_usage.getOrganizationApiRequests(org_id, timespan=timespan, total_pages=-1)
csvString = 'method,host,path,queryString,tsDate,tsTime,responseCode,sourceIp,userAgent,'
csvString += 'implementation,implementationVersion,distro,distroVersion,system,systemRelease,'
csvString += 'cpu,be_geo_id,caller\r\n'
cumulativeAPIcalls = 0;
for use in apiUsage:
csvString += use['method'] + ','
csvString += use['host'] + ','
csvString += use['path'] + ','
csvString += use['queryString'] + ','
csvString += use['ts'].split('T')[0] + ','
csvString += use['ts'].split('T')[1].replace('Z','') + ','
csvString += str(use['responseCode']) + ','
csvString += use['sourceIp'] + ','

# Special User-Agent processing
if 'python-meraki' in use['userAgent']:
print(use['userAgent'])
userAgent = use['userAgent'].split(' ')
csvString += userAgent[0] + ','
if len(userAgent) > 1:
if "implementation" in userAgent[1]:
userAgentDict = json.loads(urllib.parse.unquote(userAgent[1]))
csvString += userAgentDict['implementation']['name'] + ','
csvString += userAgentDict['implementation']['version'] + ','
csvString += userAgentDict['distro']['name'] + ','
csvString += userAgentDict['distro']['version'] + ','
csvString += userAgentDict['system']['name'] + ','
csvString += userAgentDict['system']['release'] + ','
csvString += userAgentDict['cpu'] + ','
if "be_geo_id" in userAgentDict:
csvString += userAgentDict['be_geo_id'] + ','
else:
csvString += ','
if "application" in userAgentDict:
csvString += userAgentDict['application'] + ','
elif "caller" in userAgentDict:
csvString += userAgentDict['caller'] + ','
else:
csvString += ','
else:
csvString += ',,,,,,,,,'
else:
csvString += ',,,,,,,,,'
else:
csvString += use['userAgent']+ ','
csvString += ',,,,,,,,,'

csvString += '\r\n'

# Output the file
now = datetime.now()
dt_string = now.strftime("%Y-%m-%d_%H-%M-%S")
filename = org_id + '_' + str(timespan) + '_' + dt_string + '.csv'
file = open(filename, 'w')
file.write(csvString)
file.close()
print('Results written to ' + filename)

if __name__ == '__main__':
# First check for API key
if "MERAKI_DASHBOARD_API_KEY" not in os.environ:
print('You must set the MERAKI_DASHBOARD_API_KEY variable')
sys.exit()

# Now check arguments
parser = argparse.ArgumentParser(description='Generate a CSV file of Meraki API activity for an organization.')
parser.add_argument('org_id', help='Organization id to pull API activity from')
parser.add_argument('--timespan', type=int, default=900,
help='The timespan (in seconds) for which the information will be fetched. Default = 900 (15 mins)')
args = parser.parse_args()
print('About to run with org_id: ' + args.org_id + ' and timespan: ' + str(args.timespan))

# Finally, let's roll
start_time = datetime.now()
main(args.org_id, args.timespan)
end_time = datetime.now()
print(f'\nScript complete, total runtime {end_time - start_time}')
116 changes: 116 additions & 0 deletions examples/apiData2CSV_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import csv
from datetime import datetime
import os
import json
import argparse
import sys

import meraki

import urllib.parse
import platform

# This example pulls API calls from the passed in org_id from the last timespan
# seconds, where the default timespan is 900 (hint 24 hours = 3600 seconds) and
# generates a CSV file with the data.
#
# Either input your API key below by uncommenting line 10 and changing line 16 to api_key=API_KEY,
# or set an environment variable (preferred) to define your API key. The former is insecure and not recommended.
# For example, in Linux/macOS: export MERAKI_DASHBOARD_API_KEY=093b24e85df15a3e66f1fc359f4c48493eaa1b73
# API_KEY = '093b24e85df15a3e66f1fc359f4c48493eaa1b73'
#
# Optionally, Cisco partners can set their BE GEO ID by using export BE_GEO_ID=XXXXXX
# where XXXXX is a valid BE GEO ID. This is used for metrics collection.
#
# Optionally, a calling application can be set by using export MERAKI_PYTHON_SDK_CALLER=YYYYY
# where YYYYY is a string identifying the application, script, or whatever piece of code
# is callig the Meraki Python SDK


def main(org_id, timespan):
# Instantiate a Meraki dashboard API session
dashboard = meraki.DashboardAPI(
base_url='https://api-mp.meraki.com/api/v1/',
print_console=False,
output_log=False,
)

# Get list of API usage data and start the output csv string
apiUsage = dashboard.organizations.getOrganizationApiRequests(org_id, timespan=timespan, total_pages=-1)
csvString = 'method,host,path,queryString,tsDate,tsTime,responseCode,sourceIp,userAgent,'
csvString += 'implementation,implementationVersion,distro,distroVersion,system,systemRelease,'
csvString += 'cpu,be_geo_id,caller\r\n'
cumulativeAPIcalls = 0;
for use in apiUsage:
csvString += use['method'] + ','
csvString += use['host'] + ','
csvString += use['path'] + ','
csvString += use['queryString'] + ','
csvString += use['ts'].split('T')[0] + ','
csvString += use['ts'].split('T')[1].replace('Z','') + ','
csvString += str(use['responseCode']) + ','
csvString += use['sourceIp'] + ','

# Special User-Agent processing
if 'python-meraki' in use['userAgent']:
print(use['userAgent'])
userAgent = use['userAgent'].split(' ')
csvString += userAgent[0] + ','
if len(userAgent) > 1:
if "implementation" in userAgent[1]:
userAgentDict = json.loads(urllib.parse.unquote(userAgent[1]))
csvString += userAgentDict['implementation']['name'] + ','
csvString += userAgentDict['implementation']['version'] + ','
csvString += userAgentDict['distro']['name'] + ','
csvString += userAgentDict['distro']['version'] + ','
csvString += userAgentDict['system']['name'] + ','
csvString += userAgentDict['system']['release'] + ','
csvString += userAgentDict['cpu'] + ','
if "be_geo_id" in userAgentDict:
csvString += userAgentDict['be_geo_id'] + ','
else:
csvString += ','
if "application" in userAgentDict:
csvString += userAgentDict['application'] + ','
elif "caller" in userAgentDict:
csvString += userAgentDict['caller'] + ','
else:
csvString += ','
else:
csvString += ',,,,,,,,,'
else:
csvString += ',,,,,,,,,'
else:
csvString += use['userAgent']+ ','
csvString += ',,,,,,,,,'

csvString += '\r\n'

# Output the file
now = datetime.now()
dt_string = now.strftime("%Y-%m-%d_%H-%M-%S")
filename = org_id + '_' + str(timespan) + '_' + dt_string + '.csv'
file = open(filename, 'w')
file.write(csvString)
file.close()
print('Results written to ' + filename)

if __name__ == '__main__':
# First check for API key
if "MERAKI_DASHBOARD_API_KEY" not in os.environ:
print('You must set the MERAKI_DASHBOARD_API_KEY variable')
sys.exit()

# Now check arguments
parser = argparse.ArgumentParser(description='Generate a CSV file of Meraki API activity for an organization.')
parser.add_argument('org_id', help='Organization id to pull API activity from')
parser.add_argument('--timespan', type=int, default=900,
help='The timespan (in seconds) for which the information will be fetched. Default = 900 (15 mins)')
args = parser.parse_args()
print('About to run with org_id: ' + args.org_id + ' and timespan: ' + str(args.timespan))

# Finally, let's roll
start_time = datetime.now()
main(args.org_id, args.timespan)
end_time = datetime.now()
print(f'\nScript complete, total runtime {end_time - start_time}')
12 changes: 11 additions & 1 deletion meraki_v0/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ class DashboardAPI(object):
- print_console (boolean): print logging output to console?
- suppress_logging (boolean): disable all logging? you're on your own then!
- simulate (boolean): simulate POST/PUT/DELETE calls to prevent changes?
- be_geo_id (string): optional partner identifier for API usage tracking; can also be set as an environment variable BE_GEO_ID
- caller (string): optional identifier for API usage tracking; can also be set as an environment variable MERAKI_PYTHON_SDK_CALLER
"""

def __init__(self, api_key=None, base_url=DEFAULT_BASE_URL, single_request_timeout=SINGLE_REQUEST_TIMEOUT,
Expand All @@ -117,12 +119,18 @@ def __init__(self, api_key=None, base_url=DEFAULT_BASE_URL, single_request_timeo
retry_4xx_error=RETRY_4XX_ERROR, retry_4xx_error_wait_time=RETRY_4XX_ERROR_WAIT_TIME,
maximum_retries=MAXIMUM_RETRIES, output_log=OUTPUT_LOG, log_path=LOG_PATH,
log_file_prefix=LOG_FILE_PREFIX, print_console=PRINT_TO_CONSOLE, suppress_logging=SUPPRESS_LOGGING,
simulate=SIMULATE_API_CALLS):
simulate=SIMULATE_API_CALLS, be_geo_id='', caller=''):
# Check API key
api_key = api_key or os.environ.get(API_KEY_ENVIRONMENT_VARIABLE)
if not api_key:
raise APIKeyError()

# Pull the BE GEO ID from an environment variable if present
be_geo_id = be_geo_id or os.environ.get('BE_GEO_ID')

# Pull the caller from an environment variable if present
caller = caller or os.environ.get('MERAKI_PYTHON_SDK_CALLER')

# Configure logging
if not suppress_logging:
self._logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -163,6 +171,8 @@ def __init__(self, api_key=None, base_url=DEFAULT_BASE_URL, single_request_timeo
retry_4xx_error_wait_time=retry_4xx_error_wait_time,
maximum_retries=maximum_retries,
simulate=simulate,
be_geo_id=be_geo_id,
caller=caller,
)

# API endpoints by section
Expand Down
49 changes: 48 additions & 1 deletion meraki_v0/rest_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,52 @@

import requests

import urllib.parse
import platform

from .config import *
from .exceptions import *

def user_agent_extended(be_geo_id, caller):
# Generate extended portion of the User-Agent
user_agent_extended = be_geo_id
user_agent_extended = {}

# Mimic pip system data collection per https://github.com/pypa/pip/blob/master/src/pip/_internal/network/session.py
user_agent_extended['implementation'] = {
"name": platform.python_implementation(),
}

if user_agent_extended["implementation"]["name"] in ('CPython','Jython','IronPython'):
user_agent_extended["implementation"]["version"] = platform.python_version()
elif user_agent_extended["implementation"]["name"] == 'PyPy':
if sys.pypy_version_info.releaselevel == 'final':
pypy_version_info = sys.pypy_version_info[:3]
else:
pypy_version_info = sys.pypy_version_info
user_agent_extended["implementation"]["version"] = ".".join(
[str(x) for x in pypy_version_info]
)

if sys.platform.startswith("darwin") and platform.mac_ver()[0]:
user_agent_extended["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]}

if platform.system():
user_agent_extended.setdefault("system", {})["name"] = platform.system()

if platform.release():
user_agent_extended.setdefault("system", {})["release"] = platform.release()

if platform.machine():
user_agent_extended["cpu"] = platform.machine()

if be_geo_id:
user_agent_extended["be_geo_id"] = be_geo_id

if caller:
user_agent_extended["caller"] = caller

return urllib.parse.quote(json.dumps(user_agent_extended))

# Main module interface
class RestSession(object):
Expand All @@ -24,6 +67,8 @@ def __init__(
retry_4xx_error_wait_time=RETRY_4XX_ERROR_WAIT_TIME,
maximum_retries=MAXIMUM_RETRIES,
simulate=SIMULATE_API_CALLS,
be_geo_id='',
caller=''
):
super(RestSession, self).__init__()

Expand All @@ -39,6 +84,8 @@ def __init__(
self._retry_4xx_error_wait_time = retry_4xx_error_wait_time
self._maximum_retries = maximum_retries
self._simulate = simulate
self._be_geo_id = be_geo_id
self._caller = caller

# Initialize a new `requests` session
self._req_session = requests.session()
Expand All @@ -54,7 +101,7 @@ def __init__(
self._req_session.headers = {
'X-Cisco-Meraki-API-Key': self._api_key,
'Content-Type': 'application/json',
'User-Agent': 'python-meraki/0.100.2',
'User-Agent': 'python-meraki/0.100.2' + user_agent_extended(be_geo_id, caller),
}

# Log API calls
Expand Down
12 changes: 11 additions & 1 deletion meraki_v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class DashboardAPI(object):
- print_console (boolean): print logging output to console?
- suppress_logging (boolean): disable all logging? you're on your own then!
- simulate (boolean): simulate POST/PUT/DELETE calls to prevent changes?
- be_geo_id (string): optional partner identifier for API usage tracking; can also be set as an environment variable BE_GEO_ID
- caller (string): optional identifier for API usage tracking; can also be set as an environment variable MERAKI_PYTHON_SDK_CALLER
"""

def __init__(self, api_key=None, base_url=DEFAULT_BASE_URL, single_request_timeout=SINGLE_REQUEST_TIMEOUT,
Expand All @@ -51,12 +53,18 @@ def __init__(self, api_key=None, base_url=DEFAULT_BASE_URL, single_request_timeo
retry_4xx_error=RETRY_4XX_ERROR, retry_4xx_error_wait_time=RETRY_4XX_ERROR_WAIT_TIME,
maximum_retries=MAXIMUM_RETRIES, output_log=OUTPUT_LOG, log_path=LOG_PATH,
log_file_prefix=LOG_FILE_PREFIX, print_console=PRINT_TO_CONSOLE, suppress_logging=SUPPRESS_LOGGING,
simulate=SIMULATE_API_CALLS):
simulate=SIMULATE_API_CALLS, be_geo_id='', caller=''):
# Check API key
api_key = api_key or os.environ.get(API_KEY_ENVIRONMENT_VARIABLE)
if not api_key:
raise APIKeyError()

# Pull the BE GEO ID from an environment variable if present
be_geo_id = be_geo_id or os.environ.get('BE_GEO_ID')

# Pull the caller from an environment variable if present
caller = caller or os.environ.get('MERAKI_PYTHON_SDK_CALLER')

# Configure logging
if not suppress_logging:
self._logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -97,6 +105,8 @@ def __init__(self, api_key=None, base_url=DEFAULT_BASE_URL, single_request_timeo
retry_4xx_error_wait_time=retry_4xx_error_wait_time,
maximum_retries=maximum_retries,
simulate=simulate,
be_geo_id=be_geo_id,
caller=caller,
)

# API endpoints by section
Expand Down
Loading