API Example: Copy a Dashboard


This script copies an existing dashboard, swaps out streams, swaps out text, renames it, and saves it.

# GroveStreams.com Python 3.7 Example
# Demonstrates copying an existing dashboard, swapping out streams, swapping out text, renaming it, and saving it
 
 
# License:
# Copyright 2020 GroveStreams LLC.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import requests
import datetime

def checkResponse(response):
    if response.status_code != 200 and response.status_code != 201:

        if (response.reason != None):
            raise Exception("HTTP Failure Reason: " + response.reason + " body: " +  response.content.decode('utf-8'))
        else:
            raise Exception("HTTP Failure Body: " +  response.content.decode('utf-8'))    
       

def main():
    
    #CHANGE THESE!!!!!!
    userId = "brucelee@acme.com"
    userPwd = "wingchung"
    org = "73810174-55b0-31a8-bfed-d6a280ebc353"     
    sourceDashboard = "7a8f16f6-414f-3945-9bfc-bbfbdb767e5a" #The UID of the dashboard to copy. To get: Open Chrome browser, goto your GS org, hit F12, open dashboard, watch network tab in debug console
    swapCompUid = "527d6b2e-461c-3a28-a69a-84691ad1e765"     #new component uid for the new dashboard
    toFolderName = "Content/CustomerX"                       #existing or new folder path
    newDashboardName = "Customer X Dashboard"
    swapTextKey = "[cityName]"                               #[cityName] is used in a widget InfoPanel within our source example dashboard. Swap it out
    swapText = "Minneapolis"
    
    
    urlBase = "https://grovestreams.com/api/"
    
     
    # Login and request a user session token. Session security is required, instead of api_key security, when modifying a content store (folders)
    url = urlBase + "login"
    data = {
       "email": userId,
       "password" : userPwd
    }
    response = requests.post(url,json=data)
    checkResponse(response)
    sessionJson = response.json()
    session = sessionJson["sessionUid"]
    
    # Make a copy of the dashboard. Let the server do it because it assigns unique uids to the dashboard and widgets. 
    # Returns a collection or content nodes (dashboard descriptors) since this call can make more than one copy at a time
    url = urlBase + "cr/content/" + sourceDashboard + "?action=copy&numCopies=1&toFolderName=" + toFolderName + "&org=" + org + "&session=" + session
    response = requests.post(url)
    checkResponse(response)
    crNodeJson = response.json()
    newDashboardUid = crNodeJson["cr_node"]["children"][0]["uid"]  
    
    # Get the copied dashboard definition. Swaps out the component and its streams at the same time because of the change parameter
    # Streams are swapped out by matching IDs (not UIDs)
    url = urlBase + "view_dashboard/" + newDashboardUid + "?change=" + swapCompUid + "&org=" + org + "&session=" + session
    response = requests.get(url)
    checkResponse(response)
    dashJson = response.json()
  
    # Rename the dashboard
    dashJson["dashboard"]["name"] = newDashboardName
    
    # Swap text within the dashboard definition
    jsonString = str(dashJson)                              #Convert to string
    jsonString = jsonString.replace(swapTextKey, swapText)  #Swap all occurrences of the string
    dashJson = eval(jsonString);                            #Convert string back to json dictionary
    
    # Print out the dashboard definition for debugging
    print(str(dashJson))
       
    # Save the Dashboard
    url = urlBase + "view_dashboard?org=" + org + "&session=" + session
    response = requests.post(url, json=dashJson)
    checkResponse(response)


if __name__ == "__main__":
    try:    
        main()
    except Exception as e:
        print(str(e))
# quit
exit(0)