Python Forum
Python: Call function with variabele? Ending in error. - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Python: Call function with variabele? Ending in error. (/thread-26136.html)



Python: Call function with variabele? Ending in error. - efclem - Apr-22-2020

Hi all,
I am a beginner in Python and I am trying to create a script that is login to all kind of different devices (Storage, server, switches) and collect information out of these devices.
What I am doing is I open an csv file, read the lines and with every line I call a (ssh)funtion to login to that device. Because the devices are diverend I have multiple fuctions for every device model.
I try to create the funtion name into a variable because it could be different and I need to figure out which funtion to call with this variable, but I get an error and I am really stuck here.

Thanks for helping and I'll hope my question make sense.

def ssh_login_xxx(host_ip):
    do the login stuf

def ssh_login_yyy(host_ip):
    do the login stuf

def ssh_login_zzz(host_ip):
    do the login stuf

with open (input_file, 'r') as my_file:
    csv_reader = csv.DictReader(my_file)
    for line in csv_reader:
        dev_model = line['dev_model']
        host_ip = line['host_ip']

		sub = dev_model
        if sub == dev_model:
            function_name = ("ssh_login_"+sub) 
            print(function_name)
            function_name(host_ip)
Error:
Traceback (most recent call last): File "c:/scripting/python/Training/login.py", line 86, in <module> function_name(host_ip) TypeError: 'str' object is not callable
#lines in csv file:
dev_model,host_ip
xxx,192.0.0.10
yyy,192.0.0.11
zzz,192.0.0.12
xxx,192.0.0.13


RE: Python: Call function with variabele? Ending in error. - buran - Apr-22-2020

def ssh_login_xxx(host_ip):
    do the login stuf
 
def ssh_login_yyy(host_ip):
    do the login stuf
 
def ssh_login_zzz(host_ip):
    do the login stuf

login_functions = {'xxx':ssh_login_xxx, 'yyy':ssh_login_yyy, 'zzz':ssh_login_xxx}

with open (input_file, 'r') as my_file:
    csv_reader = csv.DictReader(my_file)
    for line in csv_reader:
        dev_model = line['dev_model']
        host_ip = line['host_ip']
 
        sub = dev_model
        if sub == dev_model:
            login_function = login_functions[sub] 
            function_name(host_ip)
You can define dict of login functions (look above). However do you realy need separate functions. Can you pass target (xxx, yyy, zzz) as argument (is the process of logging in fundamentally different?)

Also:
        sub = dev_model
        if sub == dev_model:
This doesn't make sense at all, condition will always be True

Better replace
sub = dev_model
if sub == dev_model:
    login_function = login_functions[sub] 
    function_name(host_ip)
with

try:
    login_function = login_functions[sub] 
    function_name(host_ip)
except KeyError:
    print(f'Unknown device model: {dev_model}')



RE: Python: Call function with variabele? Ending in error. - efclem - Apr-22-2020

Hi Buran, many thanks for helping me.

For this example I used several funtions for the same goal to login into different devices/models with ssh, but later an funtion could also be used by another login methode. My problem is that the script I need to choose the correct funtions and that is where I get stuck.

Your solution helped me a lot. The script is able to read the csv file and then go to the funtion but it only uses only the last line in the csv file, so it is get information out of the latest device, I think the place of the dictionary is not good. I tried to move the dictionary on several other places in the script but then the script failes.

regards,
efclem


RE: Python: Call function with variabele? Ending in error. - buran - Apr-22-2020

def ssh_login_xxx(host_ip):
    do the login stuf
  
def ssh_login_yyy(host_ip):
    do the login stuf
  
def ssh_login_zzz(host_ip):
    do the login stuf
 
login_functions = {'xxx':ssh_login_xxx, 'yyy':ssh_login_yyy, 'zzz':ssh_login_xxx}
 
with open (input_file, 'r') as my_file:
    csv_reader = csv.DictReader(my_file)
    for line in csv_reader:
        dev_model = line['dev_model']
        host_ip = line['host_ip']
        try:
            login_function = login_functions[dev_model] 
            function_name(host_ip)
        except KeyError:
            print(f'Unknown device model: {dev_model}')



RE: Python: Call function with variabele? Ending in error. - efclem - Apr-22-2020

Hi Buran,

I changed the code a little bit and now it works, I put the 'try' just below the 'for line'
Thank you very much, this helped a lot.

def ssh_login_xxx(host_ip):
    do the login stuf
   
def ssh_login_yyy(host_ip):
    do the login stuf
   
def ssh_login_zzz(host_ip):
    do the login stuf
  
login_functions = {'xxx':ssh_login_xxx, 'yyy':ssh_login_yyy, 'zzz':ssh_login_xxx}
  
with open (input_file, 'r') as my_file:
    csv_reader = csv.DictReader(my_file)
    for line in csv_reader:
        try:
			dev_model = line['dev_model']
			host_ip = line['host_ip']
            login_function = login_functions[sub] 
            function_name(host_ip)
        except KeyError:
            print(f'Unknown device model: {dev_model}')



RE: Python: Call function with variabele? Ending in error. - buran - Apr-22-2020

generally the idea is that you should include as little code as possible in the try block (i.e. be precise and handle the error where it can happen).

The change you did will catch KeyError if the csv file header does not have 'dev_model' or 'host_ip' and will print error message for each line in the file. I doubt you want this. If you want to check the header, do it before the loop.