List of Sorted and Filtered into a Select/Dropdown List

Solved
eroche
Getting noticed

List of Sorted and Filtered into a Select/Dropdown List

Hi All

 

So todays activity is to build off some of my other questions and use the inquirer module to create a list of device I can select from then use that selection as the device I want to work on. I can get it to display 1 device out of the list but it is list vertically instead of horizonal. I think it only listing the first device is due to me trying to use the FOR option to go through my sorted list. Below is the code I currently have. If anyone has suggestions please chime in. Thanks in advance!

 

response = dashboard.organizations.getOrganizationInventoryDevices(
    organization_id, total_pages='all'
    )
    

    
    SortedListOfDevices = sorted(response, key=lambda d: d['mac'] if d['name'] is None else d['name'])
    
    device_type = "MS"
    
    for item in SortedListOfDevices:
        if device_type in item['model'] and item['name'] != "":
            print(f"{item['name']}")
            devices = (item['name'])

            questions = [
                inquirer.List('inventory',
                    message = "Pick your switch: ",
                    choices = devices,
                    ),
            ]
            answers = inquirer.prompt(questions)
            print (answers["inventory"])
1 Accepted Solution
sungod
Head in the Cloud

A piece of friendly advice: You really need to decide on the outcome before coding, as you'll end up either rewriting or having a badly structured script. Also I'd spend some time reading through Python data types and how to use them. 

 

You can't reference item like that, it's not the right context at all.

 

One sneaky way to get the result you ask for without needing an extra look-up would be to use a concatenated serial$name value as the second value in the tuple, this will be returned as the answer, you then split it back into serial and name.

 

Note I'm assuming $ isn't used in any device names, possible an unsafe assumption, a safe way would be rely on the fact the serial numbers are 14 char and split that way instead, but I'd already typed everything before I thought of that... 

 

devices.append((name, item['serial'] + "$" + name))

 

Then the answer can be split back into the two parts...

 

ans = answers["inventory"].split("$")

ans[0] #is the serial number
ans[1] #is the name

 

I'm assuming answers["inventory"] is a string, if it isn't you'll need to make it one.

View solution in original post

8 Replies 8
PhilipDAth
Kind of a big deal
Kind of a big deal

Maybe @sungod can help?

sungod
Head in the Cloud

You're setting devices to just one device's name, then setting choices to devices.

 

So you only get that one choice.

 

You need to give choices a list.

 

I'm in an airport sipping champagne at the moment and haven't ever used the inquirer library, but from a quick look you probably need to do something more like...

 

 

 

response = dashboard.organizations.getOrganizationInventoryDevices(organization_id, total_pages='all')

SortedListOfDevices = sorted(response, key=lambda d: d['mac'] if d['name'] is None else d['name'])

device_type = "MS"
devices = []
for item in SortedListOfDevices:
    name = item['mac'] if item['name'] is None else item['name']
    if device_type in item['model']:
        print(name)
        devices.append(name)

questions = [
    inquirer.List('inventory',
        message = "Pick your switch: ",
        choices = devices,
         ),
]
answers = inquirer.prompt(questions)
print (answers["inventory"])

 

 

 

Note that you were testing for name "", which will never happen and you would be adding any None names to the list, I added a bit to default a None name to the MAC.

eroche
Getting noticed

Thanks that worked. To add to that, since I want to select that switch to work on, I need the SN as well. So the next trick it to assign that device to a variable so I can use that in the the rest on that function. I will play with it but if you have some insight that works to 😀

sungod
Head in the Cloud

Looks like inquirer.List accepts a list of tuples, so try replacing...

 

devices.append(name)

 

...with...

devices.append((name, item['serial']))

 

...then the choice displayed will be the name, but the answer will be the serial number.

eroche
Getting noticed

That worked perfect for what I trying to do. One last question this thread. I decided to add a confirmation statement on what switch was selected. I want print the device name with the serial number. I got the serial portion but can't seem to get the name correctly. Thoughts?

