|
| 1 | +from datetime import datetime |
| 2 | +import logging |
| 3 | +import os |
| 4 | + |
| 5 | +from .rest_session import * |
| 6 | +from .api.organizations import Organizations |
| 7 | +from .api.networks import Networks |
| 8 | +from .api.devices import Devices |
| 9 | +from .api.appliance import Appliance |
| 10 | +from .api.camera import Camera |
| 11 | +from .api.cellularGateway import CellularGateway |
| 12 | +from .api.insight import Insight |
| 13 | +from .api.sm import Sm |
| 14 | +from .api.switch import Switch |
| 15 | +from .api.wireless import Wireless |
| 16 | + |
| 17 | +# Batch class imports |
| 18 | +from .api.batch import Batch |
| 19 | + |
| 20 | +# Config import |
| 21 | +from .config import ( |
| 22 | + API_KEY_ENVIRONMENT_VARIABLE, |
| 23 | + DEFAULT_BASE_URL, |
| 24 | + SINGLE_REQUEST_TIMEOUT, |
| 25 | + CERTIFICATE_PATH, |
| 26 | + REQUESTS_PROXY, |
| 27 | + WAIT_ON_RATE_LIMIT, |
| 28 | + NGINX_429_RETRY_WAIT_TIME, |
| 29 | + ACTION_BATCH_RETRY_WAIT_TIME, |
| 30 | + RETRY_4XX_ERROR, |
| 31 | + RETRY_4XX_ERROR_WAIT_TIME, |
| 32 | + MAXIMUM_RETRIES, |
| 33 | + OUTPUT_LOG, |
| 34 | + LOG_PATH, |
| 35 | + LOG_FILE_PREFIX, |
| 36 | + PRINT_TO_CONSOLE, |
| 37 | + SUPPRESS_LOGGING, |
| 38 | + INHERIT_LOGGING_CONFIG, |
| 39 | + SIMULATE_API_CALLS, |
| 40 | + BE_GEO_ID, |
| 41 | + MERAKI_PYTHON_SDK_CALLER, |
| 42 | + USE_ITERATOR_FOR_GET_PAGES, |
| 43 | +) |
| 44 | + |
| 45 | +__version__ = '1.15.0' |
| 46 | + |
| 47 | + |
| 48 | +class DashboardAPI(object): |
| 49 | + """ |
| 50 | + **Creates a persistent Meraki dashboard API session** |
| 51 | + |
| 52 | + - api_key (string): API key generated in dashboard; can also be set as an environment variable MERAKI_DASHBOARD_API_KEY |
| 53 | + - base_url (string): preceding all endpoint resources |
| 54 | + - single_request_timeout (integer): maximum number of seconds for each API call |
| 55 | + - certificate_path (string): path for TLS/SSL certificate verification if behind local proxy |
| 56 | + - requests_proxy (string): proxy server and port, if needed, for HTTPS |
| 57 | + - wait_on_rate_limit (boolean): retry if 429 rate limit error encountered? |
| 58 | + - nginx_429_retry_wait_time (integer): Nginx 429 retry wait time |
| 59 | + - action_batch_retry_wait_time (integer): action batch concurrency error retry wait time |
| 60 | + - retry_4xx_error (boolean): retry if encountering other 4XX error (besides 429)? |
| 61 | + - retry_4xx_error_wait_time (integer): other 4XX error retry wait time |
| 62 | + - maximum_retries (integer): retry up to this many times when encountering 429s or other server-side errors |
| 63 | + - output_log (boolean): create an output log file? |
| 64 | + - log_path (string): path to output log; by default, working directory of script if not specified |
| 65 | + - log_file_prefix (string): log file name appended with date and timestamp |
| 66 | + - print_console (boolean): print logging output to console? |
| 67 | + - suppress_logging (boolean): disable all logging? you're on your own then! |
| 68 | + - inherit_logging_config (boolean): Inherits your own logger instance |
| 69 | + - simulate (boolean): simulate POST/PUT/DELETE calls to prevent changes? |
| 70 | + - be_geo_id (string): optional partner identifier for API usage tracking; can also be set as an environment variable BE_GEO_ID |
| 71 | + - caller (string): optional identifier for API usage tracking; can also be set as an environment variable MERAKI_PYTHON_SDK_CALLER |
| 72 | + - use_iterator_for_get_pages (boolean): list* methods will return an iterator with each object instead of a complete list with all items |
| 73 | + """ |
| 74 | + |
| 75 | + def __init__(self, |
| 76 | + api_key=None, |
| 77 | + base_url=DEFAULT_BASE_URL, |
| 78 | + single_request_timeout=SINGLE_REQUEST_TIMEOUT, |
| 79 | + certificate_path=CERTIFICATE_PATH, |
| 80 | + requests_proxy=REQUESTS_PROXY, |
| 81 | + wait_on_rate_limit=WAIT_ON_RATE_LIMIT, |
| 82 | + nginx_429_retry_wait_time=NGINX_429_RETRY_WAIT_TIME, |
| 83 | + action_batch_retry_wait_time=ACTION_BATCH_RETRY_WAIT_TIME, |
| 84 | + retry_4xx_error=RETRY_4XX_ERROR, |
| 85 | + retry_4xx_error_wait_time=RETRY_4XX_ERROR_WAIT_TIME, |
| 86 | + maximum_retries=MAXIMUM_RETRIES, |
| 87 | + output_log=OUTPUT_LOG, log_path=LOG_PATH, |
| 88 | + log_file_prefix=LOG_FILE_PREFIX, |
| 89 | + print_console=PRINT_TO_CONSOLE, |
| 90 | + suppress_logging=SUPPRESS_LOGGING, |
| 91 | + simulate=SIMULATE_API_CALLS, |
| 92 | + be_geo_id=BE_GEO_ID, |
| 93 | + caller=MERAKI_PYTHON_SDK_CALLER, |
| 94 | + use_iterator_for_get_pages=USE_ITERATOR_FOR_GET_PAGES, |
| 95 | + inherit_logging_config=INHERIT_LOGGING_CONFIG |
| 96 | + ): |
| 97 | + |
| 98 | + # Check API key |
| 99 | + api_key = api_key or os.environ.get(API_KEY_ENVIRONMENT_VARIABLE) |
| 100 | + if not api_key: |
| 101 | + raise APIKeyError() |
| 102 | + |
| 103 | + # Pull the BE GEO ID from an environment variable if present |
| 104 | + be_geo_id = be_geo_id or os.environ.get('BE_GEO_ID') |
| 105 | + |
| 106 | + # Pull the caller from an environment variable if present |
| 107 | + caller = caller or os.environ.get('MERAKI_PYTHON_SDK_CALLER') |
| 108 | + |
| 109 | + inherit_logging_config = inherit_logging_config |
| 110 | + |
| 111 | + # Configure logging |
| 112 | + if not suppress_logging: |
| 113 | + self._logger = logging.getLogger(__name__) |
| 114 | + |
| 115 | + if not inherit_logging_config: |
| 116 | + self._logger.setLevel(logging.DEBUG) |
| 117 | + |
| 118 | + formatter = logging.Formatter( |
| 119 | + fmt='%(asctime)s %(name)12s: %(levelname)8s > %(message)s', |
| 120 | + datefmt='%Y-%m-%d %H:%M:%S' |
| 121 | + ) |
| 122 | + handler_console = logging.StreamHandler() |
| 123 | + handler_console.setFormatter(formatter) |
| 124 | + |
| 125 | + if output_log: |
| 126 | + if log_path and log_path[-1] != '/': |
| 127 | + log_path += '/' |
| 128 | + self._log_file = f'{log_path}{log_file_prefix}_log__{datetime.now():%Y-%m-%d_%H-%M-%S}.log' |
| 129 | + handler_log = logging.FileHandler( |
| 130 | + filename=self._log_file |
| 131 | + ) |
| 132 | + handler_log.setFormatter(formatter) |
| 133 | + |
| 134 | + if output_log and not self._logger.hasHandlers(): |
| 135 | + self._logger.addHandler(handler_log) |
| 136 | + if print_console: |
| 137 | + handler_console.setLevel(logging.INFO) |
| 138 | + self._logger.addHandler(handler_console) |
| 139 | + elif print_console and not self._logger.hasHandlers(): |
| 140 | + self._logger.addHandler(handler_console) |
| 141 | + else: |
| 142 | + self._logger = None |
| 143 | + |
| 144 | + # Creates the API session |
| 145 | + self._session = RestSession( |
| 146 | + logger=self._logger, |
| 147 | + api_key=api_key, |
| 148 | + base_url=base_url, |
| 149 | + single_request_timeout=single_request_timeout, |
| 150 | + certificate_path=certificate_path, |
| 151 | + requests_proxy=requests_proxy, |
| 152 | + wait_on_rate_limit=wait_on_rate_limit, |
| 153 | + nginx_429_retry_wait_time=nginx_429_retry_wait_time, |
| 154 | + action_batch_retry_wait_time=action_batch_retry_wait_time, |
| 155 | + retry_4xx_error=retry_4xx_error, |
| 156 | + retry_4xx_error_wait_time=retry_4xx_error_wait_time, |
| 157 | + maximum_retries=maximum_retries, |
| 158 | + simulate=simulate, |
| 159 | + be_geo_id=be_geo_id, |
| 160 | + caller=caller, |
| 161 | + use_iterator_for_get_pages=use_iterator_for_get_pages |
| 162 | + ) |
| 163 | + |
| 164 | + # API endpoints by section |
| 165 | + self.organizations = Organizations(self._session) |
| 166 | + self.networks = Networks(self._session) |
| 167 | + self.devices = Devices(self._session) |
| 168 | + self.appliance = Appliance(self._session) |
| 169 | + self.camera = Camera(self._session) |
| 170 | + self.cellularGateway = CellularGateway(self._session) |
| 171 | + self.insight = Insight(self._session) |
| 172 | + self.sm = Sm(self._session) |
| 173 | + self.switch = Switch(self._session) |
| 174 | + self.wireless = Wireless(self._session) |
| 175 | + |
| 176 | + # Batch definitions |
| 177 | + self.batch = Batch() |
0 commit comments