jeppeter / extargsparse

extension for argparse package
MIT License
2 stars 1 forks source link

extargsparse

python command package for json string set

Release History

simple example

import extargsparse
import sys
commandline = '''
{
    "verbose|v<verbosemode>!attr=new;optfunc=verbose_opt_func!##increment verbose mode##" : "+",
    "flag|f<flagmode>## flag set##" : false,
    "number|n" : 0,
    "list|l<listarr>" : [],
    "string|s" : "string_var",
    "$" : "*"
}
'''

def main():
    options = ExtArgsOptions()
    options.usage = ' sample commandline parser '
    parser = extargsparse.ExtArgsParse(options)
    parser.load_command_line_string(commandline)
    args = parser.parse_command_line()
    print ('verbose = %d'%(args.verbose))
    print ('flag = %s'%(args.flag))
    print ('number = %d'%(args.number))
    print ('list = %s'%(args.list))
    print ('string = %s'%(args.string))
    print ('args = %s'%(args.args))
    return

if __name__ == '__main__':
    main()

if the command line like this python test.py -vvvv -f -n 30 -l bar1 -l bar2 var1 var2

result is like this

verbose = 4
flag = True
number = 30
list = ['bar1', 'bar2']
string = string_var
args = ['var1', 'var2']

some complex example

import extargsparse
commandline = '''
{
    "verbose|v" : "+",
    "port|p" : 3000,
    "dep" : {
        "list|l" : [],
        "string|s" : "s_var",
        "$" : "+"
    }
}
'''

def main():
    options = ExtArgsOptions()
    options.usage = ' sample commandline parser '
    parser = extargsparse.ExtArgsParse(options)
    parser.load_command_line_string(commandline)
    args = parser.parse_command_line(['-vvvv','-p','5000','dep','-l','arg1','--dep-list','arg2','cc','dd'])
    print ('verbose = %d'%(args.verbose))
    print ('port = %s'%(args.port))
    print ('subcommand = %s'%(args.subcommand))
    print ('list = %s'%(args.dep_list))
    print ('string = %s'%(args.dep_string))
    print ('subnargs = %s'%(args.subnargs))

result is like this

verbose = 4
port = 5000
subcommand = dep
list = ['arg1','arg2']
string = 's_var'
subnargs = ['cc','dd']

multiple sub command

import extargsparse
loads = '''
    {
      "verbose|v" : "+",
      "port|p" : 3000,
      "dep" : {
        "list|l" : [],
        "string|s" : "s_var",
        "$" : "+"
      },
      "rdep" : {
        "list|L" : [],
        "string|S" : "s_rdep",
        "$" : 2
      }
    }
'''

def main():
    parser = extargsparse.ExtArgsParse()
    parser.load_command_line_string(loads)
    args = parser.parse_command_line(['-vvvv','-p','5000','rdep','-L','arg1','--rdep-list','arg2','cc','dd'])
    print('verbose %d'%(args.verbose))
    print('port %d'%(args.port))
    print('subcommand %s'%(args.subcommand))
    print('rdep_list %s'%(args.rdep_list))
    print('rdep_string %s'%(args.rdep_string))
    print('subnargs %s'%(args.subnargs))
    return

if __name__ == '__main__':
  main()  

result is two subcommand prepared

verbose 4
port 5000
subcommand rdep
rdep_list ['arg1','arg2']
subnargs ['cc','dd']

use in multi load_command_line_string


import extargsparse

def load_s_1(parser):
    load1 = '''
    {
      "verbose|v" : "+",
      "port|p" : 3000,
      "dep" : {
        "list|l" : [],
        "string|s" : "s_var",
        "$" : "+"
      }
    }
    '''
    parser.load_command_line_string(load1)
    return parser

def load_s_2(parser):
    load2 = '''
    {
      "rdep" : {
        "list|L" : [],
        "string|S" : "s_rdep",
        "$" : 2
      }
    }
    '''
    parser.load_command_line_string(load2)
    return parser

