We are ready to call our utility from the cmd line, problem is we havenβt setup an entry point. We want to do something like this my_cli args
from the cmd line.
Once we have done that we will proceed to setup argparse which is one of the modules that eases the pain when dealing with input arguments. There are other modules like click, and optparse. Argparse happens the one I use the most in my cmd utilities.
Arguments modules abstract some things to make it easier to handle arguments, it also adds a quick help command based on the arguments setup. You donβt have to worry about calling a wrong argument, argparse will handle that nicely.
Setup Script Entry Point
Documentation for entry points. You can have multiple entry points, but we will only use one.
On setup.py
at the very end:
...
version='0.0.1',
zip_safe=False,
Add the following:
entry_points={
'console_scripts': [
# command = package.module:function
'my_cli = another_package.another_package:say_hello',
],
},
Quick Test
At this point we can uninstall our current utility since weβve modified setup.py
:
pip3 uninstall another-package
cd git/another-package
python3 setup.py develop
If install is sucessfull, go into terminal or cmd prompt and type my_cli
, youβll get the error below. say_hello
needs an argument for the string, and so we get a traceback as we should. And with this we know that our entry point is working as it should, even though we canβt call say_hello
without providing an argument. Note below even when I tried to provide my name, the utility doesnβt know how to handle that arg, fear not argparse to the rescue.
Fernandos-MacBook-Air:another_package terminalX$ my_cli "fer"
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/bin/my_cli", line 11, in <module>
load_entry_point('another-package', 'console_scripts', 'my_cli')()
TypeError: say_hello() missing 1 required positional argument: 'name'
Argparse Setup
Modify another_package.py
, I donβt think __ main __
is necessary since we will be caling main
from our entry point but thatβs how I always setup my utilities. This way you can also call python another_package.py args*
.
# -*- coding: utf-8 -*-
import argparse
"""Main module."""
def say_hello(name):
print("hello %s" % (name))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--name', action="store", help='Provides name')
args = parser.parse_args()
say_hello(args.name)
if __name__ == ' __main__':
main()
Modify setup.py
:
'my_cli = another_package.another_package:main',
Ok we are ready to make yet another test, uninstall, and reinstall as mentioned in the Quick Test section.
Second Test
Once utility is installed run the following commands:
my_cli
my_cli -h
my_cli -n yourname
If everything went ok, you should see your name output properly. If youβd like to know more about argparse check out the documentation.
Fernandos-MacBook-Air:another_package terminalX$ my_cli -n fer
hello fer
Next Article
In the next post we will publish our package to github or any git repo for that matter. Remember having a package in github alone is great since you can install with pip. Thanks for reading, hope you enjoyed, and until the next one.
Top comments (4)
Thanks!
I really like and recommend using click.
It is a package that away some of the burden of defining an argument parser and running it.
Fire, requires even less effort, but it is not as flexible and configurable as click.
Yeah I've been meaning to try it out, just hard to get rid of old habits lol. I know exactly how to use argparse.
At first glance click looks a lot like argparse though, what are some of the benefits as oppose to using argparse?
The major benefit is that click helps you describe the parameters you expect and injects them directly as function arguments. And then executes the function.
It takes the burden of explicitly calling a parser and invoking your own function.
This also makes it easy to nest functions without your intervention.
I also find the definition of arguments more intuitive, but that might be a matter of taste (I was never fluent in argparse).
In
click
s documentation they have a whole page that compares them to argparse and optparse.Thanks for the info! I like the decorators and not having to use the parser explicitly. Will definitely give it a try on my next utility.