Reputation: 3
I'm trying to create function that can pull information from an API library and I am having a hard time figuring out how to pass a variable selection into the function without being read as a value.
code example:
def get_list(api, val = None):
response =[]
list = api
for i in list:
response.append(f'i.{val}')
return (response)
devices = get_list(api.devices.all(), 'name')
print(devices )
Give me a long list of "i.name"
I need to resolve i.name as a variable selection and not as an actual value
I have tired:
response.append(vars()[f'i.{val}']) # locals(), globals()
But I I get the error: "KeyError: 'i.name'"
I think the problem is the 'i.name' doesn't really exist as a variable within the function.
Upvotes: 0
Views: 109
Reputation: 71
From what I understand is that you want to write a function so you will not have to repeat the for
ip_list = []
for device in lnms.devices.all():
ip_list.append(device.ip)
name_list = []
for device in lnms.devices.all():
ip_list.append(device.sysName)
First of all on your code, you are using list
as a variable which you should not cause list
is a built-in keyword.
This comment explains why your code doesn't work
This is how it would work
def get_data(devices, attr):
response = []
for device in devices:
response.append(getattr(device, attr))
return response
Or even shorter using list comprehension
def get_data(devices, attr):
return [getattr(device, attr) for device in devices]
and then you can do
ip_list = []
ip_list = get_data(lnms.devices.all(), 'ip')
name_list = []
name_list = get_data(lnms.devices.all(), 'sysName')
And if you don want to repeat lnms.devices.all()
You can write the functions like
def get_data_from_devices(attr):
response = []
for device in lnms.devices.all():
response.append(getattr(device, attr))
return response
Or with list comprehension
def get_data_from_devices(attr):
return [getattr(device, attr) for device in lnms.devices.all()]
And then you would call them as
ip_list = []
ip_list = get_data_from_devices('ip')
name_list = []
name_list = get_data_from_devices('sysName')
PS: Needs better names for functions
Upvotes: 0
Reputation: 3
I am pretty new at Python and I can see from the text above I have not explained myself very well, so here is my attempt to make things clearer.
command "lnms_device_names = get_data(lnms.devices.all(), 'sysName')"
def get_data(devices, key):
response = []
for device in devices:
response.append(device.key)
return response
# => Endpoint devices/29/key does not exists
def get_data(devices, key):
response = []
for device in devices:
response.append(f'device.{key}')
return response
# => ['device.sysName', 'device.sysName', 'device.sysName', 'device.sysName']
def get_data(devices, key):
return [device[key] for device in devices]
# => TypeError: 'LibreNMSEndpoint' object is not subscriptable
def get_data(devices, key):
response = []
for device in devices:
response.append(device[key])
return response
# => TypeError: 'LibreNMSEndpoint' object is not subscriptable
def get_data(devices, key):
response = []
for device in devices:
response.append(f'{device}.{key}') # same result with f'{str(device)}.{key}'
return response
# => full data dump no filtering by key
#WORKS:
lnms_device_names = []
for device in lnms.devices.all():
lnms_device_names.append(device.sysName)
# => ['dc2-h1-ipn03', 'dc2-h1-spine1', 'dc2-h1-spine2', 'dc2-h1-leaf1']
{
"device_id": 1,
"inserted": "2022-08-15 15:50:33",
"hostname": "172.21.142.10",
"sysName": "dc2-h1-ipn03",
"display": null,
"ip": "",
"overwrite_ip": null,
"community": "xxxxxxx",
"authlevel": null,
"authname": null,
"authpass": null,
"authalgo": null,
"cryptopass": null,
"cryptoalgo": null,
"snmpver": "v2c",
"port": 161,
"transport": "udp",
"timeout": null,
"retries": null,
"snmp_disable": 0,
"bgpLocalAs": 1,
"sysObjectID": ".1.3.6.1.4.1.9.12.3.1.3.1812",
"sysDescr": "Cisco NX-OS(tm) nxos.7.0.3.I7.9.bin, Software (nxos), Version 7.0(3)I7(9), RELEASE SOFTWARE Copyright (c) 2002-2020 by Cisco Systems, Inc. Compiled 8/27/2020 4:00:00",
"sysContact": null,
"version": "7.0(3)I7(9)",
"hardware": "N9K-C93180YC-EX",
"features": null,
"location_id": 1,
"os": "nxos",
"status": 1,
"status_reason": "",
"ignore": 0,
"disabled": 0,
"uptime": 47671869,
"agent_uptime": 0,
"last_polled": "2022-11-02 15:28:35",
"last_poll_attempted": null,
"last_polled_timetaken": 8.46,
"last_discovered_timetaken": 293.18,
"last_discovered": "2022-11-02 12:05:18",
"last_ping": "2022-11-02 15:31:02",
"last_ping_timetaken": 1.83,
"purpose": null,
"type": "network",
"serial": "xxxxxx",
"icon": "cisco.svg",
"poller_group": 0,
"override_sysLocation": 0,
"notes": null,
"port_association_mode": 1,
"max_depth": 0,
"disable_notify": 0,
"dependency_parent_id": null,
"dependency_parent_hostname": null,
"location": "xxxxx",
"lat": 64.132453,
"lng": -21.877419
},
{
"device_id": 2,
....
....
Upvotes: 0
Reputation: 3
I'm using a LibrenmsAPI library to read data from LibreNMS
regular GET request would look like:
ip_list []
for device in lnms.devices.all():
ip_list.append(device.ip)
name_list []
for device in lnms.devices.all():
ip_list.append(device.sysName)
So in order not have to make every variation of an api request I need, the idea would be to have a "list" function.
Upvotes: 0
Reputation: 66
When you call this function with devices, you are passing the argument 'name' as your "val" which you then loop over and append to results.
It would be helpful if you could also include what your desired result here would be since that is not clear at the moment.
Upvotes: 1