python click autocomplete for (str, str) option

  • Last Update :
  • Techknowledgy :

Code:

def get_opts(ctx, args, incomplete):
   ""
" auto complete for option "
opt "

   : param ctx: The current click context.: param args: The list of arguments passed in .: param incomplete: The partial word that is being completed, as a
string.May be an empty string ''
if no characters have
been entered yet.: return: list of possible choices ""
"
opts = {
   'foo1': ('bar11', 'bar21', 'bar31'),
   'foo2': ('bar12', 'bar22', 'bar32'),
   'fox3': ('bar13', 'bar23', 'bar33'),
}
if args[-1] == '--opt':
   possible_choices = opts.keys()
elif args[-1] in opts:
   possible_choices = opts[args[-1]]
else:
   possible_choices = ()
return [arg
   for arg in possible_choices
   if arg.startswith(incomplete)
]

You can pass the autocompletion function to click like:

@click.option('--opt', type = (str, str), autocompletion = get_opts)

Test Code:

import click

@click.command()
@click.option('--opt', type = (str, str), autocompletion = get_opts)
@click.argument('arg')
def cli(opt, arg):
   ""
"My Great Cli"
""

if __name__ == "__main__":
   commands = (
      ('--opt', 2, 'foo1 foo2 fox3'),
      ('--opt f', 2, 'foo1 foo2 fox3'),
      ('--opt fo', 2, 'foo1 foo2 fox3'),
      ('--opt foo', 2, 'foo1 foo2'),
      ('--opt fox', 2, 'fox3'),
      ('--opt foz', 2, ''),
      ('--opt foo2 b', 3, 'bar12 bar22 bar32'),
      ('--opt foo2 bar1', 3, 'bar12'),
      ('--opt foo2 baz', 3, ''),
   )

import os
import sys
from unittest
import mock
from click._bashcomplete
import do_complete

failed = []
for cmd_args in commands:
   cmd_args_with_arg = (
      'arg ' + cmd_args[0], cmd_args[1] + 1, cmd_args[2])
for cmd in (cmd_args, cmd_args_with_arg):
   with mock.patch('click._bashcomplete.echo') as echo:
   os.environ['COMP_WORDS'] = 'x ' + cmd[0]
os.environ['COMP_CWORD'] = str(cmd[1])
do_complete(cli, 'x', False)
completions = [c[0][0]
   for c in echo.call_args_list
]
if completions != cmd[2].split():
   failed.append(completions, cmd[2].split())

print('Click Version: {}'.format(click.__version__))
print('Python Version: {}'.format(sys.version))
if failed:
   for fail in failed:
   print('Got {}, expected {}'.format(completions, cmd[2].split()))
else:
   print('All tests passed')

Suggestion : 2

I am writing a CLI tool with Python and anycodings_python-click Click. One of the commands has an option of anycodings_python-click type=(str, str)) which is used like this: anycodings_python-click command subcommand --option foo bar.,The question is: how can I use the support anycodings_python-click that Click provides to write an anycodings_python-click autocompletion for that?,You can pass the autocompletion function anycodings_python-click to click like:,To autocomplete a click option which is anycodings_python-click two strings, in which the second string anycodings_python-click depends on the first, you do not need anycodings_python-click two completion functions. You simply anycodings_python-click need a way to determine which of the two anycodings_python-click strings is currently being completed. anycodings_python-click For an option named --opt we can anycodings_python-click complete a type of (str, str) like:

Code:

def get_opts(ctx, args, incomplete):
   ""
" auto complete for option "
opt "

   : param ctx: The current click context.: param args: The list of arguments passed in .: param incomplete: The partial word that is being completed, as a
string.May be an empty string ''
if no characters have
been entered yet.: return: list of possible choices ""
"
opts = {
   'foo1': ('bar11', 'bar21', 'bar31'),
   'foo2': ('bar12', 'bar22', 'bar32'),
   'fox3': ('bar13', 'bar23', 'bar33'),
}
if args[-1] == '--opt':
   possible_choices = opts.keys()
elif args[-1] in opts:
   possible_choices = opts[args[-1]]
else:
   possible_choices = ()
return [arg
   for arg in possible_choices
   if arg.startswith(incomplete)
]

You can pass the autocompletion function anycodings_python-click to click like:

@click.option('--opt', type = (str, str), autocompletion = get_opts)

Test Code:

import click

@click.command()
@click.option('--opt', type = (str, str), autocompletion = get_opts)
@click.argument('arg')
def cli(opt, arg):
   ""
"My Great Cli"
""

