When using click I know how to define a multiple choice option. I also know how to set an option as a required one. But, how can I indicate that an option B is required only if the value of option A is foo?
Here's an example:
import click
@click.command()
@click.option('--output',
type=click.Choice(['stdout', 'file']), default='stdout')
@click.option('--filename', type=click.STRING)
def main(output, filename):
print("output: " + output)
if output == 'file':
if filename is None:
print("filename must be provided!")
else:
print("filename: " + str(filename))
if __name__ == "__main__":
main()
If the output option is stdout, then filename is not needed. However, if the user chooses output to be file, then the other option filename must be provided. Is this pattern supported by click?
At the beginning of the function I can add something like:
if output == 'file' and filename is None:
raise ValueError('When output is "file", a filename must be provided')
But I am interested whether there's a nicer/cleaner solution.
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.
Python click simple example The example creates a command that outputs a message. Click uses the echo instead of the print . It increases compatibility and adds colouring support. $ ./simple.py Hello there $ ./simple.py --help Usage: simple.py [OPTIONS] Options: --help Show this message and exit.
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.
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.
In the particular case of this example, I think an easier method would be to get rid of --output, and simply assume stdout if --filename is not specified and if --filename is specified, then use it instead of stdout.
But assuming this is a contrived example, you can inherit from click.Option to allow hooking into the click processing:
class OptionRequiredIf(click.Option):
def full_process_value(self, ctx, value):
value = super(OptionRequiredIf, self).full_process_value(ctx, value)
if value is None and ctx.params['output'] == 'file':
msg = 'Required if --output=file'
raise click.MissingParameter(ctx=ctx, param=self, message=msg)
return value
To use the custom class, pass it as the cls argument to the option decorator like:
@click.option('--filename', type=click.STRING, cls=OptionRequiredIf)
import click
@click.command()
@click.option('--output',
type=click.Choice(['stdout', 'file']), default='stdout')
@click.option('--filename', type=click.STRING, cls=OptionRequiredIf)
def main(output, filename):
print("output: " + output)
if output == 'file':
if filename is None:
print("filename must be provided!")
else:
print("filename: " + str(filename))
main('--output=file'.split())
Usage: test.py [OPTIONS]
Error: Missing option "--filename". Required if --output=file
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