diff --git a/highTransitions-mt.py b/highTransitions-mt.py
new file mode 100644
index 0000000000000000000000000000000000000000..c07d62db3b9de298a698adb4d34301516630f709
--- /dev/null
+++ b/highTransitions-mt.py
@@ -0,0 +1,184 @@
+from netmiko import ConnectHandler
+from getpass import getpass
+import requests
+import urllib3
+import socket
+import re
+import time
+import getpass
+import datetime
+# New for threading
+from threading import Thread, currentThread, Lock
+from queue import Queue
+
+
+urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
+
+###########################################################################
+print(" 1 = UNL-City \n 2 = UNL-East \n 3 = UNO \n 4 = UNK \n Select Campus:")
+campus = input()
+print(f"Campus Selected: {campus}")
+print("----------------------------------")
+if campus == "1":
+ file = [line.strip() for line in open("unlCitySwitches-cx.txt", 'r')]
+if campus == "2":
+ file = [line.strip() for line in open("unlEastSwitches-cx.txt", 'r')]
+if campus == "3":
+ file = [line.strip() for line in open("unoSwitches-cx.txt", 'r')]
+if campus == "4":
+ file = [line.strip() for line in open("unkSwitches-cx.txt", 'r')]
+ #print(file[])
+ #file.close()
+
+##########################################################################
+print("Enter Username:")
+Ausername = input()
+print("Enter Password:")
+Apassword = getpass.getpass()
+creds = {"username": {Ausername}, "password": {Apassword}}
+file1 = open("highTransitions.txt", "w")
+
+# Threading setup
+# NUM_THREADS is number of concurrent connections you want.
+# (You can experiment with values)
+NUM_THREADS = 20
+PRINT_LOCK = Lock()
+
+
+def main():
+
+ start_time = datetime.datetime.now()
+
+ device_queue = Queue(maxsize=0)
+
+ # Loop through list of switch IP's, add to queue
+ for selectIP in file:
+ device_queue.put(selectIP)
+
+ # Pass the Queue and length to MultiThread function
+ numdev = len(file)
+ run_mt(mt_function=get_logs, q=device_queue, devs=numdev)
+
+ # Show how long script took
+ print("\nElapsed time: " + str(datetime.datetime.now() - start_time))
+
+
+# End of App
+
+# create sessions object
+def get_logs(q, kwargs):
+
+ while True:
+
+ thread_name = currentThread().getName()
+
+ if q.empty():
+ mt_print(f"{thread_name}: Closing as there's no jobs left in the queue.")
+ return
+
+ # create sessions object
+ ip_add = q.get()
+ self = ip_add
+ hostname = socket.getfqdn(ip_add)
+ print(f"Login from: {hostname} {ip_add}")
+ file1.writelines(f"Login from: {hostname} {ip_add}\n")
+ session = requests.session()
+
+ try:
+ # Login to API and set initial Variables
+ login = session.post(f"https://{self}/rest/v1/login", data=creds, verify=False)
+ transitions = 10000
+ vsfMember = 1
+ Switch = 1
+ SwitchPort = 1
+
+
+ # Check to see how many switches are in stack and convert to string
+ get_vsf = session.get(f"https://{self}/rest/v10.04/system/vsf_members?attributes=id&depth=2&selector=status&count=true")
+ vsfMember = re.findall(r'\d+',f"{get_vsf.json()}")
+ str_vsfMember = str(vsfMember[0])
+
+ # Check the model of the switch
+ get_model = session.get(f"https://{self}/rest/v10.04/system/subsystems/chassis,{Switch}?attributes=part_number_cfg&depth=4")
+ vsfModel = re.findall(r'\d+',f"{get_model.json()}")
+
+ #Run Program on all switches and ports to find High link trasitions.
+ while Switch <= int(str_vsfMember[0]):
+ if f"{str(vsfModel)}" == "['661']" or f"{str(vsfModel)}" == "['659']": # run for all 48 port switchs
+ while SwitchPort < 49:
+
+ get_log = session.get(f"https://{self}/rest/v10.04/system/interfaces/{Switch}%2F1%2F{SwitchPort}?attributes=link_resets&depth=2&selector=statistics")
+ LinkTransitions = re.findall(r'\d+',f"{get_log.json()}")
+ str_LinkTransitions = str(LinkTransitions[0])
+ if transitions <= int(str_LinkTransitions):
+
+ get_lldp = session.get(f"https://{self}/rest/v10.04/system/interfaces/{Switch}%2F1%2F{SwitchPort}/lldp_neighbors?attributes=neighbor_info&depth=4&selector=status&filter=")
+ lldpModel = f"{get_lldp.json()}"
+ split_lldpModel = lldpModel.split(", ")
+ count=3
+ while count < len(split_lldpModel): # This handles errors when no lldp info is found.
+ lsplit_lldp = lldpModel.split("'chassis_description': '",1)[1]
+ final_lldp = lsplit_lldp.split("', ",1)[0]
+ count += 1
+ print(f"Port: {Switch}/1/{SwitchPort} {str_LinkTransitions} --- {final_lldp}")
+ file1.write(f"Port: {Switch}/1/{SwitchPort} {str_LinkTransitions}\n")
+
+ final_lldp = "No LLDP Info" # Default value if no lldp info is retreived
+
+ SwitchPort += 1
+ Switch += 1
+ SwitchPort = 1
+ get_model = session.get(f"https://{self}/rest/v10.04/system/subsystems/chassis,{Switch}?attributes=part_number_cfg&depth=4")
+ vsfModel = re.findall(r'\d+',f"{get_model.json()}")
+ else:
+ while Switch <= int(str_vsfMember[0]): # Run for all 24 port switches
+ get_model = session.get(f"https://{self}/rest/v10.04/system/subsystems/chassis,{Switch}?attributes=part_number_cfg&depth=4")
+ vsfModel = re.findall(r'\d+',f"{get_model.json()}")
+ while SwitchPort < 25:
+ get_log = session.get(f"https://{self}/rest/v10.04/system/interfaces/{Switch}%2F1%2F{SwitchPort}?attributes=link_resets&depth=2&selector=statistics")
+ LinkTransitions = re.findall(r'\d+',f"{get_log.json()}")
+ str_LinkTransitions = str(LinkTransitions[0])
+ if transitions <= int(str_LinkTransitions):
+ print(f"Port: {Switch}/1/{SwitchPort} {str_LinkTransitions} --- {final_lldp}")
+ file1.write(f"Port: {Switch}/1/{SwitchPort} {str_LinkTransitions}\n")
+ SwitchPort += 1
+ Switch += 1
+ SwitchPort = 1
+ get_model = session.get(f"https://{self}/rest/v10.04/system/subsystems/chassis,{Switch}?attributes=part_number_cfg&depth=4")
+ vsfModel = re.findall(r'\d+',f"{get_model.json()}")
+
+
+ logout = session.post(f"https://{self}/rest/v1/logout")
+ print(f"Logout from: {hostname} {ip_add}")
+ file1.write(f"Logout from: {hostname} {ip_add}\n")
+ except requests.exceptions.RequestException as e:
+ print("Switch is not responding-----> " + ip_add)
+ print("Switch is not responding-----> " + ip_add)
+ print("Switch is not responding-----> " + ip_add)
+ file1.write("Switch is not responding-----> " + ip_add + "\n")
+
+ # When task is done, delete from queue
+ q.task_done()
+
+
+# For helping prevent overlapping print statements
+# between different queues.
+def mt_print(msg):
+ with PRINT_LOCK:
+ print(msg)
+
+# Main function used for MultiThreading
+def run_mt(mt_function, q, **kwargs):
+ devs = kwargs['devs']
+ num_threads = min(NUM_THREADS, devs)
+
+ for i in range(num_threads):
+ thread_name = f'Thread-{i}'
+ worker = Thread(name=thread_name, target=mt_function, args=(q, kwargs))
+ worker.start()
+
+ q.join()
+
+if __name__ == "__main__":
+ main()
+