Last active
September 27, 2017 19:41
-
-
Save gomisc/3525178867b6cfa9d86d43351c9a72f8 to your computer and use it in GitHub Desktop.
Python CLI interface
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import os, sys, argparse, traceback | |
| class cli(object): | |
| """""" | |
| def __init__(self, prog, version, args=None): | |
| self.prog = prog | |
| self.version = version | |
| self.parser = argparse.ArgumentParser(prog=prog) | |
| self.parser.add_argument('-V', '--version', action='version', version=version) | |
| self.parser.add_argument('-v', '--verbose', action="store_true", help='set verbosity level. default: %(default)s') | |
| self.parser.add_argument('-vv', '--showtb', action="store_true", help='show traceback. default: %(default)s') | |
| self.parser.add_argument('-d', '--debug', type=int, default=0, help='set debug\n [0]none [1]local\n [2]remote. default: %(default)s') | |
| self.args = args | |
| self.cmds = None | |
| def __enter__(self): | |
| return self | |
| def __exit__(self, t, v, tb): | |
| try: | |
| args = self.parser.parse_args(self.args) | |
| if not hasattr(args, 'exe'): | |
| self.parser.print_usage() | |
| else: | |
| if hasattr(args, 'debug'): | |
| if args.debug == 2: | |
| try: import pydevd; pydevd.settrace(host='127.0.0.1') | |
| except: return 0 | |
| elif args.debug == 1: | |
| try: import pdb; pdb.set_trace() | |
| except: return 0 | |
| args.exe(args) | |
| except KeyboardInterrupt: | |
| return 0 | |
| except Exception: | |
| e_t, e_v, e_tb = sys.exc_info() | |
| e_lines = traceback.format_exception(e_t, e_v, e_tb) | |
| e_caption = "%s:" % self.prog | |
| e_shift = len(e_caption) * " " | |
| print(e_caption, file=sys.stderr) | |
| if getattr(args, 'showtb', False): | |
| print(e_shift + '\n'.join(e_lines), file=sys.stderr) | |
| else: | |
| e_desc = e_lines[-2].split('\n') | |
| e_flist = e_desc[0].split(', ') | |
| print(e_shift + e_lines[-1].strip(), file=sys.stderr) | |
| print(e_shift + "In: %s %s\n%s%s" % | |
| (e_flist[0], e_flist[1], e_shift, e_desc[1].strip()), | |
| file=sys.stderr | |
| ) | |
| print(e_shift + "for help use --help\n", file=sys.stderr) | |
| return 2 | |
| def deffunc(self, f): | |
| self.parser.set_defaults(exe=f) | |
| def arg(self, *a, **kw): | |
| self.parser.add_argument(*a, **kw) | |
| def cmd(self, name, **kw): | |
| if self.cmds is None: | |
| self.cmds = self.parser.add_subparsers(help='commands') | |
| p = self.cmds.add_parser(name, **kw) | |
| p.set_defaults(cmd=name) | |
| p.arg = lambda *a, **kw: p.add_argument(*a, **kw) and p | |
| p.exe = lambda f: p.set_defaults(exe=f) and p | |
| return p | |
| ########## Usage example: | |
| """ | |
| cli.py --help | |
| usage: example [-h] [-V] [-v] [-vv] [-d DEBUG] {start,stop} ... | |
| positional arguments: | |
| {start,stop} commands | |
| start Start example | |
| stop Stop example | |
| optional arguments: | |
| -h, --help show this help message and exit | |
| -V, --version show program's version number and exit | |
| -v, --verbose set verbosity level. default: False | |
| -vv, --showtb show traceback. default: False | |
| -d DEBUG, --debug DEBUG | |
| set debug [0]none [1]local [2]remote. default: 0 | |
| cli.py start -h | |
| usage: example start [-h] [-c CONF] [-a HOST] [-p PORT] | |
| optional arguments: | |
| -h, --help show this help message and exit | |
| -c CONF, --conf CONF session config file | |
| -a HOST, --host HOST Example host. [8080] | |
| -p PORT, --port PORT Example port. [0.0.0.0] | |
| """ | |
| name = "example" | |
| version = "1.0.1" | |
| def start(**kw): pass | |
| def stop(**kw): pass | |
| if __name__ == "__main__": | |
| with cli(name, version) as command: | |
| command.cmd('start', help='Start example')\ | |
| .arg('-c', '--conf', type=str, help='session config file')\ | |
| .arg('-a', '--host', type=int, default=8080, help='Example host. [%(default)s]')\ | |
| .arg('-p', '--port', type=str, default="0.0.0.0", help='Example port. [%(default)s]')\ | |
| .exe(lambda a: start(conf=a.conf, host=a.host, port=a.port, debug=a.debug, verbose=a.verbose)) | |
| command.cmd('stop', help='Stop example')\ | |
| .exe(lambda a: stop(debug=a.debug, verbose=a.verbose)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment