argparse
is a Python standard library makes it easy to write a CLI application. You should use this module instead of optparse
which is deprecated since Python 2.7.
ref:
https://docs.python.org/3/library/argparse.html
Basic example
#!/usr/bin/env python
from __future__ import print_function
import argparse
import sys
import jokekappa
class JokeKappaCLI(object):
def __init__(self):
parser = argparse.ArgumentParser(
prog='jokekappa',
description='humor is a serious thing, you should take it seriously',
)
self.parser = parser
self.parser.add_argument('-v', '--version', action='version', version=jokekappa.__version__)
self.subparsers = parser.add_subparsers(title='sub commands')
self.subparsers \
.add_parser('one', help='print one joke randomly') \
.set_defaults(func=self.tell_joke)
self.subparsers \
.add_parser('all', help='print all jokes') \
.set_defaults(func=self.tell_jokes)
self.subparsers \
.add_parser('update', help='update jokes from sources') \
.set_defaults(func=self.update_jokes)
def parse_args(self):
if len(sys.argv) == 1:
namespace = self.parser.parse_args(['one', ])
else:
namespace = self.parser.parse_args()
namespace.func()
def tell_joke(self):
joke = jokekappa.get_joke()
print(joke['content'])
def tell_jokes(self):
for joke in jokekappa.get_jokes():
print(joke['content'])
def update_jokes(self):
jokekappa.update_jokes()
print('Done')
def main():
JokeKappaCLI().parse_args()
if __name__ == '__main__':
main()
ref:
https://github.com/CodeTengu/JokeKappa
https://stackoverflow.com/questions/5176691/argparse-how-to-specify-a-default-subcommand
Advanced example
In following code, you're able to create a Python module called pangu
and a command-line tool also called pangu
, both share the same codebase.
in pangu.py
from __future__ import print_function
import argparse
import sys
__version__ = '3.3.0'
__all__ = ['spacing_text', 'PanguCLI']
def spacing_text(text):
"""
You could find real code in https://github.com/vinta/pangu.py
"""
return text.upper().strip()
class PanguCLI(object):
def __init__(self):
parser = argparse.ArgumentParser(
prog='pangu',
description='paranoid text spacing',
)
self.parser = parser
self.parser.add_argument('-v', '--version', action='version', version=__version__)
self.parser.add_argument('text', action='store', type=str)
def parse(self):
if not sys.stdin.isatty():
print(spacing_text(sys.stdin.read()))
elif len(sys.argv) > 1:
namespace = self.parser.parse_args()
print(spacing_text(namespace.text))
else:
self.parser.print_help()
sys.exit(0)
if __name__ == '__main__':
PanguCLI().parse()
in bin/pangu
#!/usr/bin/env python
from pangu import PanguCLI
if __name__ == '__main__':
PanguCLI().parse()
in setup.py
from setuptools import setup
setup(
name='pangu',
py_modules=['pangu', ],
scripts=['bin/pangu', ],
...
)
As a result, there're multiple usages:
$ pangu "abc"
$ python -m pangu "abc"
$ echo "abc" | pangu
$ echo "abc" | python -m pangu
ABC
ref:
https://github.com/vinta/pangu.py
Accept a list as option
parser.add_argument('-u', '--usernames', type=lambda x: x.split(','), dest='usernames', required=True)
# your_command -u vinta
# your_command -u vinta,saiday
Accept conditional argument
ref:
https://stackoverflow.com/questions/15459997/passing-integer-lists-to-python