def main():
    parser = extargsparse.ExtArgsParse()
    parser = load_s_1(parser)
    parser = load_s_2(parser)
    args = parser.parse_load_command(['-p','7003','-vvvvv','rdep','-L','foo1','-S','new_var','zz','64'])
    print('port %d'%(args.port))
    print('verbose %d'%(args.verbose))
    print('subcommand %s'%(args.subcommand))
    print('rdep_list %s'%(args.rdep_list))
    print('rdep_string %s'%(args.rdep_string))
    print('subnargs %s'%(args.subnargs))
    return

if __name__ == '__main__':
  main()  

result

verbose 5
port 7003
subcommand rdep
rdep_list ['foo1']
rdep_string new_var
subnargs ['zz','64']

callback handle function example

import extargsparse
import os
commandline = '''
{
    "verbose|v" : "+",
    "port|p" : 3000,
    "dep<__main__.dep_handler>" : {
        "list|l" : [],
        "string|s" : "s_var",
        "$" : "+"
    }
}
'''

def dep_handler(args,context):
    print ('verbose = %d'%(args.verbose))
    print ('port = %s'%(args.port))
    print ('subcommand = %s'%(args.subcommand))
    print ('list = %s'%(args.dep_list))
    print ('string = %s'%(args.dep_string))
    print ('subnargs = %s'%(args.subnargs))
    print ('context["base"] = %s'%(context['base']))
    os.exit(0)
    return

def main():
    context = dict()
    context['base'] = 'basenum'
    options = ExtArgsOptions()
    options.usage = ' sample commandline parser '
    parser = extargsparse.ExtArgsParse(options)
    parser.load_command_line_string(commandline)
    args = parser.parse_command_line(['-vvvv','-p',5000,'dep','-l','arg1','-l','arg2','cc','dd'],context)

result is like this

verbose = 4
port = 5000
subcommand = dep
list = ['arg1','arg2']
string = 's_var'
subnargs = ['cc','dd']
context["base"] = basenum

with extension flag example

import extargsparse
import os
commandline = '''
{
    "verbose|v" : "+",
    "port|p+http" : 3000,
    "dep<__main__.dep_handler>" : {
        "list|l" : [],
        "string|s" : "s_var",
        "$" : "+"
    }
}
'''

def dep_handler(args):
    print ('verbose = %d'%(args.verbose))
    print ('port = %s'%(args.http_port))
    print ('subcommand = %s'%(args.subcommand))
    print ('list = %s'%(args.dep_list))
    print ('string = %s'%(args.dep_string))
    print ('subnargs = %s'%(args.subnargs))
    os.exit(0)
    return

def main():
    options = ExtArgsOptions()
    options.usage = ' sample commandline parser '
    parser = extargsparse.ExtArgsParse(options)
    parser.load_command_line_string(commandline)
    args = parser.parse_command_line(['-vvvv','-p',5000,'dep','-l','arg1','-l','arg2','cc','dd'])

result is like this

verbose = 4
port = 5000
subcommand = dep
list = ['arg1','arg2']
string = 's_var'
subnargs = ['cc','dd']

with extension flag bundle example

import extargsparse
import os
commandline = '''
{
    "verbose|v" : "+",
    "+http" : {
        "port|p" : 3000,
        "visual_mode|V" : false
    },
    "dep<__main__.dep_handler>" : {
        "list|l" : [],
        "string|s" : "s_var",
        "$" : "+"
    }
}
'''

def dep_handler(args):
    print ('verbose = %d'%(args.verbose))
    print ('port = %s'%(args.http_port))
    print ('visual_mode = %s'%(args.http_visual_mode))
    print ('subcommand = %s'%(args.subcommand))
    print ('list = %s'%(args.dep_list))
    print ('string = %s'%(args.dep_string))
    print ('subnargs = %s'%(args.subnargs))
    os.exit(0)
    return

def main():
    options = ExtArgsOptions()
    options.usage = ' sample commandline parser '
    parser = extargsparse.ExtArgsParse(options)
    parser.load_command_line_string(commandline)
    args = parser.parse_command_line(['-vvvv','-p','5000','--http-visual-mode','dep','-l','arg1','--dep-list','arg2','cc','dd'])

result is like this

verbose = 4
port = 5000
visual_mode = True
subcommand = dep
list = ['arg1','arg2']
string = 's_var'
subnargs = ['cc','dd']

with complex flag set

