Skip to content

Instantly share code, notes, and snippets.

@lplume
Forked from tomschr/example-cli-argparse.py
Created August 4, 2017 07:46
Show Gist options
  • Save lplume/5ca51d8788ea9eb179c61b02a5a8c59a to your computer and use it in GitHub Desktop.
Save lplume/5ca51d8788ea9eb179c61b02a5a8c59a to your computer and use it in GitHub Desktop.
Template for an example CLI program with docopts and logging
#!/usr/bin/env python3
"""
Does some fancy stuff
Usage:
{proc} [-h | --help]
{proc} [-v ...] INPUT OUTPUT
Options:
-h, --help Shows this help
-v Raise verbosity level
Arguments:
INPUTDIR some input things
OUTPUTDIR some output things
"""
__version__ = "0.1.0"
__author__ = "Tux Penguin <[email protected]>"
from docopt import docopt
import logging
from logging.config import dictConfig
from os.path import basename
import sys
#: The dictionary, used by :class:`logging.config.dictConfig`
#: use it to setup your logging formatters, handlers, and loggers
#: For details, see https://docs.python.org/3.4/library/logging.config.html#configuration-dictionary-schema
DEFAULT_LOGGING_DICT = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {'format': '[%(levelname)s] %(name)s: %(message)s'},
},
'handlers': {
'default': {
'level': 'NOTSET',
'formatter': 'standard',
'class': 'logging.StreamHandler',
},
},
'loggers': {
__name__: {
'handlers': ['default'],
'level': 'INFO',
'propagate': True
}
}
}
#: Map verbosity level (int) to log level
LOGLEVELS = {None: logging.WARNING, # 0
0: logging.WARNING,
1: logging.INFO,
2: logging.DEBUG,
}
#: Instantiate our logger
log = logging.getLogger(__name__)
def parsecli(cliargs=None):
"""Parse CLI arguments with docopt
:param list cliargs: List of commandline arguments or None (=use sys.argv)
:type clicargs: list | None
:return: dictionary from docopt
:rtype: dict
"""
version = "%s %s" % (__name__, __version__)
args = docopt(__doc__.format(proc=basename(sys.argv[0])),
argv=cliargs,
version=version)
# Setup logging and the log level according to the "-v" option
dictConfig(DEFAULT_LOGGING_DICT)
log.setLevel(LOGLEVELS.get(args['-v'], logging.DEBUG))
log.debug("CLI result: %s", args)
return args
def main(cliargs=None):
"""Entry point for the application script
:param list cliargs: Arguments to parse or None (=use sys.argv)
:type clicargs: list | None
:return: error codes
:rtype: int
"""
try:
args = parsecli(cliargs)
# do some useful things here...
# If everything was good, return without error:
return 0
# List possible exceptions here and turn exceptions into return codes
except Exception as error: # this should be a more specific exception
log.fatal(error)
# Use whatever return code is appropriate for your specific exception
return 10
if __name__ == "__main__":
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment