Python CLI with click
2023-05-22 python click CLI arguments help generationIn previous article I showed simple python script to extract data from ispell dictionaries. It worked well for first pass on the problem, but as the Hangman implementation continues, I needed to generate the list of words with different parameters. Coincidentally, I read an article about reading the docs and usage of click that pointed me to quite nice extensions of regular python function.
Here is the example. I started with main
function implemented like this
import click
@click.command()
@click.argument('input', type=click.File('r', encoding='utf-8'))
@click.option('-o', '--output', type=click.File('w', lazy=False, encoding='utf-8'), default='-', help='Write to file instead of stdout.')
def main(input, output):
for entry in filter(longer_noun, ispell_entries(input)):
output.write(entry[0] + '\n')
if __name__ == '__main__':
main()
The example shows input
and output
parameters that are automatically opened as a file and supplied by click. The interface is pretty standard, allows to read stdin and output to stdout or specify actual files. Click also does quite some checks to make sure the unicode would work both on console and the files.
This was good start, but lend itself easily to add more parameters and drive the filtering other using the them
@click.command()
@click.argument('input', type=click.File('r', encoding='utf-8'))
@click.option('-o', '--output', type=click.File('w', lazy=False, encoding='utf-8'), default='-',
help='Write words to file instead of stdout.')
@click.option('--min-len', default=5, show_default=True, help='Minimum characters for the word')
@click.option('--max-len', default=8, show_default=True, help='Maximum characters for the word')
@click.option('--pattern', default='HP', show_default=True, help='Pattern for selected words')
def main(input, output, min_len, max_len, pattern):
"""
Extracts noun words of specified length from ispell dictionary.
Files this was designed to work with are from https://github.com/tvondra/ispell_czech
INPUT is the ispell .cat file like hlavni.cat from distribution above
"""
for entry in filter(create_longer_noun_filter(pattern, min_len, max_len), ispell_entries(input)):
output.write(entry[0] + "\n")
click gives you automatically generated help, also. When run with --help
parameter it provides description that utilizes the docstring of the main method, help parameters of click.option
and default values
Usage: ispell-words.py [OPTIONS] INPUT
Extracts noun words of specified length from ispell dictionary. Files this
was designed to work with are from https://github.com/tvondra/ispell_czech
INPUT is the ispell .cat file like hlavni.cat from distribution above
Options:
-o, --output FILENAME Write words to file instead of stdout.
--min-len INTEGER Minimum characters for the word [default: 5]
--max-len INTEGER Maximum characters for the word [default: 8]
--pattern TEXT Pattern for selected words [default: HP]
--help Show this message and exit.
Last thing of interest is creation of filter function using a closure that wraps around parameters of the create_longer_noun_filter
function in inner definition, that is returned and used for filtering of the words
def create_longer_noun_filter(pattern, min_len, max_len):
def longer_noun(entry):
word, flags = entry
if not re.search(f'[{pattern}]', flags):
return False
return min_len <= len(word) <= max_len
return longer_noun