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.
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.
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.
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.
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.
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:
Option
that may or may not display a prompt must be configured as if displaying a prompt.Option
, so an alternate value-source is a must. I.e. a default value must be provided.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With