Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python-click: Adding an option that modifies the behavior of other parameters

This question is about the click package:

Click is a Python package for creating beautiful command line interfaces in a composable way with as little code as necessary. It’s the “Command Line Interface Creation Kit”. It’s highly configurable but comes with sensible defaults out of the box.

It aims to make the process of writing command line tools quick and fun while also preventing any frustration caused by the inability to implement an intended CLI API.

I'd like to add a click.Option to my click.Command, which changes the behavior of the other parameters of that command. Consider the following example:

@click.option('--x', default=42, prompt=True)
@click.command
def cli_a(x):
  print(x)


@click.option('--x', default=42, prompt=False)
@click.command
def cli_b(x):
  print(x)

If cli_a is called without explicitly specifying x the user is prompted to provide a value (or confirm the default value with ENTER). If cli_b is called without specifying x the default value is used without prompting the user.

I'd now like to add a flag click.Option that allows the user to choose between one of the above variants (at runtime). So, calling cli_c --i would behave like cli_a and calling cli_c would behave like cli_b.

@click.option('--i', is_flag=True, default=False, expose_value=False)
@click.option('--x', default=42, prompt=False)
@click.command
def cli_c(x):
  print(x)

Is that doable with the current API? Is it feasible?

A similar use-case would be something like an anwser-all-confimation-prompts-with-yes flag. Usually this comes up if the cli tool is supposed to be usable interactively by the user and in automated mode via a script or some such thing.

like image 292
PeterE Avatar asked Sep 18 '15 16:09

PeterE


People also ask

What is Click option in Python?

Click, or “Command Line Interface Creation Kit” is a Python library for building command line interfaces. The three main points of Python Click are arbitrary nesting of commands, automatic help page generation, and supporting lazy loading of subcommands at runtime.

What is on click option?

A user interface technique for Mac computers, where the Option key is depressed and held down while the mouse is clicked on an item onscreen. Depending on the context — what is clicked, which app is active, etc., — a variety of functions may be initiated.

Which of the following is parameter of the click command?

Click supports two types of parameters for scripts: options and arguments. There is generally some confusion among authors of command line scripts of when to use which, so here is a quick overview of the differences. As its name indicates, an option is optional.

What is click Pass_context?

This is a special attribute where commands are supposed to remember what they need to pass on to their children. In order for this to work, we need to mark our function with pass_context() , because otherwise, the context object would be entirely hidden from us.


1 Answers

I have come up with following code, which produces the desired behavior:

def deactivate_prompts(ctx, param, value):
    if not value:
        click.echo("entering batch mode, deactivating all prompts ...")
        for p in ctx.command.params:
            if isinstance(p, click.Option) and p.prompt is not None:
                p.prompt = None
    return value

@click.option('--i/--b', default=True, is_eager=True, expose_value=False, callback=deactivate_prompts)
@click.option('--x', default=42, prompt=True)
@click.command
def cli_c(x):
  print(x)

The idea is to use the callback of an eager option to modify all (other) Options of the Command.

POTENTIAL WEAK POINTS:

  • This is an all or nothing solution, i.e. either all of the prompts are active or none. For my use-case, that's exactly what I wanted, but for others that might not be the case.
  • This works only in one direction, i.e. by turning the prompts off. So each Option that may or may not display a prompt must be configured as if displaying a prompt.
  • If we turn off the prompts, we still need a value for that Option, so an alternate value-source is a must. I.e. a default value must be provided.
like image 59
PeterE Avatar answered Nov 03 '22 07:11

PeterE