### Setup Development Environment Source: https://github.com/meraki/dashboard-api-python/blob/main/CONTRIBUTING.md Clone the repository and install development dependencies using uv. ```bash git clone https://github.com/meraki/dashboard-api-python.git cd dashboard-api-python uv sync ``` -------------------------------- ### Install and Import Meraki SDK and OS Modules Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/merakiSSIDLimitsChecker.ipynb Installs the meraki SDK and imports necessary modules. Ensure environment variables for API key are set up. For Google Colab, specific setup for environment variables might be needed. ```python # Install the relevant modules. If you are using a local editor (e.g. VS Code, rather than Colab) you can run these commands, without the preceding %, via a terminal. NB: Run `pip install meraki==` to find the latest version of the Meraki SDK. %pip install meraki # If you are using Google Colab, please ensure you have set up your environment variables as linked above, then delete the two lines of ''' to activate the following code: """ %pip install colab-env -qU import colab_env """ # Rely on meraki SDK and os import meraki # We're also going to import Python's built-in JSON module, but only to make the console output pretty. In production, you wouldn't need any of the printing calls at all, nor this import! import json # Treat your API key like a password. Store it in your environment variables as 'MERAKI_DASHBOARD_API_KEY' and let the SDK call it for you. # Or, call it manually after importing Python's os module: # API_KEY = os.getenv('MERAKI_DASHBOARD_API_KEY') # Initialize the Dashboard connection. dashboard = meraki.DashboardAPI(suppress_logging=True) ``` -------------------------------- ### Install uv Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Install uv, a fast and modern Python package and environment manager, if you haven't already. ```bash uv sync ``` -------------------------------- ### Install Latest Meraki SDK Source: https://github.com/meraki/dashboard-api-python/blob/main/VERSIONING.md Use this command to install or upgrade to the latest stable release of the Meraki SDK. ```sh pip install --upgrade meraki ``` -------------------------------- ### Install and Import Meraki SDK and Utilities Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/merakiOfflineSwitchFinder.ipynb Installs necessary libraries (meraki, tablib) and imports them along with os and json. Initializes the Meraki DashboardAPI connection using an environment variable for the API key. Assumes environment variables are set up. ```python # Install the relevant modules. If you are using a local editor (e.g. VS Code, rather than Colab) you can run these commands, without the preceding %, via a terminal. NB: Run `pip install meraki==` to find the latest version of the Meraki SDK. %pip install meraki %pip install tablib # If you are using Google Colab, please ensure you have set up your environment variables as linked above, then delete the two lines of ''' to activate the following code: """ %pip install colab-env -qU import colab_env """ # Rely on meraki SDK, os, and tablib -- more on tablib later import meraki import os import tablib # We're also going to import Python's built-in JSON module, but only to make the console output pretty. In production, you wouldn't need any of the printing calls at all, nor this import! import json # Setting API key this way, and storing it in the env variables, lets us keep the sensitive API key out of the script itself # The meraki.DashboardAPI() method does not require explicitly passing this value; it will check the environment for a variable # called 'MERAKI_DASHBOARD_API_KEY' on its own. In this case, API_KEY is shown simply as an reference to where that information is # stored. API_KEY = os.getenv("MERAKI_DASHBOARD_API_KEY") # Initialize the Dashboard connection. dashboard = meraki.DashboardAPI() ``` -------------------------------- ### Install and Import Meraki SDK and Utilities Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceRestore.ipynb Installs necessary Python modules and imports the Meraki SDK, OS module for environment variables, openpyxl for Excel manipulation, and JSON for pretty printing. Initializes the Meraki Dashboard API connection. ```python # Install the relevant modules. If you are using a local editor (e.g. VS Code, rather than Colab) you can run these commands, without the preceding %, via a terminal. NB: Run `pip install meraki==` to find the latest version of the Meraki SDK. Uncomment these lines if you're using Google Colab. # %pip install meraki # %pip install openpyxl # If you are using Google Colab, please ensure you have set up your environment variables as linked above, then delete the two lines of ''' to activate the following code: """ %pip install colab-env -qU import colab_env """ # The Meraki SDK import meraki # The built-in OS module, to read environment variables # We're also going to import Python's built-in JSON module, but only to make the console output pretty. In production, you wouldn't need any of the printing calls at all, nor this import! import json # The openpyxl module, to manipulate Excel files import openpyxl # The datetime module, to generate timestamps # Treat your API key like a password. Store it in your environment variables as 'MERAKI_DASHBOARD_API_KEY' and let the SDK call it for you. # Or, call it manually after importing Python's os module: # API_KEY = os.getenv('MERAKI_DASHBOARD_API_KEY') # Initialize the Dashboard connection. dashboard = meraki.DashboardAPI(suppress_logging=True) # We'll also create a few reusable strings for later interactivity. string_constants = dict() string_constants["CONFIRM"] = ( 'OK, are you sure you want to do this? This script does not have an "undo" feature.' ) string_constants["CANCEL"] = "OK. Operation canceled." string_constants["WORKING"] = "Working..." string_constants["COMPLETE"] = "Operation complete." string_constants["NETWORK_SELECTED"] = "Network selected." string_constants["NO_VALID_OPTIONS"] = ( "There are no valid options. Please try again with an API key that has access to the appropriate resources." ) # Some of the parameters we'll work with are optional. This string defines what value will be put into a cell corresponding with a parameter that is not set on that rule. string_constants["NOT_APPLICABLE"] = "N/A" # This script is interactive; user choices and data will be stored here. user_choices = dict() user_data = dict() ``` -------------------------------- ### Install Meraki SDK in Colab Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/README.md Installs the Meraki SDK in a Colab environment. Run this in a separate cell at the top of your notebook. ```python %pip install meraki ``` -------------------------------- ### Install and Import Meraki SDK and Utilities Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceBackup.ipynb Installs necessary Python modules and imports the Meraki SDK, OS module, openpyxl for Excel manipulation, and datetime for timestamps. Initializes the Dashboard API connection. ```python # Install the relevant modules. If you are using a local editor (e.g. VS Code, rather than Colab) you can run these commands, without the preceding %, via a terminal. NB: Run `pip install meraki==` to find the latest version of the Meraki SDK. Uncomment these lines to run them in Google Colab. # %pip install meraki # %pip install openpyxl # If you are using Google Colab, please ensure you have set up your environment variables as linked above, then delete the two lines of ''' to activate the following code: """ %pip install colab-env -qU import colab_env """ # The Meraki SDK import meraki # The built-in OS module, to read environment variables # We're also going to import Python's built-in JSON module, but only to make the console output pretty. In production, you wouldn't need any of the printing calls at all, nor this import! import json # The openpyxl module, to manipulate Excel files import openpyxl # The datetime module, to generate timestamps import datetime # Treat your API key like a password. Store it in your environment variables as 'MERAKI_DASHBOARD_API_KEY' and let the SDK call it for you. # Or, call it manually after importing Python's os module: # API_KEY = os.getenv('MERAKI_DASHBOARD_API_KEY') # Initialize the Dashboard connection. dashboard = meraki.DashboardAPI(suppress_logging=True) # We'll also create a few reusable strings for later interactivity. string_constants = dict() string_constants["CONFIRM"] = ( 'OK, are you sure you want to do this? This script does not have an "undo" feature.' ) string_constants["CANCEL"] = "OK. Operation canceled." string_constants["WORKING"] = "Working..." string_constants["COMPLETE"] = "Operation complete." string_constants["NETWORK_SELECTED"] = "Network selected." string_constants["NO_VALID_OPTIONS"] = ( "There are no valid options. Please try again with an API key that has access to the appropriate resources." ) # Some of the parameters we'll work with are optional. This string defines what value will be put into a cell corresponding with a parameter that is not set on that rule. string_constants["NOT_APPLICABLE"] = "N/A" # This script is interactive; user choices and data will be stored here. user_choices = dict() user_data = dict() ``` -------------------------------- ### Install Meraki SDK via Terminal Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/README.md Installs the Meraki SDK using pip in a terminal environment. This command can be used for other packages as well. ```shell pip install meraki ``` -------------------------------- ### Install Meraki Python Library with Pip Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Install the Meraki Python library using pip. If you have both Python 2 and 3 installed, use 'pip3' and 'python3'. ```bash pip install meraki ``` ```bash pip3 install meraki ``` -------------------------------- ### Install Specific Meraki Python Library Version Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Install a specific version of the Meraki Python library using pip. Use 'pip install meraki==' to list available versions. Avoid versions starting with '0' as they are end-of-life. ```bash pip install meraki==1.34.0 ``` -------------------------------- ### Install Meraki Python Library Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Install or upgrade the Meraki Python library using pip or uv. Ensure you are using Python 3.10+. ```bash pip install --upgrade meraki ``` ```bash uv pip install --upgrade meraki ``` -------------------------------- ### Install Generator Dependencies Source: https://github.com/meraki/dashboard-api-python/blob/main/generator/readme.md Installs the necessary dependencies for the Meraki API library generator using uv. Ensure Python 3.11 or later is installed. ```shell uv sync --group generator ``` -------------------------------- ### Install colab-env and import modules in Colab Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/README.md Installs the 'colab-env' package for simulating environment variables in Google Colab and imports necessary modules. Run this cell first to set up the environment. ```python %pip install colab-env -qU import colab_env import os ``` -------------------------------- ### Run Generator Source: https://github.com/meraki/dashboard-api-python/blob/main/CONTRIBUTING.md Install generator dependencies and run the library generation script. ```bash uv sync --group generator uv run python generator/generate_library.py ``` -------------------------------- ### Install Package in Colab Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/README.md Use this command in a Colab notebook to install any Python package. Ensure this is run before using the package. ```python %pip install PACKAGE_NAME ``` -------------------------------- ### Synchronous API Usage Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Demonstrates how to instantiate the client and make a synchronous API call to get organizations. ```APIDOC ## Synchronous API Call Example ### Description This example shows how to initialize the Meraki Dashboard API client and retrieve a list of organizations accessible by the API key. ### Method ```python import meraki # Instantiate the client dashboard = meraki.DashboardAPI() # Make an API call to get organizations my_orgs = dashboard.organizations.getOrganizations() ``` ### Keyword Argument Validation To enable validation for keyword arguments, instantiate the client with `validate_kwargs=True`. ```python dashboard = meraki.DashboardAPI(validate_kwargs=True) # Example of an unrecognized kwarg that will log a warning dashboard.networks.updateNetwork(networkId, nme="HQ") ``` ``` -------------------------------- ### Check Installed Meraki Python Library Version Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Verify the currently installed version of the Meraki Python library using pip. ```bash pip show meraki ``` -------------------------------- ### Get Meraki Organizations and Prompt User Choice Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceRestore.ipynb Fetches all organizations accessible by the API key and then prompts the user to select one using the UserChoice class. This is a common step before making network-specific API calls. ```python # getOrganizations will return all orgs to which the supplied API key has access user_choices["all_organizations"] = dashboard.organizations.getOrganizations() # Prompt the user to pick an organization. user_choices["organization"] = UserChoice( options_list=user_choices["all_organizations"], subject_of_choice="organizations", single_option_noun="organization", no_valid_options_message=string_constants["NO_VALID_OPTIONS"], ) ``` -------------------------------- ### Fetching OpenAPI v3 Spec Source: https://github.com/meraki/dashboard-api-python/blob/main/docs/OASV3-MIGRATION.md Demonstrates how to fetch the OpenAPI v3 specification from the Meraki API using an HTTP GET request with a specified version parameter. ```python requests.get("https://api.meraki.com/api/v1/openapiSpec", params={"version": 3}) ``` -------------------------------- ### Make an Async Dashboard API Call Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Make asynchronous API calls using the `await client.section.operation` format. This example retrieves organizations asynchronously. ```python my_orgs = await aiomeraki.organizations.getOrganizations() ``` -------------------------------- ### Make a Dashboard API Call Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Make API calls to the Meraki dashboard using the format client.scope.operation. This example retrieves a list of organizations accessible by the API key. ```python my_orgs = dashboard.organizations.getOrganizations() ``` -------------------------------- ### Create Excel Workbook for Meraki Uplink Preferences Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceBackup.ipynb Initializes an Excel workbook with formatted worksheets and headers for WAN uplink preferences, VPN uplink preferences, and custom performance classes. Use this to set up the structure for your backup. ```python def create_workbook(): # Create a workbook with the appropriate column headers and/or worksheets # First we'll create the workbook, then we'll design the worksheets. Just like in Excel, by default, the workbook has one worksheet, titled 'Sheet'. new_workbook = openpyxl.Workbook() # We'll specify that the active worksheet is our wan_prefs_worksheet wan_prefs_worksheet = new_workbook.active # Let's rename the worksheet from 'Sheet' to something more descriptive wan_prefs_worksheet.title = "wanUplinkPreferences" # Name the columns for the wan_prefs_worksheet. Think of this like a single-line CSV: wan_title_row_headers = ( "Protocol", "Source", "Src port", "Destination", "Dst port", "Preferred uplink", ) # Add that title row to the worksheet wan_prefs_worksheet.append(wan_title_row_headers) # Let's make the title row bold for easier reading for row in wan_prefs_worksheet.iter_rows(): for cell in row: cell.font = openpyxl.styles.Font(bold=True) # Now let's do the same for the VPN uplink preferences, and custom performance classes. # First, create a separate worksheet for the VPN uplink preferences vpn_prefs_worksheet = new_workbook.create_sheet(title="vpnUplinkPreferences") custom_performance_classes_worksheet = new_workbook.create_sheet( title="customPerformanceClasses" ) # Name the columns for the vpn_prefs_worksheet and custom_performance_classes_worksheet. vpn_title_row_headers = ( "Type", "Protocol or App ID", "Source or App Name", "Src port", "Destination", "Dst port", "Preferred uplink", "Failover criterion", "Performance class type", "Performance class name", "Performance class ID", ) classes_title_row_headers = ( "ID", "Name", "Max Latency", "Max Jitter", "Max Loss Percentage", ) # Add the title rows to the appropriate worksheets vpn_prefs_worksheet.append(vpn_title_row_headers) custom_performance_classes_worksheet.append(classes_title_row_headers) # Let's make those title rows bold, too for row in vpn_prefs_worksheet.iter_rows(): for cell in row: cell.font = openpyxl.styles.Font(bold=True) for row in custom_performance_classes_worksheet.iter_rows(): for cell in row: cell.font = openpyxl.styles.Font(bold=True) print("Created formatted workbook.") return new_workbook ``` -------------------------------- ### Fetch Organization Devices and Statuses Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/merakiOfflineSwitchFinder.ipynb Retrieves all devices and their statuses for a given organization. This is the initial step to gather data for analysis. ```python devices = dashboard.organizations.getOrganizationDevices( organizationId=firstOrganizationId ) devices_statuses = dashboard.organizations.getOrganizationDevicesStatuses( organizationId=firstOrganizationId ) ``` -------------------------------- ### Import Meraki Async Library Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Import the asynchronous version of the Meraki library for concurrent operations using async/await syntax. ```python import meraki.aio ``` -------------------------------- ### Instantiate Meraki Dashboard API Client Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Instantiate the DashboardAPI client. You can optionally specify parameters during instantiation. ```python dashboard = meraki.DashboardAPI() ``` -------------------------------- ### Identify and Select Networks with MX Appliances Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceRestore.ipynb Fetches all networks for an organization and filters them to identify those with MX appliances. It then prompts the user to select a network from the filtered list. ```python user_choices["all_networks"] = dashboard.organizations.getOrganizationNetworks( organizationId=user_choices["organization"].id ) # Find the networks with appliances user_choices["networks_with_appliances"] = [ network for network in user_choices["all_networks"] if "appliance" in network["productTypes"] ] # If any are found, let the user choose a network. Otherwise, let the user know that none were found. The logic for this class is defined in a cell above. user_choices["network_choice"] = UserChoice( options_list=user_choices["networks_with_appliances"], subject_of_choice="networks with appliances", single_option_noun="network", ) ``` -------------------------------- ### Instantiate Async Meraki Dashboard API Client Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Instantiate the AsyncDashboardAPI client using an `async with` statement to ensure client sessions are properly closed after use. ```python async with meraki.aio.AsyncDashboardAPI() as aiomeraki: ``` -------------------------------- ### Create Changelog Fragment (Towncrier) Source: https://github.com/meraki/dashboard-api-python/blob/main/CONTRIBUTING.md Create a changelog fragment using the towncrier command. This is an alternative to using echo. ```bash # Or via towncrier uv run towncrier create -c "Retry on 429 now honors Retry-After." 1234.fixed.md ``` -------------------------------- ### Define Function to Get Uplink Classes and Preferences Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceBackup.ipynb Defines a reusable function to fetch uplink selection preferences and custom performance classes for a given network. This function uses the Meraki Dashboard API SDK. ```python def getNetworkClassesAndPrefs(*, networkId): # Get the uplink preferences (WAN and VPN) uplink_prefs = dashboard.appliance.getNetworkApplianceTrafficShapingUplinkSelection( networkId=networkId ) # Get the custom performance classes custom_performance_classes = ( dashboard.appliance.getNetworkApplianceTrafficShapingCustomPerformanceClasses( networkId=networkId ) ) # Create a dict network_classes_and_prefs with both that we can return and call later network_classes_and_prefs = { "uplinkPrefs": uplink_prefs, "customPerformanceClasses": custom_performance_classes, } return network_classes_and_prefs user_data["current_classes_and_prefs"] = getNetworkClassesAndPrefs( networkId=user_choices["network"].id ) ``` -------------------------------- ### Run Tests with uv Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Execute tests using uv to manage the Python environment and dependencies. ```bash uv run pytest ``` -------------------------------- ### Build and Save Workbook Execution Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceBackup.ipynb This Python code executes the functions to create, populate, and save a workbook containing Meraki uplink preferences. It assumes `create_workbook`, `add_custom_performance_classes_to_workbook`, `add_wan_prefs_to_workbook`, `add_vpn_prefs_to_workbook`, and `save_workbook` are defined. ```python uplink_prefs_workbook = create_workbook() add_custom_performance_classes_to_workbook(uplink_prefs_workbook) add_wan_prefs_to_workbook(uplink_prefs_workbook) add_vpn_prefs_to_workbook(uplink_prefs_workbook) save_workbook(uplink_prefs_workbook) ``` -------------------------------- ### Create Changelog Fragment (Issue Linked) Source: https://github.com/meraki/dashboard-api-python/blob/main/CONTRIBUTING.md Create a changelog fragment for a specific issue using echo. This is for user-facing changes. ```bash # Issue-linked echo "Retry on 429 now honors Retry-After." > changelog.d/1234.fixed.md ``` -------------------------------- ### Generate OASv3 Library Source: https://github.com/meraki/dashboard-api-python/blob/main/docs/OASV3-MIGRATION.md Run the Python script to generate the library based on the live v3 OpenAPI Specification. ```bash python generator/generate_library_oasv3.py ``` -------------------------------- ### Import Meraki Library Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Import the Meraki library at the top of your Python script to begin using its functionalities. ```python import meraki ``` -------------------------------- ### Asynchronous API Usage Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Illustrates how to use the asynchronous version of the client with asyncio to make API calls. ```APIDOC ## Asynchronous API Usage Example ### Description This example demonstrates how to use the `meraki.aio.AsyncDashboardAPI` client within an asyncio event loop to make asynchronous API calls. ### Method ```python import meraki.aio import asyncio async def main(): async with meraki.aio.AsyncDashboardAPI() as aiomeraki: # Make an asynchronous API call to get organizations my_orgs = await aiomeraki.organizations.getOrganizations() print(my_orgs) if __name__ == "__main__": asyncio.run(main()) ``` ``` -------------------------------- ### Print WAN Preferences Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceRestore.ipynb Prints the WAN preferences section from the loaded uplink preferences data. Use this to inspect the backed-up WAN settings. ```python printj(user_data["loaded_combined_uplink_prefs"]["wanPrefs"]) ``` -------------------------------- ### Preview Rendered Changelog Source: https://github.com/meraki/dashboard-api-python/blob/main/CONTRIBUTING.md Preview the rendered changelog without consuming fragments using towncrier build --draft. ```bash # Preview the rendered changelog without consuming fragments uv run towncrier build --draft --version "$(grep '^version' pyproject.toml | sed 's/version = "(.*")/")" ``` -------------------------------- ### Load Uplink Preferences Workbook Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceRestore.ipynb Loads the uplink preferences from a specified workbook file. This is the initial step for any backup or restore operation. ```python user_data["loaded_combined_uplink_prefs"] = load_uplink_prefs_workbook( WORKBOOK_FILENAME ) ``` -------------------------------- ### Load Uplink Preferences Workbook Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceRestore.ipynb Loads custom performance classes, WAN uplink preferences, and VPN uplink preferences from an Excel workbook. Requires the 'openpyxl' library. ```python import openpyxl def load_uplink_prefs_workbook(workbook_filename): # Create a workbook object out of the actual workbook file loaded_workbook = openpyxl.load_workbook(workbook_filename, read_only=True) # Create empty rule lists to which we can add the rules defined in the workbook loaded_custom_performance_classes = [] loaded_wan_uplink_prefs = [] loaded_vpn_uplink_prefs = [] # Open the worksheets loaded_custom_performance_classes_worksheet = loaded_workbook[ "customPerformanceClasses" ] loaded_wan_prefs_worksheet = loaded_workbook["wanUplinkPreferences"] loaded_vpn_prefs_worksheet = loaded_workbook["vpnUplinkPreferences"] ## CUSTOM PERFORMANCE CLASSES ## # We'll also count the number of classes to help the user know that it's working. performance_class_count = 0 # For reference, the expected column order is # ID [0], Name [1], Max Latency [2], Max Jitter [3], Max Loss Percentage [4] # Append each performance class loaded_custom_performance_classes for row in loaded_custom_performance_classes_worksheet.iter_rows(min_row=2): # Let's start with an empty rule dictionary to which we'll add the relevant parameters performance_class = {} # Append the values performance_class["customPerformanceClassId"] = row[0].value performance_class["name"] = row[1].value performance_class["maxLatency"] = row[2].value performance_class["maxJitter"] = row[3].value performance_class["maxLossPercentage"] = row[4].value # Append the performance class to the loaded_custom_performance_classes list loaded_custom_performance_classes.append(performance_class) performance_class_count += 1 print(f"Loaded {performance_class_count} custom performance classes.") ## WAN PREFERENCES ## # We'll also count the number of rules to help the user know that it's working. rule_count = 0 # For reference, the expected column order is # Protocol [0], Source [1], Src port [2], Destination [3], Dst port [4], Preferred uplink [5] # Append each WAN preference to loaded_wan_uplink_prefs for row in loaded_wan_prefs_worksheet.iter_rows(min_row=2): # Let's start with an empty rule dictionary to which we'll add the relevant parameters rule = {} # We know that there will always be a preferred uplink rule_preferred_uplink = row[5].value.lower() # The first column is Protocol rule_protocol = row[0].value.lower() # Source column is [1] rule_source = row[1].value # Destination column is [3] rule_destination = row[3].value.lower() # Assemble the rule into a single Python object that uses the syntax that the corresponding API call expects if rule_protocol == "any": # Since protocol is 'any' then src and dst ports are also 'any' rule_src_port = "any" rule_dst_port = "any" # Protocol is any, so leave out the port numbers rule_value = { "protocol": rule_protocol, "source": {"cidr": rule_source}, "destination": {"cidr": rule_destination}, } else: # Since protocol is not 'any', we pass these as-is rule_src_port = row[2].value rule_dst_port = row[4].value # Rule isn't any, so we need the port numbers rule_value = { "protocol": rule_protocol, "source": {"port": rule_src_port, "cidr": rule_source}, "destination": {"port": rule_dst_port, "cidr": rule_destination}, } # Append the trafficFilters param to the rule rule["trafficFilters"] = [ { "type": "custom", # This worksheet doesn't have any Type column "value": rule_value, } ] # Append the preferredUplink param to the rule rule["preferredUplink"] = rule_preferred_uplink # Append the rule to the loaded_wan_uplink_prefs list loaded_wan_uplink_prefs.append(rule) rule_count += 1 print(f"Loaded {rule_count} WAN uplink preferences.") ## VPN PREFERENCES ## # For reference, the expected column order is # Type [0], Protocol or App ID [1], Source or App Name [2], Src port [3], Destination [4], # Dst port [5], Preferred uplink [6], Failover criterion [7], Performance class type [8], # Performance class name [9], Performance class ID [10] # We'll also count the number of rules to help the user know that it's working. rule_count = 0 # Append each WAN preference to loaded_wan_uplink_prefs for row in loaded_vpn_prefs_worksheet.iter_rows(min_row=2): ``` -------------------------------- ### Run Async Code with asyncio Source: https://github.com/meraki/dashboard-api-python/blob/main/README.md Run your asynchronous Meraki API code within an event loop using `asyncio.run()`. Replace `my_async_entry_point` with your main async function. ```python import asyncio if __name__ == "__main__": # replace my_async_entry_point with the name of your entry point method asyncio.run(my_async_entry_point()) ``` -------------------------------- ### Run Meraki API Library Generator Source: https://github.com/meraki/dashboard-api-python/blob/main/generator/readme.md Executes the Python script to generate the Meraki Dashboard API library locally. Replace YOUR_ORG_ID and YOUR_API_KEY with your specific credentials. On Windows, you might need to prepend '."' to the script name. ```shell uv run --group generator python generate_library.py -v locally_generated -o YOUR_ORG_ID -k YOUR_API_KEY ``` -------------------------------- ### UserChoice Class for CLI Options Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceRestore.ipynb A reusable class for creating command-line interface prompts to allow users to choose from a list of options. It handles displaying options, validating input, and assigning the chosen ID and name. ```python class UserChoice: """A re-usable CLI option prompt.""" def __init__( self, options_list=[], subject_of_choice="available options", single_option_noun="option", id_parameter="id", name_parameter="name", action_verb="choose", no_valid_options_message="no valid options", ): self.options_list = options_list # options_list is a list of dictionaries containing attributes id_parameter and name_parameter self.subject_of_choice = subject_of_choice # subject_of_choice is a string that names the subject of the user's choice. It is typically a plural noun. self.single_option_noun = single_option_noun # single_option_noun is a string that is a singular noun corresponding to the subject_of_choice self.id_parameter = id_parameter # id_parameter is a string that represents the name of the sub-parameter that serves as the ID value for the option in options_list. It should be a unique value for usability. self.name_parameter = name_parameter # name_paraemter is a string that represents the name of the sub-parameter that serves as the name value for the option in options_list. It does not need to be unique. self.action_verb = action_verb # action_verb is a string that represents the verb of the user's action. For example, to "choose" self.no_valid_options_message = no_valid_options_message # no_valid_options_message is a string that represents an error message if options_list is empty # Confirm there are options in the list if len(self.options_list): print(f"We found {len(self.options_list)} {self.subject_of_choice}:") # Label each option and show the user their choices. option_index = 0 for option in self.options_list: print( f"{option_index}. {option[self.id_parameter]} with name {option[self.name_parameter]}" ) option_index += 1 print( f"Which {self.single_option_noun} would you like to {self.action_verb}?" ) self.active_option = int(input(f"Choose 0-{option_index - 1}:")) # Ask until the user provides valid input. while self.active_option not in list(range(option_index)): print( f"{self.active_option} is not a valid choice. Which {self.single_option_noun} would you like to {self.action_verb}?" ) self.active_option = int(input(f"Choose 0-{option_index - 1}:")) print( f"Your {self.single_option_noun} is {self.options_list[self.active_option][self.name_parameter]}." ) # Assign the class id and name vars to the chosen item's self.id = self.options_list[self.active_option][self.id_parameter] self.name = self.options_list[self.active_option][self.name_parameter] ``` -------------------------------- ### Check Meraki SDK and API Versions Source: https://github.com/meraki/dashboard-api-python/blob/main/VERSIONING.md For SDK v3.x and later, use this Python code to print the current SDK version and the corresponding API version it targets. This helps in debugging and ensuring compatibility. ```python import meraki print(meraki.__version__) # SDK version, e.g. "4.1.0b2" print(meraki.__api_version__) # API version, e.g. "1.70.0-beta.2" ``` -------------------------------- ### Interactive Prompt to Remove SSID Limits Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/merakiSSIDLimitsChecker.ipynb Provides an interactive prompt to confirm the removal of identified SSID-level bandwidth limits. Includes confirmation steps and messages for working and completion status. Use with care, as there is no undo feature. ```python # Re-used strings string_constants = dict() string_constants["CONFIRM"] = ( 'OK, are you sure you want to do this? This script does not have an "undo" feature.' ) string_constants["CANCEL"] = "OK. Operation canceled." string_constants["WORKING"] = "Working..." string_constants["COMPLETE"] = "Operation complete." # Let's give the user the option to clear those bandwidth limits if len(organization_ssids_with_limits): print("Would you like to remove all SSID-level bandwidth limits?") if input("([Y]es/[N]o):") in ["Y", "y", "Yes", "yes", "ye", "Ye"]: print(string_constants["CONFIRM"]) if input("([Y]es/[N]o):") in ["Y", "y", "Yes", "yes", "ye", "Ye"]: print(string_constants["WORKING"]) removeSsidLimits(organization_ssids_with_limits) print(string_constants["COMPLETE"]) else: print(string_constants["CANCEL"]) else: print(string_constants["CANCEL"]) ``` -------------------------------- ### Identify and Select Network with MX Appliance Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceBackup.ipynb Filters networks to find those with MX appliances and prompts the user to select one. Requires the Meraki Dashboard API SDK to be initialized. ```python # Make a list of all networks in the org user_choices["all_networks"] = dashboard.organizations.getOrganizationNetworks( organizationId=user_choices["organization"].id ) # Find the networks with appliances user_choices["networks_with_appliances"] = [ network for network in user_choices["all_networks"] if "appliance" in network["productTypes"] ] # If any are found, let the user choose a network. Otherwise, let the user know that none were found. The logic for this class is defined in a cell above. user_choices["network"] = UserChoice( options_list=user_choices["networks_with_appliances"], subject_of_choice="networks with appliances", single_option_noun="network", ) ``` -------------------------------- ### Prompt User to Pick an Organization Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceBackup.ipynb This snippet re-uses the UserChoice class to prompt the user to select an organization from a list obtained via the API. Ensure the Meraki dashboard API client is initialized. ```python # getOrganizations will return all orgs to which the supplied API key has access user_choices["all_organizations"] = dashboard.organizations.getOrganizations() # Prompt the user to pick an organization. user_choices["organization"] = UserChoice( options_list=user_choices["all_organizations"], subject_of_choice="organizations", single_option_noun="organization", ) ``` -------------------------------- ### Add VPN Preferences to Workbook Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceBackup.ipynb Appends VPN preference rules to a workbook. Increments a rule counter for each rule added. ```python # We then add that row to the worksheet. vpn_prefs_worksheet.append(rule_row) # increase the rule_count rule_count += 1 print(f"Added {rule_count} rules to wanUplinkPreferences.") return workbook ``` -------------------------------- ### Update VPN Preferences with Performance Class ID Updates Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceRestore.ipynb Iterates through loaded VPN preferences and updates custom performance class IDs based on provided mappings. Returns the count of updated preferences. ```python def update_vpn_prefs_performance_class_ids( *, loaded_vpn_prefs, performance_class_id_updates ): vpn_prefs_updates = 0 # For each update in the ID updates list for update in performance_class_id_updates: # For each rule in loaded_vpn_prefs for rule in loaded_vpn_prefs: # If the rule's performance class type is set if "performanceClass" in rule.keys(): # If the rule's performance class type is custom if rule["performanceClass"]["type"] == "custom": # And if the rule's customPerformanceClassId matches one from our ID updates list if ( rule["performanceClass"]["customPerformanceClassId"] == update["loaded_id"] ): # Then we update it with the new ID rule["performanceClass"]["customPerformanceClassId"] = update[ "current_id" ] vpn_prefs_updates += 1 return vpn_prefs_updates ``` -------------------------------- ### Format Data for Excel using Tablib Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/merakiOfflineSwitchFinder.ipynb Converts the list of offline switch data into a tabular format using the `tablib` library, making it easy to import into spreadsheet applications like Excel. ```python # Let's convert that JSON-formatted data to a tabular dataset. You can copy/paste this into Excel, or write additional Python to create a new Excel file entirely! excel_formatted = tablib.import_set( json.dumps(devices_last_reported_times), format="json" ) # Let's see how it looks! print(excel_formatted) ``` -------------------------------- ### Restore Meraki Uplink Preferences and Custom Performance Classes Source: https://github.com/meraki/dashboard-api-python/blob/main/notebooks/Uplink preference backup and restore/merakiUplinkPreferenceRestore.ipynb This code block executes the functions to restore custom performance classes, update VPN preferences with new performance class IDs, and then restore both VPN and WAN uplink preferences. Ensure all necessary data structures (user_data, user_choices) are populated before execution. ```python # Restore the custom performance classes user_data["updated_performance_class_ids"] = restore_custom_performance_classes( listOfLoadedCustomPerformanceClasses=user_data["loaded_combined_uplink_prefs"Ма[ "customPerformanceClasses" ], networkId=user_choices["network_choice"].id, ) # Update the custom perfromance class IDs if user_data["updated_performance_class_ids"]: update_vpn_prefs_performance_class_ids( loaded_vpn_prefs=user_data["loaded_combined_uplink_prefs"]["vpnPrefs"], performance_class_id_updates=user_data["updated_performance_class_ids"], ) # Restore the VPN prefs user_data["restored_vpn_prefs"] = restore_vpn_prefs( user_data["loaded_combined_uplink_prefs"]["vpnPrefs"] ) # Restore the WAN prefs user_data["restored_wan_prefs"] = restore_wan_prefs( user_data["loaded_combined_uplink_prefs"]["wanPrefs"] ) ``` -------------------------------- ### HTTP-Method Parsers (v3) Source: https://github.com/meraki/dashboard-api-python/blob/main/docs/OASV3-MIGRATION.md These functions are adapted for OpenAPI v3, maintaining v2 signatures but threading `request_body` and `spec` through for comprehensive parameter parsing. ```python def parse_get_params(operation, parameters, request_body, spec) def parse_post_and_put_params(method, operation, parameters, request_body, spec) def parse_delete_params(operation, parameters, request_body, spec) ```