if __name__ == "__main__":
   commands = (
      ('--opt', 2, 'foo1 foo2 fox3'),
      ('--opt f', 2, 'foo1 foo2 fox3'),
      ('--opt fo', 2, 'foo1 foo2 fox3'),
      ('--opt foo', 2, 'foo1 foo2'),
      ('--opt fox', 2, 'fox3'),
      ('--opt foz', 2, ''),
      ('--opt foo2 b', 3, 'bar12 bar22 bar32'),
      ('--opt foo2 bar1', 3, 'bar12'),
      ('--opt foo2 baz', 3, ''),
   )

import os
import sys
from unittest
import mock
from click._bashcomplete
import do_complete

failed = []
for cmd_args in commands:
   cmd_args_with_arg = (
      'arg ' + cmd_args[0], cmd_args[1] + 1, cmd_args[2])
for cmd in (cmd_args, cmd_args_with_arg):
   with mock.patch('click._bashcomplete.echo') as echo:
   os.environ['COMP_WORDS'] = 'x ' + cmd[0]
os.environ['COMP_CWORD'] = str(cmd[1])
do_complete(cli, 'x', False)
completions = [c[0][0]
   for c in echo.call_args_list
]
if completions != cmd[2].split():
   failed.append(completions, cmd[2].split())

print('Click Version: {}'.format(click.__version__))
print('Python Version: {}'.format(sys.version))
if failed:
   for fail in failed:
   print('Got {}, expected {}'.format(completions, cmd[2].split()))
else:
   print('All tests passed')

Suggestion : 3

Custom completions can be provided for argument and option values by providing an autocompletion function that returns a list of strings. This is useful when the suggestions need to be dynamically generated completion time. The callback function will be passed 3 keyword arguments:,Generally, the shell completion support will complete commands, options, and any option or argument values where the type is click.Choice. Options are only listed if at least a dash has been entered.,ZSH and fish support showing documentation strings for completions. These are taken from the help parameters of options and subcommands. For dynamically generated completions a help string can be provided by returning a tuple instead of a string. The first element of the tuple is the completion and the second is the help string to display.,Here is an example of using a callback function to generate dynamic suggestions with help strings:

$ repo <TAB>
   <TAB>
      clone commit copy delete setuser
      $ repo clone -<TAB>
         <TAB>
            --deep --help --rev --shallow -r
import os

def get_env_vars(ctx, args, incomplete):
   return [k
      for k in os.environ.keys() if incomplete in k
   ]

@click.command()
@click.argument("envvar", type = click.STRING, autocompletion = get_env_vars)
def cmd1(envvar):
   click.echo('Environment variable: %s' % envvar)
click.echo('Value: %s' % os.environ[envvar])
import os

def get_colors(ctx, args, incomplete):
   colors = [('red', 'a warm color'),
      ('blue', 'a cool color'),
      ('green', 'the other starter color')
   ]
return [c
   for c in colors
   if incomplete in c[0]
]

@click.command()
@click.argument("color", type = click.STRING, autocompletion = get_colors)
def cmd1(color):
   click.echo('Chosen color is %s' % color)
eval "$(_FOO_BAR_COMPLETE=source_bash foo-bar)"
eval "$(_FOO_BAR_COMPLETE=source_zsh foo-bar)"
eval(env _FOO_BAR_COMPLETE = source_fish foo - bar)

Suggestion : 4

We get all the CLI parameters as a raw list of str by declaring a parameter with type List[str], here it's named args.,Here we name the list of all the raw CLI parameters args because that's the convention with Click.,You can also get the raw CLI parameters, just a list of str with everything passed in the command line before the incomplete value.,We are getting the names already provided with --name in the command line before this completion was triggered.

import typer

def main(name: str = typer.Option("World", help = "The name to say hi to.")):
   print(f "Hello {name}")

if __name__ == "__main__":
   typer.run(main)
// Hit the TAB key in your keyboard below where you see the: [TAB]
$ typer. / main.py[TAB][TAB]

// Depending on your terminal/shell you will get some completion like this ✨
run--Run the provided Typer app.
utils--Extra utility commands
for Typer apps.

// Then try with "run" and --
$ typer. / main.py run--[TAB][TAB]

   // You will get completion for --name, depending on your terminal it will look something like this
   --name--The name to say hi to.

// And you can run it as if it was with Python directly
$ typer. / main.py run--name Camila

Hello Camila
import typer

def complete_name():
   return ["Camila", "Carlos", "Sebastian"]

def main(
      name: str = typer.Option(
         "World", help = "The name to say hi to.", autocompletion = complete_name
      )
   ):
   print(f "Hello {name}")

if __name__ == "__main__":
   typer.run(main)
$ typer. / main.py run--name[TAB][TAB]

// We get the values returned from the function 🎉
Camila Carlos Sebastian
import typer

valid_names = ["Camila", "Carlos", "Sebastian"]

