click-repl icon indicating copy to clipboard operation
click-repl copied to clipboard

Question: Wiring up a repl to execute a 3rd level nested click command with a prompt_toolkit input

Open iPoetDev opened this issue 1 year ago • 1 comments

Implementer help sought - start with click_repl (this is where some examples would assist)

Seek to connect the text of an input to executing a click command in a app level repl from a prompt

I see from the readme for an advanced usage ... this is from here.

import click
from click_repl import repl
from prompt_toolkit.history import FileHistory

@click.group()
def cli():
    pass

@cli.command()
def mycli(): # name changed from readme
    prompt_kwargs = {
        'history': FileHistory('.mycli_history'),
    }
    repl(click.get_current_context(), prompt_kwargs=prompt_kwargs)
    
cli()

From Prompt_toolkit, I got me a working nested command structure (str only) This is from their SQL Tutorial https://python-prompt-toolkit.readthedocs.io/en/stable/pages/tutorials/repl.html

import click
from click_repl import repl
from prompt_toolkit import PromptSession
from prompt_toolkit.history import FileHistory

import cmdcomplete # custom local

def cliprompt():
    """Main. Build an SQLite REPL Tutorial"""
    session = PromptSession(
            completer=cmdcomplete.nest_auto,
            history=FileHistory('.mycli-history'))
    
    while True:
        try:
            text = session.prompt('PyCriteria >  ')
        except KeyboardInterrupt:
            continue
        except EOFError:
            break
        else:
            return text
    print('GoodBye!')
  • Note: I have a nested command structure as per AWS
  • https://mauricebrg.com/article/2020/08/advanced_cli_structures_with_python_and_click.html

and my sample/random subcommands from click are, and assume these are in the nest_auto completer

import click

@click.group()
def cli():
    pass


@click.command()
def mycli():
    """MyCli"""
    prompt_kwargs = {
            'history': FileHistory('.mycli-history'),
            }
    repl(click.get_current_context(), prompt_kwargs=prompt_kwargs)


@click.command()
@click.option('--arg1', required=True, help='This is argument 1')
@click.option('--arg2', required=True, help='This is argument 2')
def subcmd1(arg1, arg2):
    print(f'Subcommand 1 with arg1={arg1} and arg2={arg2}')


@click.command()
@click.option('--arg3', required=True, help='This is argument 3')
@click.option('--arg4', required=True, help='This is argument 4')
def subcmd2(arg3, arg4):
    print(f'Subcommand 2 with arg3={arg3} and arg4={arg4}')


cli.add_command(mycli)
mycli.add_command(subcmd1)

So My question is giving me a brain freeze / starter burn

  1. How do I wire up the following so I get the instruction to execute a click command from a prompt_toolkit string input.... ?
  2. I am running my app like this (screenshot)
  3. The logical map of subcommands is the larger screenshot.
if __name__ == '__main__':
    prompttext = cliprompt()
  
    repl(cli, prompt=prompttext)  # as pycharm inspector says Unexpected argument

But I don't know how to link the prompt input to a click command to be fired

The nested command structure is as per AWS command structure base command subcommand (this last entry is the function caller) image image

iPoetDev avatar May 10 '23 17:05 iPoetDev