I'm trying to build an interactive menu using py-click. Basically just a structure that:
My code:
import click
@click.group(invoke_without_command=True)
@click.pass_context
def main_group(ctx):
""" Lists all the submenu options available"""
cmds = main_group.list_commands(ctx)
click.echo(f"Available options:")
for idx, cmd_str in enumerate(cmds):
click.echo(f"{idx}:{cmd_str}")
click.echo(f"Now that you know all the options, let's make a selection:")
ctx.invoke(main_group.get_command(ctx, "selection"))
@main_group.command()
@click.option('--next_cmd', prompt='Next command:', help="Enter the number corresponding to the desired command")
@click.pass_context
def selection(ctx, next_cmd):
click.echo(f"You've selected {next_cmd}")
# check that selection is valid
# invoke the desired command
# return to parent previous command
@main_group.command()
def submenu_1():
click.echo('A submenu option ')
@main_group.command()
def submenu_2():
click.echo('Another option')
if __name__ == '__main__':
main_group()
However, the output from the above is:
Available options:
0:application-code
1:selection
2:submenu-1
3:submenu-2
Now that you know all the options, let's make a selection:
You've selected None
Process finished with exit code 0
Basically, the prompt from the selection command has no effect. But the selection command itself works, because if I run it directly:
if __name__ == '__main__':
# main_group()
selection()
then I am actually prompted for my selection. So... why is the prompt being ignored? Or is the basic premise behind my approach to building this the issue, e.g. Click isn't meant for that?
EDIT: Going through a bunch of git repo that uses this library, including the examples they provide, I haven't been able to find any that build a structure somewhat similar to what I want. Basically the paradigm of building a click-application seems to be isolated command that perform action that modify the state of something, not so much a navigation through a menu offering different options. Not to say it's impossible, but it doesn't seem to be supported out of the box either.
No answers given to this question. I've spent some more time on this. I've made a little bit of progress on this but I am still not able to have something such as:
Main Menu
- Option 1
- Option 2
- Option 3
- Submenu 1
and then
Submenu 1
- Option 1
- Option 2
- Submenu 2
- Back to Main
etc. My conclusion is that click isn't the right tool to use for that. In fact, I'm not sure the alternative would necessarily make it much easier either (argparse, docopt, ...). Maybe to do that the best approach would be to just build a class structure yourself.
Or then, go with an approach that's closer to what the shell or docker use, don't bother with any menu navigation and just launch atomic commands that act on the state of the application.