Package: declarative-parser
Modern, declarative argument parser for Python 3.6+. Powerful like
click, integrated like argparse, declarative as sqlalchemy. MIT
licenced.Documented on
RTD. Install
with:python3-mpipinstalldeclarative_parserAs simple as argparseIt’s built on top of argparse - everything you already know stays valid!fromdeclarative_parserimportParser,ArgumentclassMyParser(Parser):square=Argument(help='display a square of a given number')parser=MyParser()args=parser.parse_args()print(args.square**2)Nested and ParallelEveryone knows about nested args. What about parallel groups?supported_formats=['png','jpeg','gif']classInputOptions(Parser):path=Argument(type=argparse.FileType('rb'),optional=False)format=Argument(default='png',choices=supported_formats)classOutputOptions(Parser):format=Argument(default='jpeg',choices=supported_formats)scale=Argument(type=int,default=100,help='Rescale image to%%of original size')classImageConverter(Parser):description='This app converts images'verbose=Argument(action='store_true')input=InputOptions()output=OutputOptions()parser=ImageConverter()commands='--verbose input image.png output --format gif --scale 50'.split()namespace=parser.parse_args(commands)assertnamespace.input.format=='png'assertnamespace.output.format=='gif'IntelligentMake use of Python 3 type hints to reduce tedious task of parsers
writing to two or three lines. Positional, keyword arguments, type
hints, docstrings - everything can be meaningfully transformed into a
parser. And if you decide to take control, just overwrite the
automatically deduced arguments with anArgument()defined as a
class variable.importargparsefromdeclarative_parserimportArgumentfromdeclarative_parser.constructor_parserimportConstructorParserclassMyProgram:database=Argument(type=argparse.FileType('r'),help='Path to file with the database')def__init__(self,text:str,threshold:float=0.05,database=None):"""My program does XYZ.

        Arguments:
          threshold: a floating-point value defining threshold, default 0.05
          database: file object to the database if any
        """print(text,threshold,None)parser=ConstructorParser(MyProgram)options=parser.parse_args()program=parser.constructor(**vars(options))And it works quite intuitively:$./my_program.pytest--threshold0.6test0.6None$./my_program.pytest--thresholdfusage:my_program.py[-h][--databaseDATABASE][--thresholdTHRESHOLD]text{}...my_program.py:error:argument--threshold:invalidfloatvalue:'f'$./my_program.py--threshold0.6usage:my_program.py[-h][--databaseDATABASE][--thresholdTHRESHOLD]text{}...my_program.py:error:thefollowingargumentsarerequired:textThree docstring formats are supported: Google, NumPy and
reStructuredText, with the default being Google.PS. It works with functions too; see the documentation ofFunctionParser.PracticalWhat if you only want to show licence of your program? or version? Is
there a need to write a separate logic? DeclarativeParser gives you
utility decorator:@actionwhich utilizes the power ofargparse.Action, leaving behind the otherwise necessary boilerplate
code.__version__=2.0importargparsefromdeclarative_parserimportactionfromdeclarative_parser.constructor_parserimportConstructorParserclassMyProgram:def__init__(self,threshold:float=0.05):"""My program does XYZ.

        Arguments:
          threshold: a floating-point value, default 0.05
        """pass@actiondefversion(options):print(__version__)parser=ConstructorParser(MyProgram)options=parser.parse_args()program=parser.constructor(**vars(options))The execution of an action will (by default) cause the program to exit
immediately when finished.See following run as example:$./my_program.py--version2.0See more examples inthe
documentation.