import extargsparse
import os
commandline = '''
{
    "verbose|v" : "+",
    "$port|p" : {
        "value" : 3000,
        "type" : "int",
        "nargs" : 1 , 
        "helpinfo" : "port to connect"
    },
    "dep<__main__.dep_handler>" : {
        "list|l" : [],
        "string|s" : "s_var",
        "$" : "+"
    }
}
'''

def dep_handler(args):
    print ('verbose = %d'%(args.verbose))
    print ('port = %s'%(args.port))
    print ('subcommand = %s'%(args.subcommand))
    print ('list = %s'%(args.list))
    print ('string = %s'%(args.string))
    print ('subnargs = %s'%(args.subnargs))
    os.exit(0)
    return

def main():
    options = ExtArgsOptions()
    options.usage = ' sample commandline parser '
    parser = extargsparse.ExtArgsParse(options)
    parser.load_command_line_string(commandline)
    args = parser.parse_command_line(['-vvvv','-p','5000','dep','-l','arg1','-l','arg2','cc','dd'])

result is like this

verbose = 4
port = 5000
subcommand = dep
list = ['arg1','arg2']
string = 's_var'
subnargs = ['cc','dd']

extension for help and long opt

#! /usr/bin/env python

import tempfile
import sys
import os
import extargsparse

def pair_parse(args,validx,keycls,params):
  if (validx + 1) >= len(params):
    raise Exception('need 2 args for [++pair|+p]')
  val = getattr(args,keycls.optdest,None)
  if val is None:
    val = []
  val.append(params[validx])
  val.append(params[(validx+1)])
  setattr(args,keycls.optdest,val)
  return 2

def pair_help(keycls):
  return '[first] [second]'

def single_2_jsonfunc(args,keycls,value):
    if not isinstance(value,list):
        raise Exception('not list value')
    if (len(value) % 2) != 0:
        raise Exception('not even sized')
    setvalue = []
    i = 0
    while i < len(value):
        setvalue.append(value[i])
        i += 2
    setattr(args,keycls.optdest,setvalue)
    return

def main():
  commandline='''
  {
    "verbose|v" : "+",
    "pair|p!optparse=pair_parse;opthelp=pair_help!" : [],
    "even|e!jsonfunc=single_2_jsonfunc!" : [],
    "clr_CA_name" : null,
    "$" : "*"
  }
  '''
  options = extargsparse.ExtArgsOptions()
  options.longprefix = '++'
  options.shortprefix = '+'
  options.jsonlong = 'jsonfile'
  options.helplong = 'usage'
  options.helpshort = '?'
  options.flagnochange = True
  parser = extargsparse.ExtArgsParse(options)
  parser.load_command_line_string(commandline)
  args = parser.parse_command_line()
  print('verbose [%d]'%(args.verbose))
  print('pair (%s)'%(args.pair))
  print('args (%s)'%(args.args))
  print('clr_CA_name (%s)'%(args.clr_CA_name))
  print('event (%s)'%(args.even))
  return

if __name__ == '__main__':
  main()
python3 opthelp.py +?

result will be

opthandle.py 0.0.1  [OPTIONS] [args...]

[OPTIONS]
    ++jsonfile     jsonfile     json input file to get the value set
    ++usage|+?                  to display this help information
    ++verbose|+v   verbose      verbose set default(0)
    ++even|+e      even         even set default([])
    ++clr_CA_name  clr_CA_name  clr_CA_name set default(None)
    ++pair|+p      pair         [first] [second]

cc.json file

{
"even": ["good", "bad"]
}
python opthandle.py ++jsonfile cc.json ++pair cc ss rr +vvvv

result will be

verbose [4]
pair (['cc', 'ss'])
args (['rr'])
clr_CA_name (None)
event (['good'])

extension attribute

extension get example

#! /usr/bin/env python

import sys
import os
_extargs_parent_dir = os.path.abspath(os.path.join(os.path.abspath(os.path.dirname(__file__)),'..','..'))
if _extargs_parent_dir not in sys.path:
    _temp_path = sys.path
    sys.path = [_extargs_parent_dir]
    sys.path.extend(_temp_path)

import extargsparse

def load_s_1(parser):
    load1 = '''
    {
      "verbose|v" : "+",
      "port|p" : 3000,
      "dep" : {
        "list|l" : [],
        "string|s" : "s_var",
        "$" : "+"
      }
    }
    '''
    parser.load_command_line_string(load1)
    return parser

