Your python code is now 100% more elegant and usable as a command-line program u...
source link: https://www.tuicool.com/articles/iYJ3auU
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Your python code is now 100% more elegant and usable as a command-line program using Click
Many people who use python are used to the scriptfile workflow, where you write a rigid script in python and run it, somewhat similar to how people use bash scripts.
- You find an answer in a blog somewhere that describes how to do something in python
- You draft up a python script for the task and get it to work
- You hard-code all the parameters the script needs
Don't get me wrong – drafting up python scripts to prototype your idea is really useful. You get your idea working fast, even if your code becomes messy and unmaintainable.
However, wouldn't you like your python script to be as elegant and usable as all the command-line utilities you're used to?
ls -l find -name *.py grep -r "some text" ssh --version
What if I told you it's SUPER easy to give your python script a full-featured Command Line Interface (CLI)
For kicks, lets take the python3 print()
function, and give it a CLI. Kind of like the echo
command in bash.
This is the definition of print()
: https://docs.python.org/3/library/functions.html#print
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
So in python, you can print in all sorts of ways, more than just print('hello')
. For example, you can add customized string to append to the end, change the seperator between words, and output to a file instead of stdout.
print('hello', end='\r') # brings cursor back to beginning of line print('hello', 'hi', sep=',') # prints commas between each word print('hello', file=open('out.txt', 'w')) # write output to file
The simple CLI
Take a look on how easy it is to turn the print statement above into a full-featured CLI.
print.py
#!/usr/bin/env python3 import click import sys @click.command() @click.argument('args', nargs=-1) @click.option('-s', '--sep', default=' ', help='String to seperate each argument (default: " ")]') @click.option('-e', '--end', default='\n', help='String to append to end (default: "\\n")') @click.option('-o', '--out', default=None, help='Output file (default: stdout)') def print_prog(args, sep, end, out): '''Print the arguments you give this program to stdout or to a file. Similar to echo. ''' print(*args, sep=sep, end=end, file=open(out, 'w') if out else sys.stdout) if __name__ == '__main__': print_prog()
Essentially this script is taking all the command line arguments and giving them directly to the print()
function. So we are in effect giving the bash-terminal all the capabilities of python's print()
. Instead of print
this CLI program could easily be changed to perform any scripting task with flexible and configurable input.
Now that we have our command-line-enabled python script, lets see how well it does…
echoing things
./print.py can it echo this?
can it echo this?
displaying help menu
./print.py --help
Usage: print.py [OPTIONS] [ARGS]... Print the arguments you give this program to stdout or to a file. Similar to echo. Options: -s, --sep TEXT String to seperate each argument (default: " ")] -e, --end TEXT String to append to end (default: "\n") -o, --out TEXT Output file (default: stdout) --help Show this message and exit.
Wow… we can already see this has more features than the ever-so-useful echo
For example, we can change the seperator between the args
./print.py these args are seperated by dashes --sep='-'
these-args-are-seperated-by-dashes
Also, not always ending with just a newline
./print.py maybe I want 2 newlines --end=$'\n\n' && print.py instead
maybe I want 2 newlines instead
You can write to a file too
./print.py write this to a file --out=file.txt
Then read the file
cat file.txt
write this to a file
Making this your own
This was a demonstration to show you how easy it is to create your own CLI. You don't need write plain python scriptfiles anymore.
Take this template and apply it to your own program.
Visit the Click website
to reference the Click
documentation while building your projects.
Also, for a slightly more complex example, you can check out my QuadArt project
which uses Click CLI to be usable by anyone through the terminal. I wrote a blog post about it here
. Here is an exerpt of the part of quadart.py
that uses Click
:
@click.command() @click.argument('filename') @click.option('-l', '--left', default=None, help='left pixel of image') @click.option('-r', '--right', default=None, help='right pixel of image') @click.option('-u', '--up', default=None, help='top pixel of image') @click.option('-d', '--down', default=None, help='bottom pixel of image') @click.option('-o', '--output', default=None, help='name of file to save result to') @click.option('-s', '--size', default=512, help='Output size') @click.option('-t', '--type', 'draw_type', default='circle', help='Draw type') @click.option('--thresh', default=10, help='Standard deviation threshold for color difference') @click.option('-m', '--max-recurse', 'max_recurse', default=0, help='Maximum allowed recursion depth. Default is infinity.') def main(filename, left, right, up, down, output, size, draw_type, thresh, max_recurse): quadart = QuadArt(std_thresh=thresh, draw_type=draw_type, max_recurse=max_recurse) quadart.generate(filename, left=left, right=right, up=up, down=down, output_size=size) if output is None: quadart.display() else: quadart.save(output) if __name__ == '__main__': main()
This is the magic of combining python and the terminal with the glue of CLI. The possibilities are endless!
See you next post.
–Ricky
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK