Write your first command line app using Python

There’re many articles about how to build a python lib, but fewer articles discuss about how to build a command line app using python. This article is to solve the problem.

Prepare

First, we need some knowledge to help us build a command line tool fluently: How app like pip execute when we tap pip in terminal?

Executable file like pip and other command line scripts are locate in /Users/{UserName}/miniconda3/envs/{envName}/bin/pip (My os is macOS Catalina and I use mini-conda for Python env management, in other os, you can type which pip for more information)

When we tap pip install {an exec package}, pip will copy scripts assigned in setup.py to the bin dir in your PATH like /Users/{UserName}/miniconda3/envs/{envName}/bin.

After that, every time you tap{an exec package}, system will execute script above.

So, the core problems are:

  1. What we need to put in the script file in bin directory?
  2. How can we tell the pip to put our executable scripts to bin folder correctly ?

What we need to put in the script file in bin directory?

The answer is very simple, we just need to open a script like pip in the conda/env/{env}/bin.

We can see code like

1
2
3
4
5
6
7
8
9
10
11
#!/Users/{userName}/miniconda3/envs/py38/bin/python

# -*- coding: utf-8 -*-
import re
import sys

from pip._internal.cli.main import main

if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())

The first line is expand dynamically when install the package, which we will discuss next. Line from pip._internal.cli.main import main is to import function from your Real package (Code in {ProjectName}/), it just like a bridge between your script and lib code in {pkg}/.

About sys.exit(main()), you can see StackOverflow Post for more detail.

So, the script file we need to put is like

1
2
3
4
5
6
7
8
9
#!python
import re
import sys

# import your code functions and main functions

if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main()) # or other function name, anyway

Notice: The first line is changed to #!python because when installing, pip will dynamically change to the right python location according to the env.

How can we tell the pip to put our executable scripts to bin folder correctly ?

In setup.py, there is a keyword argument scripts=['bin/{scripts name}'], the value is a list type value, we can to put any scripts to the array.

Simply, we just need to put scripts below in the bin directory.

The project file tree is like

Of course, you can rename you script folder to any name you want, as long as you write the right name in scripts=['bin/{scripts name}'] in setup.py.The screenshot is to help understand the whole project file structure.

Conclusion

In this article, we discuss the very first two steps to build a command line app using Python.

Reference

Build Your First pip Package

评论