def load_s_2(parser):
    load2 = '''
    {
      "rdep" : {
        "list|L" : [],
        "string|S" : "s_rdep",
        "$" : 2
      }
    }
    '''
    parser.load_command_line_string(load2)
    return parser

def debug_cmd_opts(parser,name=''):
    opts = parser.get_cmdopts(name)
    if opts is not None :
        for opt in opts:
            if opt.type == 'args':
                continue
            print('[%s] opt %s'%(name,opt.longopt))
    subcmds = parser.get_subcommands(name)
    if subcmds is not None:
        print('[%s] subcmds %s'%(name,subcmds))
    return subcmds

def debug_total(parser,name=''):
    subcmds = debug_cmd_opts(parser,name)
    if subcmds is not None and len(subcmds) > 0:
        for c in subcmds:
            cname = ''
            cname += '%s'%(name)
            if len(cname) > 0:
                cname += '.'
            cname += '%s'%(c)
            debug_total(parser,cname)
    return

def main():
    parser = extargsparse.ExtArgsParse()
    parser = load_s_1(parser)
    parser = load_s_2(parser)
    debug_total(parser)
    return

if __name__ == '__main__':
  main()  

result will be

[] opt --json
[] opt --help
[] opt --verbose
[] opt --port
[] subcmds ['dep', 'rdep']
[dep] opt --dep-json
[dep] opt --help
[dep] opt --dep-string
[dep] opt --dep-list
[dep] subcmds []
[rdep] opt --rdep-json
[rdep] opt --help
[rdep] opt --rdep-string
[rdep] opt --rdep-list
[rdep] subcmds []

no default help and no json to specify

if you want no help or json to in the options ,just use option with nohelpoption or nojsonoption

no cmd with prefix

if you want no command prefix to add in the command ,please use option with cmdprefixadded = False give example

flagnochange

if you set this true, it will not change the _ to - in the flag mode

#! /usr/bin/env python

import extargsparse

def main():
  commandline='''
  {
    "verbose|v" : "+",
    "dep" : {
      "list|l" : [],
      "string|s" : "s_dep",
      "$" : "*"
    },
    "rdep" : {
      "list|l" : [],
      "string|s" : "s_rdep",
      "$" : "+"
    }
  }
  '''
  optstr = '''
  {
    "nojsonoption" : true,
    "cmdprefixadded" : false
  }
  '''
  options = extargsparse.ExtArgsOptions(optstr)
  parser = extargsparse.ExtArgsParse(options)
  parser.load_command_line_string(commandline)
  args = parser.parse_command_line()
  print('verbose [%d]'%(args.verbose))
  print('subcommand [%s]'%(args.subcommand))
  print('list [%s]'%(args.list))
  print('string [%s]'%(args.string))
  print('subnargs [%s]'%(args.subnargs))
  return

if __name__ == '__main__':
  main()

give command

python noprefix.py rdep -h
noprefix.py  rdep [OPTIONS] args...
[OPTIONS]
    --help|-h            to display this help information
    --string|-s  string  string set default(s_rdep)
    --list|-l    list    list set default([])

give

python  noprefix.py  rdep --list cc --list bb 222
verbose [0]
subcommand [rdep]
list [['cc', 'bb']]
string [s_dep]
subnargs [['222']]

Rules

*** example

import extargsparse
import os
commandline = '''
{
    "verbose|v" : "+",
    "+http" : {
        "port|p" : 3000,
        "visual_mode|V" : false
    },
    "dep<__main__.dep_handler>" : {
        "list|l" : [],
        "string|s" : "s_var",
        "$" : "+"
    }
}
'''

def dep_handler(args):
    print ('verbose = %d'%(args.verbose))
    print ('port = %s'%(args.http_port))
    print ('visual_mode = %s'%(args.http_visual_mode))
    print ('subcommand = %s'%(args.subcommand))
    print ('list = %s'%(args.dep_list))
    print ('string = %s'%(args.dep_string))
    print ('subnargs = %s'%(args.subnargs))
    os.exit(0)
    return

