loading...

Part 4 Argparse and Script Entry Points

kodaman2 profile image Fernando B 🚀 Originally published at kodaman2.github.io on ・2 min read

Python Packages Development (5 Part Series)

1) Part 1 Introduction to Python Packages 2) Part 2 A Basic Package 3) Part 3 Another Package with Cookiecutter 4) Part 4 Argparse and Script Entry Points 5) Part 5 Package and Deployment

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.

Python Packages Development (5 Part Series)

1) Part 1 Introduction to Python Packages 2) Part 2 A Basic Package 3) Part 3 Another Package with Cookiecutter 4) Part 4 Argparse and Script Entry Points 5) Part 5 Package and Deployment

Posted on by:

kodaman2 profile

Fernando B 🚀

@kodaman2

Coding space junkie with a sprinkle of writer heart. DMs open for any questions or comments. 🙂

Discussion

markdown guide
 

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 clicks 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.