Skip to main content

Modern, declarative argument parser for Python 3.6+

Project description

Build Status Code Climate Coverage Status Documentation Status

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 -m pip install declarative_parser

As simple as argparse

It’s built on top of argparse - everything you already know stays valid!

from declarative_parser import Parser, Argument

class MyParser(Parser):
    square = Argument(help='display a square of a given number')

parser = MyParser()
args = parser.parse_args()
print(args.square**2)

Nested and Parallel

Everyone knows about nested args. What about parallel groups?

supported_formats = ['png', 'jpeg', 'gif']

class InputOptions(Parser):
    path = Argument(type=argparse.FileType('rb'), optional=False)
    format = Argument(default='png', choices=supported_formats)

class OutputOptions(Parser):
    format = Argument(default='jpeg', choices=supported_formats)
    scale = Argument(type=int, default=100, help='Rescale image to %% of original size')

class ImageConverter(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)

assert namespace.input.format == 'png'
assert namespace.output.format == 'gif'

Intelligent

Make 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 an Argument() defined as a class variable.

import argparse
from declarative_parser import Argument
from declarative_parser.constructor_parser import ConstructorParser

class MyProgram:

    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.py test --threshold 0.6
test 0.6 None
$ ./my_program.py test --threshold f
usage: my_program.py [-h] [--database DATABASE] [--threshold THRESHOLD] text {} ...
my_program.py: error: argument --threshold: invalid float value: 'f'
$ ./my_program.py --threshold 0.6
usage: my_program.py [-h] [--database DATABASE] [--threshold THRESHOLD] text {} ...
my_program.py: error: the following arguments are required: text

Three docstring formats are supported: Google, NumPy and reStructuredText, with the default being Google.

PS. It works with functions too; see the documentation of FunctionParser.

Practical

What 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: @action which utilizes the power of argparse.Action, leaving behind the otherwise necessary boilerplate code.

__version__ = 2.0

import argparse
from declarative_parser import action
from declarative_parser.constructor_parser import ConstructorParser

class MyProgram:

    def __init__(self, threshold: float=0.05):
        """My program does XYZ.

        Arguments:
          threshold: a floating-point value, default 0.05
        """
        pass

    @action
    def version(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 --version
2.0

See more examples in the documentation.

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

declarative_parser-0.1.3.tar.gz (12.3 kB view details)

Uploaded Source

File details

Details for the file declarative_parser-0.1.3.tar.gz.

File metadata

File hashes

Hashes for declarative_parser-0.1.3.tar.gz
Algorithm Hash digest
SHA256 3f8fb8b53c7d13243490e5e96095f0b358920895406c70e2cc92af36ac2d6433
MD5 911e0a6e09bf3e9d6512721b4ca89dc5
BLAKE2b-256 bfc063e53bc5fb74a367759052ba6b13622acc345f193eb59a1756f0b96cf512

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