Skip to main content

generate __main__.py with argparse setup generated from YAML

Project description

cligen

image image image

cligen is is a utility to generate command-line parsing code, writing your __main__.py from a specification in YAML. The generated code requires Python 3.8+.

For a commandline utility direction that needs the subcommands left and right, and where the subcommand left can have the option --u-turn (assuming you drive on the right side of the road), and both subcommands could have a --verbose option would look like:

!Cli 0:
- !Instance driving.Direction
- !Option [verbose, v, !Help increase verbosity level, !Action count]
- left:
  - !Help turning to the left
  - !Option [u-turn, U, !Type bool, !Help make a U-turn]
- right:
  - !H turning to the right

with the result that direction left -h will show:

usage: direction left [-h] [--u-turn] [--verbose]

optional arguments:
  -h, --help     show this help message and exit
  --u-turn, -U   make a U-turn
  --verbose, -v  increase verbosity level

When direction left is called from the command-line, the code in __main__.py will create an instance of the class Direction imported from driving.py, providing the result of the parsing as argument to the intialisation, and then call the method left_subcommand or method left (trying in that order) of that class. cligen can alternatively generate code that calls functions imported from a Python file, or call code inserted from the YAML specification in __main__.py itself (in this case the ..._subcommand is not tried, and the results of parsing passed in to the function).

The YAML document can either be in a file cli.yaml on its own, or, if you want to diminish file clutter in your project root, it can be stored in the variable _cligen_data in __init__.py, this means between the following two lines in that file:

_cligen_data = """\
"""

The YAML document uses various tags, many of which have a short version (e.g. !H is equivalent to using !Help).

Having the commandline options and argument data in a programmatically modifiable format like YAML, makes it more easy to check or manipulate all your utilities. E.g. if you want to make sure that all utilities that have a --verbose option also have a --quiet option that decreases the verbosity level.

Feature list

  • multiple long (--date) and short options (-D) can be associated with one target.

  • additional smart types/actions. E.g. an option with type 'date' defaults to datetime.date.today() and you can specify an argument like yesterday or -w-2 (two weeks ago)

  • default values, with optionally some of the defaults defaults updated from a configuration file (YAML/INI/PON)

  • nested parsers for subcommands, and subcommands inheriting options from their parent. This allows you to insert parent options before or after the subcommand, without the cligen code needing to re-arrange the commandline.

  • an optional default subcommand/parser, which is used if unknown options/arguments are found.

  • Optional shorthands in the form of alternative executable names for often used subcommand and/or options strings.

  • no dependencies on anything but the Python standard library, unless your config file is in a format that requires some installed library ( YAML -> ruamel.yaml )

  • allow YAML aliases for tagged scalars to be used by other tags:

    - !Help &xhelp text1 text2 text3  # this is the same as: "&xhelp !Help text1 text2 text3"
    - !Prolog [*xhelp]                # xhelp is a tagged scalar, "!Prolog *xhelp" would error
                                      # the value for !Prolog is automatically un-sequenced
    

Using !Config

In its most explicit form the tag !Config can takes a two element sequence as value. The first element indicates the type (pon, yaml, ini, TBI: json), the second the path to the file. A path starting with a tilde (~) will be expanded. A path not starting with tilde, or (forward-)slash (/), will be appended to your users config directory.

If !Config is followed by a scalar that looks like a path (i.e. the value starts with ~ or includes a /) the extension of the path is taken to be the type. In other cases !Config is assumed to be followed by a type and the basename is derived from the package name (_package_data['full_package_name']) in your users config directory.

A user config directory is based on XDG config locations (on Windows, the config information is expected under %APPDATA%)

When !Config is specified the inserted code will check for --config some_explicit_path on the commandline and load the config data from the path specified.

config file format

Config files are assumed to contain a dictionary at the root level (for formats like .ini the data is converted to a dictionary during loading). This dictionary contains keys that correspond to the various subparsers. A section global (or optionally glbl in PON to prevent use of a reserved keyword, renamed to global after loading), is used for defaults for options that come before the subparser as well as for global options. Each section consists of key-value pairs, where the key corresponds to a long option (--verbose) or if that is not available the short option (-v), either without the leading dashes.

Assuming you have the following configuration:

!Cli 0:
- !Opt [verbose, v, !H increase verbosity, !Action count]
- !Config [pon, /usr/local/etc/myutil.pon]
- subp1: []

your myutil.pon can use:

dict(glbl=dict(verbose=2))

to set the verbosity (you might want to format your PON somewhat nicer.

The same with a YAML file:

!Cli 0:
- !Opt [verbose, v, !H increase verbosity, !Action count]
- !Config YAML
- subp1: []

your ~/.config/your_util_name/your_util_name.yaml would be:

global:
  verbose: 2

argparse

An earlier version of cligen generated argparse commmands in the __main__.py file. The current python output doesn't use argparse anymore, resulting in code that is about twice as big, but also twice as fast.

The old, unmaintained, code generator can be invoked by providing --type argparse

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cligen-0.5.2.tar.gz (53.1 kB view details)

Uploaded Source

Built Distribution

cligen-0.5.2-py3-none-any.whl (44.6 kB view details)

Uploaded Python 3

File details

Details for the file cligen-0.5.2.tar.gz.

File metadata

  • Download URL: cligen-0.5.2.tar.gz
  • Upload date:
  • Size: 53.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.5

File hashes

Hashes for cligen-0.5.2.tar.gz
Algorithm Hash digest
SHA256 92c17338a5312f2c392e7611d91400c4c80ce8caf0dd48aeed20cdb9aa759687
MD5 59bc6a0d7e3dd0420ca9b20e4e9b49c2
BLAKE2b-256 897d3c45bc8df21801e929812c384e06fe7546d5691c1ec33356ea74e4de7032

See more details on using hashes here.

File details

Details for the file cligen-0.5.2-py3-none-any.whl.

File metadata

  • Download URL: cligen-0.5.2-py3-none-any.whl
  • Upload date:
  • Size: 44.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.5

File hashes

Hashes for cligen-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 8fbb1501b5e54654c65e83938d3ca85f08e6a8618a786a2b5e5218b6bab11223
MD5 9c6561c5135b6935b48c43d6c5ac0743
BLAKE2b-256 29084fe769cd64e2ab95052bb6f1041fb9164943aaad0ab3c9f3132a2dc9eb10

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page