def main():
    parser = extargsparse.ExtArgsParse(usage=' sample commandline parser ')
    parser.load_command_line_string(commandline)
    args = parser.parse_command_line(['-vvvv','-p','5000','--http-visual-mode','dep','--dep-json','dep.json','-l','arg1','--dep-list','arg2','cc','dd'])

result like this

verbose = 4
port = 5000
visual_mode = True
subcommand = dep
list = ['arg1','arg2']
string = 'jsonstring'
subnargs = ['cc','dd']

because we modify the value in the command line ,so the json file value is ignored

Most Complex Example

#!/usr/bin/python
import tempfile
import os
import sys
import extargsparse

def main():
  commandline= '''
  {
    "verbose|v" : "+",
    "rollback|R" : true,
    "+http" : {
      "url|u" : "http://www.google.com",
      "visual_mode|V": false
    },
    "$port|p" : {
      "value" : 3000,
      "type" : "int",
      "nargs" : 1 , 
      "helpinfo" : "port to connect"
    },
    "dep" : {
      "list|l" : [],
      "string|s" : "s_var",
      "$" : "+"
    }
  }
  '''
  jsonfile = None
  depjsonfile = None
  try:
    depstrval = 'newval'
    depliststr = '["depenv1","depenv2"]'
    deplistval = eval(depliststr)
    httpvmstr = "True"
    httpvmval = eval(httpvmstr)
    fd,jsonfile = tempfile.mkstemp(suffix='.json',prefix='parse',dir=None,text=True)
    os.close(fd)
    fd = -1
    fd ,depjsonfile = tempfile.mkstemp(suffix='.json',prefix='parse',dir=None,text=True)
    os.close(fd)
    fd = -1
    with open(jsonfile,'w+') as f:
      f.write('{ "http" : { "url" : "http://www.yahoo.com"} ,"dep":{"list" : ["jsonval1","jsonval2"],"string" : "jsonstring"},"port":6000,"verbose":3}\n')
    with open(depjsonfile,'w+') as f:
      f.write('{"list":["depjson1","depjson2"]}\n')
    delone = True
    while delone:
      delone = False
      for k in os.environ.keys():
        if k.startswith('EXTARGS_') or k.startswith('DEP_') or k == 'EXTARGSPARSE_JSON' or k.startswith('HTTP_'):
          del os.environ[k]
          delone = True
          break

    os.environ['EXTARGSPARSE_JSON'] = jsonfile
    os.environ['DEP_JSON'] = depjsonfile
    parser = extargsparse.ExtArgsParse(priority=[extargsparse.ENV_COMMAND_JSON_SET,extargsparse.ENVIRONMENT_SET,extargsparse.ENV_SUB_COMMAND_JSON_SET])
    parser.load_command_line_string(commandline)
    os.environ['DEP_STRING'] = depstrval
    os.environ['DEP_LIST'] = depliststr
    os.environ['HTTP_VISUAL_MODE']=httpvmstr

    args = parser.parse_command_line(['-p','9000','--no-rollback','dep','--dep-string','ee','ww'])
    print('args.verbose %d'%(args.verbose))
    print('args.port %d'%(args.port))
    print('args.dep_list %s'%(args.dep_list))
    print('args.dep_string %s'%(args.dep_string))
    print('args.http_visual_mode %s'%(args.http_visual_mode))
    print('args.http_url %s'%(args.http_url))
    print('args.subcommand %s'%(args.subcommand))
    print('args.subnargs %s'%(args.subnargs))
  finally:
    if depjsonfile is not None:
      os.remove(depjsonfile)
    depjsonfile = None
    if jsonfile is not None:
      os.remove(jsonfile)
    jsonfile = None
    if 'EXTARGSPARSE_JSON' in os.environ.keys():
      del os.environ['EXTARGSPARSE_JSON']
    if 'DEP_JSON' in os.environ.keys():
      del os.environ['DEP_JSON']
  return

if __name__ == '__main__':
  main()

result is

args.verbose 3
args.port 9000
args.rollback False
args.dep_list [u'jsonval1', u'jsonval2']
args.dep_string ee
args.http_visual_mode True
args.http_url http://www.yahoo.com
args.subcommand dep
args.subnargs ['ww']

extension mode see example seeextension get example

this is for use when other will use