Package: jk_argparsing
jk_argparsingIntroductionThis module provides an API for processing command line arguments. There isargparseof course, but this API is better. Better means: Simpler, more easy to use.Information about this module can be found here:github.orgpypi.python.orgHistoryNot every piece of software has a history. This module has.Work on this module began over a decade ago in a complete different programming language: C#. As I required some command line tools in C# I implemented a .Net library for that purpose as there was nothing like that I could use. This library was so convenient that a) I prepared it for release under the Apache Open Source license and b) ported it to Python some years later.So this python module here is based on that .Net library. It is basically a port of that library. However, year after year I improved that Python module bit by bit, so this Python module became a very convenient tool, way beyond the original capabilities of that .Net library.The next sections provide detailed information about how to usejk_argparsing.How to use this moduleImportTo import this module use the following statement:importjk_argparsingConceptFirst some short information about terminology used by this module:Anoptionis something like-hor-lor--help. (e.g.:ls -la)Acommandis something likeupdateorinstallor whatever. (e.g.:apt update)NOTE: Command line parsing will follow these conceps (and only these concepts) listed above.Usingjk_argparsingis very simple:You first instantiate an object ofArgsParser.Then you define defaults in a data dictionary for your options.Then you configure this object by invoking methods on this object. By doing this you define ...the author(s) of your programthe license your program will be usingoptions, your program might require (together with expectations for arguments to provide)commands, your program might provide (together with expectations for arguments to provide)exit codes, your program might usevarious other information useful for a userAfter configuration is complete, you invokeparse()to initiate parsing of the command line specified by the user. In doing so ...program options are parsed and entries in your data dictionary will be modified in the process.An object of typeParsedArgswill now be returned.You can now use this returnes object to process the commands provided on the command line.ExampleFirst, let's create an instance ofArgsParser:ap=ArgsParser(appName="myapp",shortAppDescription="My short description")Then let's configure this object. The following is just an example of what you might want to do:ap.createSynopsis("myapp -x foo")ap.createSynopsis("myapp -y bar")ap.optionDataDefaults.set("help",False)ap.createOption(None,"enabled","Something is enabled.").expectString("OPT1",minLength=2).onOption=\lambdaargOption,argOptionArguments,parsedArgs:\parsedArgs.optionData.set("my",argOptionArguments[0])ap.createOption("h","help","Display this help text.").onOption=\lambdaargOption,argOptionArguments,parsedArgs:\parsedArgs.optionData.set("help",True)ap.createOption("n","nothing",LOREM_IPSUM)ap.createAuthor("Jürgen Knauth","jk@binary-overflow.de")ap.setLicense("apache",YEAR=2017,COPYRIGHTHOLDER="Jürgen Knauth")ap.createReturnCode(0,"Everything is okay.")ap.createReturnCode(1,"An I/O error occurred.")ap.createReturnCode(-1,"Invalid configuration.")ap.createCommand("foo","Lorem ipsum dolor sid amet.")ap.createCommand("bar","The quick brown fox jumps over the lazy dog.")Now if you would generate a help text by invokingap.showHelp()you would get this result:myapp - My short description

SYNOPSIS

    myapp -x foo
    myapp -y bar

OPTIONS

        --enabled OPT1  Something is enabled.
    -h  --help          Display this help text.
    -n  --nothing       Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse congue, orci vel interdum bibendum, nisi mauris
                        porttitor tortor, non tincidunt neque quam eget est. Vivamus sollicitudin urna ut elit lobortis, eget pretium est
                        sollicitudin. Vivamus venenatis ut erat quis gravida. Praesent vel purus finibus velit pretium eleifend.

COMMANDS

    bar  The quick brown fox jumps over the lazy dog.
    foo  Lorem ipsum dolor sid amet.

PROGRAM EXIT CODES

    0   Everything is okay.
    1   An I/O error occurred.
    -1  Invalid configuration.

AUTHORS

    Jürgen Knauth <jk@binary-overflow.de>

