Search code examples
pythonpython-3.xmultithreadingnetmiko

How can I rewrite the code for multitheading


I would like to do the multithreading to my code, but have no idea how to start .... Basically the python script will perfrom a "for" loop to a lot of devices (defined in another file "pyntc_devices_list"), to backup config for all devices.

With multithreading, I should run the backup to all devices at the same time, rather than one by one. Much appreciate for the help.

My code is as below:

from pyntc import ntc_device as NTC
from pyntc_devices_list import Get_Devices_List

all_devices = Get_Devices_List()

for device in all_devices:
    print('Backing up ' + device['name'])
    try:
        DEVICE = NTC(host=device['ip'], username=device['username'], password=device['password'], device_type='cisco_ios$
        DEVICE.open()
    except Exception as unknown_error:
        print('Error: ' + str(unknown_error))
        continue

    back_config = DEVICE.backup_running_config(device['name'] + '.cfg')
    DEVICE.close()

Part of the "pyntc_devices_list"

ESW1 = {
    'name': 'ESW1',
    'ip': '192.168.122.72',
    'username': 'yyc',
    'password': 'cisco',
 }

 ESW2 = {
    'name': 'ESW2',
    'ip': '192.168.122.73',
    'username': 'yyc',
    'password': 'cisco',
 }

 ESW3 = {
    'name': 'ESW3',
    'ip': '192.168.122.74',
    'username': 'yyc',
    'password': 'cisco',
 }

 def Get_Devices_List():
    all_devices = [ESW1, ESW2, ESW3]
    return all_devices

Solution

  • The book https://scaling-python.com, with which I am not associated, offers some great solutions for multithreading in python 3.x (and multiprocessing in fact). Here are some of the multithreading options (but I mainly refer the interested reader to the book, from which the code extracts are taken):

    1. threading module (examples 2.1, 2.2, 2.3):
    import threading
    t = threading.Thread(target=my_func,args=(...,))
    t.start()
    t.join()
    
    1. concurrent.futures (examples 2.7, 2.8):
    from concurrent import futures
    with futures.ThreadPoolExecutor as executor:
        futures = [executor.submit(my_func) for _ in range(...)]
    results = [f.result() for f in futures]
    

    There are plenty of other routes in the book. I did run into some issues when using futures alongside gunicorn/uwsgi Flask workers - and it's not clear these are resolvable as of now.

    Hope that helps (can also update this answer if anyone has any other solutions).