def complete_name(incomplete: str):
   completion = []
for name in valid_names:
   if name.startswith(incomplete):
   completion.append(name)
return completion

def main(
      name: str = typer.Option(
         "World", help = "The name to say hi to.", autocompletion = complete_name
      )
   ):
   print(f "Hello {name}")

if __name__ == "__main__":
   typer.run(main)
$ typer. / main.py run--name Ca[TAB][TAB]

// We get the values returned from the function that start with Ca 🎉
Camila Carlos

Suggestion : 5

September 15, 2021by Zhen Chen

Create a command

import click
from utils
import PyOrm

@click.group(no_args_is_help = False, add_help_option = False, invoke_without_command = True)
@click.pass_context
def cli(ctx):
   ""
"Milvus CLI"
""
ctx.obj = PyOrm() # PyOrm is a util class which wraps the milvus python SDK.You can pass any class instance here.Any command
function passed by @click.obj can call it.

if __name__ == '__main__':
   cli()

Then we add the first sub command help under cli:

# Print the help message of specified command.
def print_help_msg(command):
   with click.Context(command) as ctx:
   click.echo(command.get_help(ctx))

# Use @cli.command() to create a sub command of cli.
@cli.command()
def help():
   ""
"Show help messages."
""
# Print help message of cli.
click.echo(print_help_msg(cli))

Now we can use cli help in terminal:

$ python milvus_cli / scripts / milvus_cli.py help

Then we add some sub commands into this sub group by @listDetails.command() (not @cli.command()). Here's just an example, you can ignore the implement and we will discuss it later.

@listDetails.command()
@click.option('--timeout', 'timeout', help = "[Optional] - An optional duration of time in seconds to allow for the RPC. When timeout is set to None, client waits until server response or error occur.",
   default = None)
@click.option('--show-loaded', 'showLoaded', help = "[Optional] - Only show loaded collections.",
   default = False)
@click.pass_obj
def collections(obj, timeout, showLoaded):
   ""
"List all collections."
""
try:
obj.checkConnection()
click.echo(obj.listCollections(timeout, showLoaded))
except Exception as e:
   click.echo(message = e, err = True)

@listDetails.command()
@click.option('-c', '--collection', 'collection', help = 'The name of collection.',
   default = '')
@click.pass_obj
def partitions(obj, collection):
   ""
"List all partitions of the specified collection."
""
try:
obj.checkConnection()
validateParamsByCustomFunc(
   obj.getTargetCollection, 'Collection Name Error!', collection)
click.echo(obj.listPartitions(collection))
except Exception as e:
   click.echo(message = e, err = True)

And all options' values will be passed into the function in order of definition.

@cli.command(no_args_is_help = False)
@click.option('-a', '--alias', 'alias', help = "Milvus link alias name, default is `default`.",
   default = 'default', type = str)
@click.option('-h', '--host', 'host', help = "Host name, default is `127.0.0.1`.",
   default = '127.0.0.1', type = str)
@click.option('-p', '--port', 'port', help = "Port, default is `19530`.",
   default = 19530, type = int)
@click.pass_obj
def connect(obj, alias, host, port):
   pass

Suggestion : 6

Last updated on 2022-05-24.

import panel as pn
pn.extension()
autocomplete = pn.widgets.AutocompleteInput(
   name = 'Autocomplete Input', options = ['Biology', 'Chemistry', 'Physics'],
   placeholder = 'Write something here')

pn.Row(autocomplete, height = 100)
autocomplete.value
''
not_restricted = autocomplete.clone(value = 'Mathematics', restrict = False)
pn.Row(not_restricted, height = 100)
not_restricted.value

Suggestion : 7

Initialize the autocomplete with the classes option specified, changing the theming for the ui-autocomplete class:,Initialize the autocomplete with the appendTo option specified:,Initialize the autocomplete with the minLength option specified:,Initialize the autocomplete with the autoFocus option specified:

$(".selector").autocomplete({
   appendTo: "#someElem"
});
// Gettervar appendTo = $( ".selector" ).autocomplete( "option", "appendTo" ); // Setter$( ".selector" ).autocomplete( "option", "appendTo", "#someElem" );
$(".selector").autocomplete({
   autoFocus: true
});
// Gettervar autoFocus = $( ".selector" ).autocomplete( "option", "autoFocus" ); // Setter$( ".selector" ).autocomplete( "option", "autoFocus", true );
$(".selector").autocomplete({
   classes: {
      "ui-autocomplete": "highlight"
   }
});
// Gettervar themeClass = $( ".selector" ).autocomplete( "option", "classes.ui-autocomplete" ); // Setter$( ".selector" ).autocomplete( "option", "classes.ui-autocomplete", "highlight" );