Automagic shell tab completion for Python CLI applications
shtab is a Python library that automatically generates shell tab completion scripts for command-line interface (CLI) applications. It processes an `argparse.ArgumentParser` object to produce completion scripts for `bash`, `zsh`, and `tcsh`. It aims for speed and correctness, avoiding the side-effects and performance issues of alternatives like `argcomplete` and `pyzshcomplete`. As of version 1.8.0, it is actively maintained by Iterative AI, with its development often driven by the needs of projects like DVC, but designed for general-purpose use.
Warnings
- gotcha Shell environment setup is crucial. Users must ensure their shell (e.g., bash, zsh) is configured to source completion scripts, and the `shtab`-generated script is placed in a directory where the shell looks for completions (e.g., `~/.bashrc.d/`, `$fpath` for zsh). In addition, both `shtab` and the application it's completing must be accessible/importable from the environment where the completion script is generated and used.
- gotcha By default, `shtab` may silently fail if it cannot import the requested application's parser object. This can lead to confusion if completion isn't working as expected without any error messages. Additionally, the `prog` argument of `argparse.ArgumentParser` must accurately reflect the executable's name for correct completion, especially when using `options.entry_points.console_scripts` or direct script execution.
Install
-
pip install shtab -
conda install -c conda-forge shtab
Imports
- complete
import shtab; shtab.complete(...)
- add_argument
import shtab; shtab.add_argument(parser, ...)
Quickstart
import argparse
import shtab
import os
def get_main_parser():
parser = argparse.ArgumentParser(prog='mycli', description='A simple CLI tool')
parser.add_argument('--auth-key', type=str, default=os.environ.get('MYCLI_AUTH_KEY', ''), help='Authentication key')
parser.add_argument('--output', '-o', choices=['json', 'yaml', 'text'], default='text', help='Output format')
parser.add_argument('command', choices=['status', 'run', 'config'], help='Command to execute')
return parser
if __name__ == '__main__':
parser = get_main_parser()
# Integrate shtab for completion. This creates a hidden argument like --print-completion
shtab.add_argument(parser, shells=['bash', 'zsh', 'tcsh'])
args = parser.parse_args()
# Example of how a user would generate and install completion:
# mycli --print-completion bash > ~/.bashrc.d/mycli.bash-completion
# source ~/.bashrc.d/mycli.bash-completion
print(f"Running command: {args.command}")
if args.auth_key:
print("Auth key provided.")
else:
print("No auth key provided.")
print(f"Output format: {args.output}")