def customer_room_webhook_create(target_url, room, resource, event, filter_, secret=None): """ Create a webhook in room for resource on event filtered by filter_. Optionally set secret used to create signature """ # we want notified anytime a message resource = "messages" # is created event = "created" # in the newly created room filter_ = "roomId=%s" % room.id # insecure example secret used to generate the payload signature secret = target_url + '12345' spark_api = ciscosparkapi.CiscoSparkAPI( access_token=current_app.config['SPARK_TOKEN']) return spark_api.webhooks.create(room.title + 'messages created', target_url, resource, event, filter_, secret)
def customer_room_message_send(customer_id, **room_args): """ Posts message to customer's Spark Room. Pass the customer #, the Spark Room ID will be looked up/created for you. """ if 'text' not in room_args and 'markup' not in room_args and 'files' not in room_args: return None team_id = current_app.config['SPARK_AGENT_TEAM_ID'] spark_api = ciscosparkapi.CiscoSparkAPI( access_token=current_app.config['SPARK_TOKEN']) rooms = spark_api.rooms.list(teamId=team_id) # type='group') logging.info("Looking for %s's room" % customer_id) for room in rooms: logging.info("Checking room title %s" % room.title) if room.title[-10:] is customer_id[-10:]: break # found the customers room # If room is not found and break is never encountered, else block runs # http://book.pythontips.com/en/latest/for_-_else.html else: logging.info("Didn't find a room, creating a new one") # New customer room = customer_new_signup(customer_id, team_id) # post the message to spark room return spark_api.messages.create(roomId=room.id, **room_args)
def create_new_message_webhook(room, webhook_url): """ Create the webhook if it doesn't already exist. The Webhook is triggered when new messages are posted to the room. :param room: Cisco Spark Room object to create webhook in :param webhook_url: URL for webhook to POST JSON payload to :return: Cisco Spark Webhook object. """ # when a message resource = "messages" # is created event = "created" filter_ = "" # insecure example secret used to generate the payload signature secret = config.SPARK_WEBHOOK_SECRET # Connect to SparkAPI with SPARK_TOKEN spark_api = ciscosparkapi.CiscoSparkAPI(access_token=config.SPARK_TOKEN) webhook_name = 'messages created' # search webhooks items for matching for webhook in spark_api.webhooks.list(): if webhook.name == webhook_name: break else: webhook = spark_api.webhooks.create(webhook_name, webhook_url, resource, event, filter_, secret) return webhook
def customer_new_signup(customer_id, team_id): """ Called when a new signup occurs * post message to customer via SMS and in spark room for agent to see * creates row in Smart Sheet NOTE: in a production environment these tasks would be offloaded to Celery or some other async job queue to keep users from waiting/isolate from errors """ # Send message via tropo message = "Thanks for signing up! To get in touch, reply to this message or call this number during business hours." send_customer_sms(customer_id, message) spark_api = ciscosparkapi.CiscoSparkAPI( access_token=os.environ['SPARK_TOKEN']) # create a new team room for the customer # http://ciscosparkapi.readthedocs.io/en/latest/user/api.html#ciscosparkapi.RoomsAPI.create room = spark_api.rooms.create(customer_id, teamId=team_id) # create webhook for new room # http://ciscosparkapi.readthedocs.io/en/latest/user/api.html#ciscosparkapi.WebhooksAPI.create # let flask build an external url based on SERVER_NAME target_url = url_for('.spark_webhook_post', _external=True) secret = None webhook = customer_room_webhook_create(target_url, room, "messages", "created", "roomId=%s" % room.id) smartsheet_log_signup(customer_id, datetime.now()) return room
def __init__(self, config): super().__init__(config) bot_identity = config.BOT_IDENTITY # Do we have the basic mandatory config needed to operate the bot self._bot_token = bot_identity.get('TOKEN', None) if not self._bot_token: log.fatal( 'You need to define the Cisco Spark Bot TOKEN in the BOT_IDENTITY of config.py.' ) sys.exit(1) self._webhook_destination = bot_identity.get('WEBHOOK_DESTINATION', None) if not self._webhook_destination: log.fatal( 'You need to define WEBHOOK_DESTINATION in the BOT_IDENTITY of config.py.' ) sys.exit(1) self._webhook_secret = bot_identity.get('WEBHOOK_SECRET', None) if not self._webhook_secret: log.fatal( 'You need to define WEBHOOK_SECRET in the BOT_IDENTITY of config.py.' ) sys.exit(1) self._bot_rooms = config.CHATROOM_PRESENCE if not self._bot_rooms: log.fatal('You need to define CHATROOM_PRESENCE in config.py.') sys.exit(1) log.debug("Room presence: {}".format(self._bot_rooms)) # Adjust message size limit to cater for the non-standard size limit if config.MESSAGE_SIZE_LIMIT > CISCO_SPARK_MESSAGE_SIZE_LIMIT: log.info( "Capping MESSAGE_SIZE_LIMIT to {} which is the maximum length allowed by CiscoSpark" .format(CISCO_SPARK_MESSAGE_SIZE_LIMIT)) config.MESSAGE_SIZE_LIMIT = CISCO_SPARK_MESSAGE_SIZE_LIMIT # Build the complete path to the Webhook URI if self._webhook_destination[len(self._webhook_destination) - 1] != '/': self._webhook_destination += '/' self._webhook_destination += CISCO_SPARK_WEBHOOK_URI # Initialize the CiscoSparkAPI session used to manage the Spark integration log.debug("Fetching and building identifier for the bot itself.") self._session = sparkapi.CiscoSparkAPI(self._bot_token) self.bot_identifier = CiscoSparkPerson(self, self._session.people.me()) log.debug("Done! I'm connected as {} : {} ".format( self.bot_identifier, self.bot_identifier.emails))
def WebEx_Message_Sent(MsgText): # Create a Cisco Spark object spark = ciscosparkapi.CiscoSparkAPI(access_token=SPARK_ACCESS_TOKEN) # Sent Message to the group result = spark.messages.create(SPARK_ROOM_ID, text=MsgText)
def create_new_webex_teams_incident_room(incident, ticket): ''' Creates a new Webex team room and populates it with the details of the incident from the incident report in the tool. ''' webex_teams = ciscosparkapi.CiscoSparkAPI(config['webex_teams']['token']) incident_room = webex_teams.rooms.create("Security Incident %(incident)s" % {'incident': ticket}) md = ''' ## New Incident %(incident)s Patient Zero Computer Name: %(computer)s Logged-in User: %(username)s Host IP Address: %(hosts)s ServiceNow Link: https://%(sn_host)s/nav_to.do?uri=incident.do?sysparm_query=number=%(incident)s ''' % { 'incident': ticket, 'computer': incident['computer_name'], 'username': incident['username'], 'hosts': incident['host_ip_addresses'], 'sn_host': config['servicenow']['hostname'] } message = webex_teams.messages.create(incident_room.id, markdown=md, files=['./Incident Report.txt']) return (incident_room.id)
def webhook_process(request): """ Send any room messages to customer by SMS, making sure not to echo customer's SMS or @mention messages. :param request: Flask request object :return: Flask response """ # Basic sanity checking if not request.json or not ('event' in request.json and 'data' in request.json): logging.log(logging.ERROR, 'No json or data in json') abort(400) if request.json['event'] != 'created': logging.log(logging.ERROR, 'Event is not created') abort(400) # Check for Spark Key defined webhook_key = config.SPARK_WEBHOOK_SECRET # only validate if key is defined if webhook_key: # Validate webhook - https://developer.ciscospark.com/blog/blog-details-8123.html hashed = hmac.new(webhook_key, request.data, hashlib.sha1) expected_signature = hashed.hexdigest() signature = request.headers.get('X-Spark-Signature') if expected_signature != signature: logging.log( logging.ERROR, 'Invalid Spark Signature, expected %s but got %s' % (expected_signature, signature)) abort(400) # Loop/echo prevention if request.json['data'][ 'personEmail'] == config.SPARK_CUSTOMER_PROXY_EMAIL: return "OK" # Connect to Spark API spark_api = ciscosparkapi.CiscoSparkAPI(access_token=config.SPARK_TOKEN) # Get the room info from room id that was passed from webhook room = spark_api.rooms.get(request.json['data']['roomId']) # Get the message message = spark_api.messages.get(request.json['data']['id']) # allow agents to privately exchange messages within context of the customer space # without sending a copy to the customer (agent whisper/notes) if message.mentionedPeople: return 'OK' # customer id is room name customer_id = room.title[-10:] # send SMS tropo.send_sms(customer_id, message.text) return 'OK'
def new_casebook(returned_observables, entry_title, entry_link, access_token): bearer_token = 'Bearer ' + access_token headers = { 'Authorization': bearer_token, 'Content-Type': 'application/json', 'Accept': 'application/json' } # create title and description for SOC researcher to have more context casebook_title = "New Case added by RSS_feed: " + entry_title casebook_description = "Python generated casebook (Talos RSS_feed): " + entry_link casebook_datetime = datetime.now().isoformat() + "Z" # create right json format to create casebook casebook_json = json.dumps({ "title": casebook_title, "description": casebook_description, "observables": json.loads(returned_observables), "type": "casebook", "timestamp": casebook_datetime }) # post request to create casebook response = requests.post( 'https://private.intel.amp.cisco.com/ctia/casebook', headers=headers, data=casebook_json) if response.status_code == 201: print(f"[201] Success, casebook added: {entry_title}\n") # if Webex Teams tokens set, then send message to Webex room if config_file['webex_access_token'] is '' or config_file[ 'webex_room_id'] is '': # user feed back print("Webex Teams not set.\n\n") else: # instantiate the Webex handler with the access token webex = ciscosparkapi.CiscoSparkAPI( config_file['webex_access_token']) # post a message to the specified Webex room try: message = webex.messages.create(config_file['webex_room_id'], text=casebook_title) # error handling, if for example the Webex API key expired except Exception: print( "Webex authentication failed... Please make sure Webex Teams API key has not expired. Please review developer.webex.com for more info.\n" ) else: print( f"Something went wrong while posting the casebook to CTR, status code: {response.status_code}\n" ) return response.text
def main(): """Grab a config for the device.""" time = strftime("%Y-%m-%d@%H-%M", gmtime()) spark = ciscosparkapi.CiscoSparkAPI( access_token=env_user.SPARK_ACCESS_TOKEN) # Use the appropriate network driver to connect to the device: driver = napalm.get_network_driver('ios') with open(r'ios_list.txt', 'r') as ip_input: for ip in ip_input: ip = ip.strip() # Connect: PUT ADEQUATE USERNAME AND password device = driver(hostname=ip, username='******', password='******') print('Opening ...') device.open() ios_facts = device.get_facts() running_config = device.get_config() runn_final = running_config.get("running") #print (runn_final) --> CHECK RUNN BEFORE PUTING INSIDE FILE ################## #OUTPUT GENERATED FOR FILES ########################### #mytime = time.strftime('%Y-%m-%d-%H-%M-%S') #Remove the trailing /n from varible ip this is required for file creation ip = ip.strip(' \t\n\r') print print(ip + ' config backup in place') print #filename = 'tas_%s.txt' % str(ip) #filename = os.path.join('NETVIRT-', mytime) filename = ("NETVIRT-" + time) filepath = os.path.join('configs', ip, filename) if not os.path.exists(os.path.dirname(filepath)): os.makedirs(os.path.dirname(filepath)) with open(filepath, "w") as f: f.write(runn_final) f.close() #create the directory if it does not exist #if not os.path.exists("Backup"): #os.makedirs("Backup") #f = open("Backup/" + ios_facts['hostname'] + "." + time, 'w') #f.write(runn_final) #f.close message = spark.messages.create( env_user.SPARK_ROOM_ID, #files=[next_data_file], text='BACKUP COMPLETED') print(message) device.close()
def send_message_to_teams(host, quarantine): ''' Posts a message to a Teams space to alert team to a newly infected host. ''' webex_teams = ciscosparkapi.CiscoSparkAPI(config['webex_teams']['token']) irt_room = config['webex_teams']['irt_room'] if (quarantine == 1): message = f"Host {host} was discovered compromised and automatically quarantined." else: message = f"Host {host} was discovered compromised. Use irflow to investigate and/or quarantine." send = webex_teams.messages.create(irt_room, text=message)
def main(): """Grab a config for the device.""" time = strftime("%Y-%m-%d@%H-%M", gmtime()) # Use the appropriate network driver to connect to the device: driver = napalm.get_network_driver('ios') # Connect: PUT ADEQUATE USERNAME AND password device = driver(hostname='????', username='******', password='******') spark = ciscosparkapi.CiscoSparkAPI(access_token=env_user.SPARK_ACCESS_TOKEN) print ('Opening ...') device.open() ios_facts = device.get_facts() running_config = device.get_config() runn_final = running_config.get("running") #print (runn_final) --> CHECK RUNN BEFORE PUTING INSIDE FILE ###TRY TO FORMAT OUTPUT RUNNING CONFIG### #run2file = json.dumps(running_config, indent=4) #run2file = run2file.replace("\\n", "") #run2file = run2file.strip(' \t\n\r') #run2file2 = run2file.get("running") #print (run2file2) #with open(run2file) as run2file2: #run2fileFinal = run2file2.read().splitlines() #print (lines) #running_config = running_config.strip(' \t\n\r') #print (running_config) #checkpoint = device._get_checkpoint_file() #print(checkpoint) #create the directory if it does not exist if not os.path.exists("Backup"): os.makedirs("Backup") f = open("Backup/" + ios_facts['hostname'] + "." + time, 'w') f.write(runn_final) f.close message = spark.messages.create(env_user.SPARK_ROOM_ID, #files=[next_data_file], text='BACKUP COMPLETED') print(message) device.close()
def verify() -> bool: """Verify access to the Cisco Webex APIs.""" print("==> Verifying access to the Cisco Webex APIs") # Check to ensure the user has provided their Webex Access Token if not env_user.SPARK_ACCESS_TOKEN: print("\nFAILED: You must provide your SPARK_ACCESS_TOKEN in the " "env_user.py file.\n") return False spark = ciscosparkapi.CiscoSparkAPI( access_token=env_user.SPARK_ACCESS_TOKEN) # Verify the Cisco Webex APIs are accessible and responding try: me = spark.people.me() except ciscosparkapi.SparkApiError as e: print("\nFAILED: The API call to Cisco Webex returned the following " "error:\n{}\n".format(e)) return False else: print( "\nYou are connected to Cisco Webex (formerly Cisco Spark) as: {}\n" .format(me.emails[0])) # Check to ensure the user has provided a Webex Room ID if not env_user.SPARK_ROOM_ID: print("\nFAILED: You must provide the SPARK_ROOM_ID of the room you " "want to work with in the env_user.py file.\n") return False # Verify the Webex Room exists and is accessible via the access token try: room = spark.rooms.get(env_user.SPARK_ROOM_ID) except ciscosparkapi.SparkApiError as e: print( "\nFAILED: There was an error accessing the Webex Room using the " "SPARK_ROOM_ID you provided; error details:\n{}\n".format(e)) return False else: print("You will be posting messages to the following room: '{}'\n" "".format(room.title)) return True
import os import sys import ciscosparkapi # Get the absolute path for the directory where this file is located "here" here = os.path.abspath(os.path.dirname(__file__)) # Get the absolute path for the project / repository root project_root = os.path.abspath(os.path.join(here, "../..")) # Extend the system path to include the project root and import the env files sys.path.insert(0, project_root) # Create a Cisco Spark object spark = ciscosparkapi.CiscoSparkAPI( "OTExNzA4OWMtMTc5My00ZGM3LWE1ODYtMWMwYmEyMzI1MjZiODg4OTRlYTQtNjlk_PF84_1eb65fdf-9643-417f-9974-ad72cae0e10f" ) ############## USER DEFINED SETTINGS ############### # MERAKI SETTINGS webhook_data = "Webhook Data Goes Here" secret = "secret goes here" #################################################### app = Flask(__name__) @app.route("/", methods=["POST"]) def get_webhook_json(): global webhook_data webhook_data = request.json
def test_custom_timeout(self): custom_timeout = 10 connection_object = ciscosparkapi.CiscoSparkAPI(timeout=custom_timeout) assert connection_object.timeout == custom_timeout
def test_default_timeout(self): connection_object = ciscosparkapi.CiscoSparkAPI() assert connection_object.timeout == ciscosparkapi.DEFAULT_TIMEOUT
def test_custom_base_url(self): custom_url = "https://spark.cmlccie.com/v1/" connection_object = ciscosparkapi.CiscoSparkAPI(base_url=custom_url) assert connection_object.base_url == custom_url
def test_default_base_url(self): connection_object = ciscosparkapi.CiscoSparkAPI() assert connection_object.base_url == ciscosparkapi.DEFAULT_BASE_URL
def WebServiceParser(): # Instantiate a Firepower object fmc = Firepower(CONFIG_DATA) # If there's no defined Network Object, make one, then store the UUID - else, get the current object if CONFIG_DATA['IP_UUID'] is '': # Create the JSON to submit object_json = { 'name': OBJECT_PREFIX + 'O365_Web_Service_IPs', 'type': 'NetworkGroup', 'overridable': True, } # Create the Network Group object in the FMC ip_group_object = fmc.createObject('networkgroups', object_json) # Save the UUID of the object CONFIG_DATA['IP_UUID'] = ip_group_object['id'] saveConfig() else: # Get the Network Group object of the specified UUID ip_group_object = fmc.getObject('networkgroups', CONFIG_DATA['IP_UUID']) # If there's no defined URL Object, make one, then store the UUID if CONFIG_DATA['URL_UUID'] is '': # Create the JSON to submit object_json = { 'name': OBJECT_PREFIX + 'O365_Web_Service_URLs', 'type': 'UrlGroup', 'overridable': True, } # Create the URL Group object in the FMC url_group_object = fmc.createObject('urlgroups', object_json) # Save the UUID of the object CONFIG_DATA['URL_UUID'] = url_group_object['id'] saveConfig() else: # Get the URL Group object of the specified UUID url_group_object = fmc.getObject('urlgroups', CONFIG_DATA['URL_UUID']) # Get the latest version of the loaded feed latestVersion = CONFIG_DATA['VERSION'] # create GUID for GET requests clientRequestId = str(uuid.uuid4()) # URL needed to check latest version webServiceVersionURL = "https://endpoints.office.com/version?clientrequestid=" # assemble URL for get request for version getURLVersion = webServiceVersionURL + clientRequestId # do GET request reqVersion = requests.get(getURLVersion) # grab output in JSON format version = reqVersion.json() # loop through version list and grab Wordwide list version for element in version: if (element['instance'] == 'Worldwide'): newVersion = int(element['latest']) # if the version did not change, the Web Service feed was not updated. if (newVersion == latestVersion): # user feed back sys.stdout.write("\n") sys.stdout.write( "Web Service List has NOT been updated since the last load, no update needed!\n" ) sys.stdout.write("\n") # check if there is a newer version if (newVersion > latestVersion): # update version and save the config CONFIG_DATA['VERSION'] = newVersion # user feedback sys.stdout.write("\n") sys.stdout.write( "New version of Office 365 worldwide commercial service instance endpoints detected: %(version)s" % {'version': CONFIG_DATA['VERSION']}) sys.stdout.write("\n") ### PARSE JSON FEED ### # URL needed for the worldwide web service feed webServiceURL = "https://endpoints.office.com/endpoints/worldwide?NoIPv6=true&clientrequestid=" # assemble URL for get request getURL = webServiceURL + clientRequestId # do GET request req = requests.get(getURL) # initiate lists to be filled with addresses URL_List = [] IP_List = [] # error handling if true then the request was HTTP 200, so successful if (req.status_code == 200): # grab output in JSON format output = req.json() # iterate through each 'item' in the JSON data for item in output: # make sure URLs exist in the item if 'urls' in item: # iterate through all URLs in each item for url in item['urls']: # remove asterisks to put URLs into Firepower format # (https://www.cisco.com/c/en/us/support/docs/security/firesight-management-center/118852-technote-firesight-00.html#anc14) url = url.replace('*', '') # if the URL hasn't already been appended, then append it if url not in URL_List: URL_List.append(url) # make sure IPs exist in the item if 'ips' in item: # iterate through all IPs in each item for ip in item['ips']: # if the IP hasn't already been appended, then append it if ip not in IP_List: IP_List.append(ip) # Reset the fetched Network Group object to clear the 'literals' ip_group_object['literals'] = [] ip_group_object.pop('links', None) # Add all the fetched IPs to the 'literals'of the Network Group object for ip_address in IP_List: ip_group_object['literals'].append({ 'type': 'Network', 'value': ip_address }) # Update the NetworkGroup object fmc.updateObject('networkgroups', CONFIG_DATA['IP_UUID'], ip_group_object) # Reset the fetched URL Group object to clear the 'literals' url_group_object['literals'] = [] url_group_object.pop('links', None) # Add all the fetched URLs to the 'literals' of the URL Group object for url in URL_List: url_group_object['literals'].append({'type': 'Url', 'url': url}) # Update the UrlGroup object fmc.updateObject('urlgroups', CONFIG_DATA['URL_UUID'], url_group_object) # user feed back sys.stdout.write("\n") sys.stdout.write("Web Service List has been successfully updated!\n") sys.stdout.write("\n") saveConfig() # If the user wants us to deploy policies, then do it if CONFIG_DATA['AUTO_DEPLOY']: DeployPolicies(fmc) # if Webex Teams tokens set, then send message to Webex room if CONFIG_DATA['WEBEX_ACCESS_TOKEN'] is '' or CONFIG_DATA[ 'WEBEX_ROOM_ID'] is '': # user feed back sys.stdout.write("Webex Teams not set.\n") sys.stdout.write("\n") else: # adjust the Webex message based on the config if CONFIG_DATA['AUTO_DEPLOY']: message_text = "Microsoft Office 365 objects have been successfully updated! Firepower policy deployment was initiated..." else: message_text = "Microsoft Office 365 objects have been successfully updated! Firepower policy deployment is required." # instantiate the Webex handler with the access token webex = ciscosparkapi.CiscoSparkAPI( CONFIG_DATA['WEBEX_ACCESS_TOKEN']) # post a message to the specified Webex room message = webex.messages.create(CONFIG_DATA['WEBEX_ROOM_ID'], text=message_text)
import ciscosparkapi # Get the absolute path for the directory where this file is located "here" here = os.path.abspath(os.path.dirname(__file__)) # Get the absolute path for the project / repository root project_root = os.path.abspath(os.path.join(here, "../..")) # Extend the system path to include the project root and import the env files sys.path.insert(0, project_root) import env_lab # noqa import env_user # noqa # Create a Cisco Spark object spark = ciscosparkapi.CiscoSparkAPI(access_token=env_user.SPARK_ACCESS_TOKEN) # Create message list messages = [ "I've completed the Intro to Model Driven Programmability Mission!" ] # Create a list of devices to query devices = [ { "conn": env_lab.IOS_XE_1, "ip": "172.16.255.1", "prefix": "24" }, { "conn": env_lab.IOS_XE_2,
def test_creating_a_new_ciscosparkapi_object_without_an_access_token(self): with pytest.raises(ciscosparkapi.ciscosparkapiException): ciscosparkapi.CiscoSparkAPI()
def api(): return ciscosparkapi.CiscoSparkAPI()
import ciscosparkapi import json import os import requests #first : pip install ciscosparkapi SPARK_ACCESS_TOKEN = "<Webex_Token>" #you Webex team Token SPARK_ROOM_ID = "<ROOM_ID>" spark = ciscosparkapi.CiscoSparkAPI(SPARK_ACCESS_TOKEN) message = spark.messages.create( SPARK_ROOM_ID, text='Hello - Test Message from My Python Script !') print('MESSAGE SENT !')
def test_default_single_request_timeout(self): connection_object = ciscosparkapi.CiscoSparkAPI() assert connection_object.single_request_timeout == \ ciscosparkapi.DEFAULT_SINGLE_REQUEST_TIMEOUT
def test_custom_single_request_timeout(self): custom_timeout = 10 connection_object = ciscosparkapi.CiscoSparkAPI( single_request_timeout=custom_timeout ) assert connection_object.single_request_timeout == custom_timeout
def webex_message(item): spark = ciscosparkapi.CiscoSparkAPI(access_token=token) message = spark.messages.create(roomId=room_id, text="{0:30}".format(item.name))
now = datetime.datetime.now() network_id = ('<Variable>') access_token = ('<Variable>') teams_room = ("<Variable>") api_key = ('<Variable>') #to do, grab a device list and pull all serials for device type MV spark = ciscosparkapi.CiscoSparkAPI(access_token=access_token) base_url = 'https://api.meraki.com/api/v0' def meraki_snapshots( api_key, network_id, time=None, filters=None): # Get devices of network and filter for MV cameras headers = { 'X-Cisco-Meraki-API-Key': api_key, #'Content-Type': 'application/json' # issue where this is only needed if timestamp specified } response = requests.request("GET",f'https://api.meraki.com/api/v0/networks/{network_id}/devices', headers=headers) devices = response.json() cameras = [device for device in devices if device['model'][:2] == 'MV'] snapshoturl = [] for camera in cameras:
def test_creating_a_new_ciscosparkapi_object_via_access_token_argument( self, access_token): connection_object = ciscosparkapi.CiscoSparkAPI( access_token=access_token) assert isinstance(connection_object, ciscosparkapi.CiscoSparkAPI)
def test_creating_a_new_ciscosparkapi_object_via_environment_varable(self): connection_object = ciscosparkapi.CiscoSparkAPI() assert isinstance(connection_object, ciscosparkapi.CiscoSparkAPI)
def test_non_default_wait_on_rate_limit(self): connection_object = ciscosparkapi.CiscoSparkAPI( wait_on_rate_limit=not ciscosparkapi.DEFAULT_WAIT_ON_RATE_LIMIT ) assert connection_object.wait_on_rate_limit != \ ciscosparkapi.DEFAULT_WAIT_ON_RATE_LIMIT