print ('\n' + 'Following Switch has been selected: ' + item(name) + ' ' + answers["inventory"])

 

sungod
Head in the Cloud

A piece of friendly advice: You really need to decide on the outcome before coding, as you'll end up either rewriting or having a badly structured script. Also I'd spend some time reading through Python data types and how to use them. 

 

You can't reference item like that, it's not the right context at all.

 

One sneaky way to get the result you ask for without needing an extra look-up would be to use a concatenated serial$name value as the second value in the tuple, this will be returned as the answer, you then split it back into serial and name.

 

Note I'm assuming $ isn't used in any device names, possible an unsafe assumption, a safe way would be rely on the fact the serial numbers are 14 char and split that way instead, but I'd already typed everything before I thought of that... 

 

devices.append((name, item['serial'] + "$" + name))

 

Then the answer can be split back into the two parts...

 

ans = answers["inventory"].split("$")

ans[0] #is the serial number
ans[1] #is the name

 

I'm assuming answers["inventory"] is a string, if it isn't you'll need to make it one.

eroche
Getting noticed

Ok I updated the devices.append line. Now the other one, you mean the

answers = inquirer.prompt(questions)

 

Try ans = answers["inventory"].split("$") then Print(ans[0])

 

I appreciate all time you have spent with me on my questions. I am hoping as I go through this exercise I will get a better understanding. To be honest this is the first time I have ventured into the Python world. Hence the reason for so many second thoughts and add-ins as I go. These are things I am finding that would work a little better for what I am trying to do.

eroche
Getting noticed

That worked the way it is suppose to, here is my fine code.

def menu_config_port(): #Sub-Menu to configure port
    clearconsole()
    
    API_KEY = get_meraki_api_key()
    dashboard = meraki.DashboardAPI(API_KEY, suppress_logging=True)
    
    organization_id = ''
    
    response = dashboard.organizations.getOrganizationInventoryDevices(
    organization_id, total_pages='all'
    )
    

    
    SortedListOfDevices = sorted(response, key=lambda d: d['mac'] if d['name'] is None else d['name'])
    
    device_type = "MS"
    devices = []
    for item in SortedListOfDevices:
        name = item['name'] if item['name'] is None else item['name']
        if device_type in item['model']:
            devices.append((name, item['serial'] + "$" + name))

    questions = [
        inquirer.List('inventory',
            message = "Pick your switch: ",
            choices = devices,
            ),
    ]
    
    answers = inquirer.prompt(questions, theme=GreenPassion())
    ans = answers["inventory"].split("$")

    print (Fore.WHITE,Style.BRIGHT + '\n' + 'Following Switch has been selected: ' 
        + ' ' + Fore.GREEN,Style.BRIGHT + ans[1] 
        + Fore.WHITE,Style.BRIGHT + ":" 
        + Fore.YELLOW,Style.BRIGHT + ans[0] +  Style.RESET_ALL)
  
# Select Device    
    sw_sn = ans[0]
    port = input ('\n' + 'What port would you like to update? (1,2...48): ')
    print (Fore.BLUE,Style.BRIGHT +'\n' + 'Below is the current information for that port:  ' + '\n')
    API_KEY = get_meraki_api_key()
    dashboard = meraki.DashboardAPI(API_KEY, suppress_logging=True)
    serial = (sw_sn) 
    port_id = (port)

    response = dashboard.switch.getDeviceSwitchPort(serial, port_id)
    
    fields = ['portId', 'name', 'enabled', 'poeEnabled', 'type', 'vlan', 'voiceVlan', 'allowedVlans', 'isolationEnabled', 'rstpEnabled', 'stpGuard', 'linkNegotiation']
    
    for field in fields:
        print (f"{field}: {response[field]}")

Screenshot 2024-07-27 011954.png

Get notified when there are additional replies to this discussion.
Welcome to the Meraki Community!
To start contributing, simply sign in with your Cisco account. If you don't yet have a Cisco account, you can sign up.