LICENSE

    This program is free software: you can redistribute it and/or modify it under the terms of the Apache Software License as published by
    Apache Software Foundation in version 2. For more details see the Apache Software License, which should be vailable at:
    https://www.apache.org/licenses/LICENSE-2.0Adding a descriptionYou might want to add a description. For better readability this description could have chapters:ap.addDescriptionChapter("Introduction","Lorem ipsum dolor sid amet ...")ap.addDescriptionChapter("Usage","Lorem ipsum dolor sid amet ...")ap.addDescriptionChapter("Whatever","Lorem ipsum dolor sid amet ...")A description is placedafterthe synopsis andbeforethe options.Additional methods are provided to insert text at some other position in the help textjk_argparsingwill create for yoou:addExtraChapterHead(..)addExtraChapterMiddle(..)addExtraChapterEnd(..)The full help text created will then have the following structure:PositionDescriptionA titleIn this example here: "myapp - My short description"SynposisMultiple lines defined bycreateSynopsis(..)A head text sectionDefined byaddExtraChapterHead(..)The standard descriptionDefined byaddDescriptionChapter(..)A middle text sectionDefined byaddExtraChapterMiddle(..)OptionsA formatted table with all options provided bycreateOption(..)CommandsA formatted table with all commands provided bycreateCommand(..)Program exit codesA formatted table with all exit codes provided bycreateReturnCode(..)A final text sectionDefined byaddExtraChapterEnd(..)AuthorsA list of all authors defined bycreateAuthor(..)LicenseA short license information defined bysetLicense(..)Program optionsFor your program to support options your first step should be to provide default value(s) that can get modified later during parsing. Here we usehelpfor demonstration purposes:ap.optionDataDefaults.set("help",False)Then define the option so that the parser later will be able to process it:ap.createOption("h","help","Display this help text.").onOption=\lambdaargOption,argOptionArguments,parsedArgs:\parsedArgs.optionData.set("help",True)In this particular case the option will have no argument.
However, the option will have a lambda function that can be assigned toonOption. This lambda function will be executed if the parser encounteres this option.The lambda function will receive three arguments:argOption- The option that is currently being parsed. (You typically have no use for this parameter as by attaching a lambda function you already know the option that is going to be parsed.)argOptionArguments- A list of arguments the option might have. (This list is empty in our case as--helpdoes not have any additional arguments.)parsedArgs- TheParsedArgsobject the parser is creating by parsing the command line onap.parse(). (ThisParsedArgsobject will be returned later to the caller ofap.parse().)Within this lambda functions you should accessparsedArgs.optionData. This is a dictionary you can modify. For simplicity invokeset(..)to modify a values.
In this example here the original value forhelpwill be overwritten.Program commandsFor your program to support commands you just define your command. Example:ap.createCommand("update","Perform some kind of update.")Of course you could have a command with an argument:ap.createCommand("process-file","Load a settings file.")\.expectFile("<settingsFile>",minLength=1,mustExist=True,toAbsolutePath=True)Now if the user runs your program with arguments such as these ...yourprogram process-file some/path/to/a/file... the parsing engine will check that a file path followsprocess-filethat refers to an existing file. In addition this argument will converted to an absolute path automatically during parsing.Processing such kind of program arguments in your program is simple. Here is an example:# parse the command line using our predefined object `ArgsParser` in `ap`# NOTE: all options get processed automatically during this parsing stepparsedArgs=ap.parse()ifparsedArgs.optionData["help"]:# `help` is true, so let's exit hereap.showHelp()sys.exit(1)ifnotparsedArgs.programArgs:# no program arguments specified, so let's exit hereap.showHelp()sys.exit(1)forcmdName,cmdArgsinparsedArgs.parseCommands():ifcmdName=='update':# do somethig...elifcmdName=='process-file':# do somethig...else:# fallback if - by accident - we have an error in our implementation hereraiseException("Implementation error!")Expectations for options and commandsOptions and commands can have "expections". An expectation is an argument a user must append to the option. Example:yourprogram --output-file some/path/to/a/file do-somethingOr:yourprogram process-file some/path/to/a/fileHere ...--output-filewould be an option that expects one argument,do-somethingwould be a command that has no arguments andprocess-filewould be a command that expects one argument.Here is how you could define such a command:ap.createCommand("process-file","Load a settings file.")\.expectFile("<settingsFile>",minLength=1,mustExist=True,toAbsolutePath=True)The following expectations for arguments to options and commands are available:Method to invokeDescriptionexpectFileOrDirectory(..)Provided argument must be a file or directoryexpectFile(..)Provided argument must be a fileexpectDirectory(..)Provided argument must be a directoryexpectString(..)Provided argument must be a text stringexpectInt32(..)Provided argument must be an integer numberNOTE: By definitionexpectString(..),expectFileOrDirectory(..),expectFile(..)andexpectDirectory(..)are quite similar: They all specify that a string is expected. However, each method will support constraints. WhileexpectString(..)only supports standard string constraints, the other methods will assume that the specified string denotes a file or directory.Author(s)Jürgen Knauth:pubsrc@binary-overflow.deLicenseThis software is provided under the following license:Apache Software License 2.0