magmax / python-inquirer

A collection of common interactive command line user interfaces, based on Inquirer.js (https://github.com/SBoudrias/Inquirer.js/)
MIT License
1.01k stars 97 forks source link

List Choices Limit #612

Closed edroche74 closed 3 months ago

edroche74 commented 3 months ago

I am new to Inquirer and love it BUT running into an issue. I am creating my choices from a list of device fromour MEraki Dashboard. The total number is 31 choices. When I get to approx 27 in the list the script errors out. I am also using the GreenPassion theme. This also does it whennot using the theme. Below is the error and the code in my script it errors on.

Error: File "/usr/local/lib/python3.11/dist-packages/inquirer/prompt.py", line 11, in prompt answers[question.name] = render.render(question, answers) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/inquirer/render/console/init.py", line 38, in render return self._event_loop(render) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/dist-packages/inquirer/render/console/init.py", line 50, in _event_loop self._print_options(render) File "/usr/local/lib/python3.11/dist-packages/inquirer/render/console/init.py", line 70, in _print_options self.print_line(" {color}{s} {m}{t.normal}", m=message, color=color, s=symbol) File "/usr/local/lib/python3.11/dist-packages/inquirer/render/console/init.py", line 170, in print_line self.print_str(base + self.terminal.clear_eol(), lf=lf, kwargs) File "/usr/local/lib/python3.11/dist-packages/inquirer/render/console/init.py", line 176, in print_str print(base.format(t=self.terminal, kwargs), end="\n" if lf else "") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: str returned non-string (type NoneType) root@raspberrypi5:/mnt/m2ssd/python#

Script Line:

inquirer.prompt(questions, theme=GreenPassion())

Cube707 commented 3 months ago

I can do much as you have not provided any of the Input you pass into inquirer. Please provide a reproducible example that causes the error (NOT your full code-file, make a new file with be minimum code that produces the error)

My first guess would be that you use an Object in one of your querrys that implements the __str__ function wrong.

edroche74 commented 3 months ago

Thank you for your response!

Sorry...wasn't sure if you would need the whole thing since it kind of looked it was something with that line. Here is the whole sections of the 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']))

questions = [
    inquirer.List('inventory',
        message = "Pick your switch: ",
        choices = devices,
        ),
]
inquirer.prompt(questions, theme=GreenPassion())
answers = inquirer.prompt(questions)
print ('\n' + 'Following Switch has been selected: ' + ' ' + answers["inventory"])

Select Device

sw_sn = answers["inventory"]
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]}")`
Cube707 commented 3 months ago

Failed as the function get_meraki_api_key() is not defined.

Let me repeate myself: provide a minimal, reproducable example so I can see and test myself where it goes wrong. Otherwise I once again can only guess that you have an object somewhere in you list that can't be converted into a string.

Cube707 commented 3 months ago

For example this line: name = item['name'] if item['name'] is None else item['name'] may result in None entries

edroche74 commented 3 months ago

inquire_test.txt

Attached is the script cutdown to only the portion using the inquirer module. I have (2) options for the choices portion. One is used witht he Meraki portion to dynamically pull the device choice from the our dashboard. Two is the list of devices in the script itself. Ideally, I want to used the dynamic option so there is less admistration of the script later on. I did test it with static list in the script and the issue didn't repeat. One other thing I noticed with the dynamic option is after I select a device it gives me the list again. Then it moves on after selecting the secodn time. I hope this is what you wanted. Thanks for looking at it.

Cube707 commented 3 months ago

it gives me the list again. Then it moves on after selecting the second time

because you call inquirer.prompt two times...

inquirer.prompt(questions, theme=GreenPassion())
answers = inquirer.prompt(questions)

Still can not run the code your provided, it fails with ValueError: No API key found. Please set the MERAKI_API_KEY enviroment variable..

And Running this works as expected:

import inquirer
from inquirer.themes import GreenPassion

questions = [
    inquirer.List('inventory',
        message = "Pick your switch: ",
        choices = ["Switch1","Switch2","Switch3","Switch4","Switch5","Switch6","Switch7","Switch8","Switch9","Switch10","Switch11","Switch12","Switch13","Switch14","Switch15","Switch16","Switch17","Switch18","Switch19","Switch20","Switch21","Switch22","Switch23","Switch24","Switch25","Switch26","Switch27","Switch28","Switch29","Switch30","Switch31","Switch32","Switch33","Switch34","Switch35","Switch36","Switch37","Switch38","Switch39","Switch40"],
    ),
]
answers = inquirer.prompt(questions, theme=GreenPassion())
print ('\n' + 'Following Switch has been selected: ' + ' ' + answers["inventory"])

image

edroche74 commented 3 months ago

Thank you for responses but I can't give you my Meraki API key since that will give complete access to our infrastructure. I guess I will need to research more and try to figure it out.

edroche74 commented 3 months ago

I figured it out....(1) of the devices in our inventory being pulled from our Meraki instance had a blank name and once I fixed that I was able to scroll all the way throught the list without it erroring out.