parsearg


Nameparsearg JSON
Version 0.3.5 PyPI version JSON
download
home_pagehttps://github.com/tharte/parsearg
Summaryparsearg turns argparse on its head the declarative way
upload_time2021-06-21 18:08:37
maintainerThomas P. Harte
docs_urlNone
authorThomas P. Harte
requires_python>=3.6
licenseMIT
keywords cli subcommand parser argparse
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Quickstart

## Overview

`parsearg` is a Python package for writing command-line interfaces ("CLI")
that augments (rather than replaces) the standard Python module for writing
CLIs, `argparse`. There is nothing wrong with `argparse`: It's fine in terms of
the *functionality* that it provides, but it can be clunky to use, especially
when a program's structure has subcommands, or nested subcommands (*i.e.*
subcommands that have subcommands).  Moreover, because of the imperative
nature of `argparse`, it makes it hard to understand how a program's interface
is structured (*viz.* the program's "view").

`parsearg` puts a layer on top of `argparse` that makes writing a CLI easy: You
declare your view (*i.e.* the CLI), with a `dict` so that the view
is a data structure (*i.e.* pure configuration). The data structure declares
the *intent* of the CLI and you no longer have to instruct `argparse`
on how to put the CLI together: `parsearg` does that for you.
In this respect, `parsearg` turns `argparse` on its head, in the sense that
it replaces imperative instructions with declarative data.

## Usage

Suppose we wish to create a program called `quickstart-todos.py` to manage the TO-DOs
of a set of different users. We want to have subprograms of `quickstart-todos.py`; for
example, we may want to create a user (`python quickstart-todos.py create user`, say),
or we may want to create a TO-DO for a particular user (`python quickstart-todos.py
create todo`, say).  We might also want to add optional parameters to each
subprogram such as the user's email and phone number, or the TO-DO's 
due date. An invocation of the program's CLI might look like
the following:
```bash
$ python quickstart-todos.py create user Bob --email=bob@email.com --phone=+1-212-555-1234
$ python quickstart-todos.py create todo Bob 'taxes' --due-date=2021-05-17
```
With `argparse`, the subprogram `create` would necessitate fiddling
with subparsers.  With `parsearg`, the CLI for the above is declared
with a `dict` and `parsearg.parser.ParseArg` supplants the normal use of
`argparse.ArgumentParser`. Moreover, the callback associated with
each subcommand is explicitly linked to its declaration.

```python
import sys
from parsearg import ParseArg

def create_user(args):
    print(f'created user: {args.name!r} (email: {args.email}, phone: {args.phone})')
    
def create_todo(args):
    print(f'created TO-DO for user {args.user!r}: {args.title} (due: {args.due_date})')
    
view = {
    'create|user': {
        'callback':   create_user,
        'name':       {'help': 'create user name', 'action': 'store'},
        '-e|--email': {'help': "create user's email address", 'action': 'store', 'default': ''},
        '-p|--phone': {'help': "create user's phone number", 'action': 'store', 'default': ''},
    },
    'create|todo': {
        'callback':   create_todo,
        'user':       {'help': 'user name', 'action': 'store'},
        'title':      {'help': 'title of TO-DO', 'action': 'store'},
        '-d|--due-date': {'help': 'due date for the TO-DO', 'action': 'store', 'default': None},
    },
}

def main(args):
    # ParseArg takes the place of argparse.ArgumentParser
    parser = ParseArg(d=view)

    # parser.parse_args returns an argparse.Namespace
    ns     = parser.parse_args(args)

    # ns.callback contains the function in the 'callback' key of 'view'
    result = ns.callback(ns)

if __name__ == "__main__":
    args = sys.argv[1:] if len(sys.argv) > 1 else []
    
    main(' '.join(args))
```

A fully-worked version of this TO-DO example is presented in the docs. The output
of the above is:
```
$ python quickstart-todos.py create user Bob --email=bob@email.com --phone=212-555-1234
created user: 'Bob' (email: bob@email.com, phone: 212-555-1234)

$ python quickstart-todos.py create todo Bob 'taxes' --due-date=2021-05-17
created TO-DO for user 'Bob': taxes (due: 2021-05-17)
```

Because `parsearg` is built on top of `argparse`, all the usual features
are available, such as the extensive help features (essentially
making the CLI self-documenting):
```
$ python quickstart-todos.py --help
usage: quickstart-todos.py [-h] {create} ...

positional arguments:
  {create}

optional arguments:
  -h, --help  show this help message and exit

$ python quickstart-todos.py create --help
usage: quickstart-todos.py create [-h] {todo,user} ...

positional arguments:
  {todo,user}

optional arguments:
  -h, --help   show this help message and exit

$ python quickstart-todos.py create user --help
usage: quickstart-todos.py create user [-h] [-e EMAIL] [-p PHONE] name

positional arguments:
  name                  create user name

optional arguments:
  -h, --help            show this help message and exit
  -e EMAIL, --email EMAIL
                        create user's email address
  -p PHONE, --phone PHONE
                        create user's phone number
$ python quickstart-todos.py create todo --help
usage: quickstart-todos.py create todo [-h] [-d DUE_DATE] user title

positional arguments:
  user                  user name
  title                 title of to-do

optional arguments:
  -h, --help            show this help message and exit
  -d DUE_DATE, --due-date DUE_DATE
                        due date for the to-do
```


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/tharte/parsearg",
    "name": "parsearg",
    "maintainer": "Thomas P. Harte",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "tharte@cantab.net",
    "keywords": "CLI,subcommand,parser,argparse",
    "author": "Thomas P. Harte",
    "author_email": "tharte@cantab.net",
    "download_url": "https://files.pythonhosted.org/packages/b9/25/d742c8d07d7f9c62b552e5d374c51eb5d861bf825104ae7a75c6f9fb0114/parsearg-0.3.5.tar.gz",
    "platform": "",
    "description": "# Quickstart\n\n## Overview\n\n`parsearg` is a Python package for writing command-line interfaces (\"CLI\")\nthat augments (rather than replaces) the standard Python module for writing\nCLIs, `argparse`. There is nothing wrong with `argparse`: It's fine in terms of\nthe *functionality* that it provides, but it can be clunky to use, especially\nwhen a program's structure has subcommands, or nested subcommands (*i.e.*\nsubcommands that have subcommands).  Moreover, because of the imperative\nnature of `argparse`, it makes it hard to understand how a program's interface\nis structured (*viz.* the program's \"view\").\n\n`parsearg` puts a layer on top of `argparse` that makes writing a CLI easy: You\ndeclare your view (*i.e.* the CLI), with a `dict` so that the view\nis a data structure (*i.e.* pure configuration). The data structure declares\nthe *intent* of the CLI and you no longer have to instruct `argparse`\non how to put the CLI together: `parsearg` does that for you.\nIn this respect, `parsearg` turns `argparse` on its head, in the sense that\nit replaces imperative instructions with declarative data.\n\n## Usage\n\nSuppose we wish to create a program called `quickstart-todos.py` to manage the TO-DOs\nof a set of different users. We want to have subprograms of `quickstart-todos.py`; for\nexample, we may want to create a user (`python quickstart-todos.py create user`, say),\nor we may want to create a TO-DO for a particular user (`python quickstart-todos.py\ncreate todo`, say).  We might also want to add optional parameters to each\nsubprogram such as the user's email and phone number, or the TO-DO's \ndue date. An invocation of the program's CLI might look like\nthe following:\n```bash\n$ python quickstart-todos.py create user Bob --email=bob@email.com --phone=+1-212-555-1234\n$ python quickstart-todos.py create todo Bob 'taxes' --due-date=2021-05-17\n```\nWith `argparse`, the subprogram `create` would necessitate fiddling\nwith subparsers.  With `parsearg`, the CLI for the above is declared\nwith a `dict` and `parsearg.parser.ParseArg` supplants the normal use of\n`argparse.ArgumentParser`. Moreover, the callback associated with\neach subcommand is explicitly linked to its declaration.\n\n```python\nimport sys\nfrom parsearg import ParseArg\n\ndef create_user(args):\n    print(f'created user: {args.name!r} (email: {args.email}, phone: {args.phone})')\n    \ndef create_todo(args):\n    print(f'created TO-DO for user {args.user!r}: {args.title} (due: {args.due_date})')\n    \nview = {\n    'create|user': {\n        'callback':   create_user,\n        'name':       {'help': 'create user name', 'action': 'store'},\n        '-e|--email': {'help': \"create user's email address\", 'action': 'store', 'default': ''},\n        '-p|--phone': {'help': \"create user's phone number\", 'action': 'store', 'default': ''},\n    },\n    'create|todo': {\n        'callback':   create_todo,\n        'user':       {'help': 'user name', 'action': 'store'},\n        'title':      {'help': 'title of TO-DO', 'action': 'store'},\n        '-d|--due-date': {'help': 'due date for the TO-DO', 'action': 'store', 'default': None},\n    },\n}\n\ndef main(args):\n    # ParseArg takes the place of argparse.ArgumentParser\n    parser = ParseArg(d=view)\n\n    # parser.parse_args returns an argparse.Namespace\n    ns     = parser.parse_args(args)\n\n    # ns.callback contains the function in the 'callback' key of 'view'\n    result = ns.callback(ns)\n\nif __name__ == \"__main__\":\n    args = sys.argv[1:] if len(sys.argv) > 1 else []\n    \n    main(' '.join(args))\n```\n\nA fully-worked version of this TO-DO example is presented in the docs. The output\nof the above is:\n```\n$ python quickstart-todos.py create user Bob --email=bob@email.com --phone=212-555-1234\ncreated user: 'Bob' (email: bob@email.com, phone: 212-555-1234)\n\n$ python quickstart-todos.py create todo Bob 'taxes' --due-date=2021-05-17\ncreated TO-DO for user 'Bob': taxes (due: 2021-05-17)\n```\n\nBecause `parsearg` is built on top of `argparse`, all the usual features\nare available, such as the extensive help features (essentially\nmaking the CLI self-documenting):\n```\n$ python quickstart-todos.py --help\nusage: quickstart-todos.py [-h] {create} ...\n\npositional arguments:\n  {create}\n\noptional arguments:\n  -h, --help  show this help message and exit\n\n$ python quickstart-todos.py create --help\nusage: quickstart-todos.py create [-h] {todo,user} ...\n\npositional arguments:\n  {todo,user}\n\noptional arguments:\n  -h, --help   show this help message and exit\n\n$ python quickstart-todos.py create user --help\nusage: quickstart-todos.py create user [-h] [-e EMAIL] [-p PHONE] name\n\npositional arguments:\n  name                  create user name\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -e EMAIL, --email EMAIL\n                        create user's email address\n  -p PHONE, --phone PHONE\n                        create user's phone number\n$ python quickstart-todos.py create todo --help\nusage: quickstart-todos.py create todo [-h] [-d DUE_DATE] user title\n\npositional arguments:\n  user                  user name\n  title                 title of to-do\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -d DUE_DATE, --due-date DUE_DATE\n                        due date for the to-do\n```\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "parsearg turns argparse on its head the declarative way",
    "version": "0.3.5",
    "split_keywords": [
        "cli",
        "subcommand",
        "parser",
        "argparse"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "f9d7529891db9efc502494a0b4c5427a",
                "sha256": "026f4998851707a186ad43530f960a85e765ae2cb506e679c167467b6d66a438"
            },
            "downloads": -1,
            "filename": "parsearg-0.3.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f9d7529891db9efc502494a0b4c5427a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 9432,
            "upload_time": "2021-06-21T18:08:36",
            "upload_time_iso_8601": "2021-06-21T18:08:36.170264Z",
            "url": "https://files.pythonhosted.org/packages/4f/5e/0784110b40ebb482900e1f3c0fa3a20532e7da551f20cc04043a0f9397b6/parsearg-0.3.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "88685402c69cc911e611af446b603d46",
                "sha256": "fb912b7d91a23daa377a9e9982f4f9db58e53af426c6e1efed953578c115ca32"
            },
            "downloads": -1,
            "filename": "parsearg-0.3.5.tar.gz",
            "has_sig": false,
            "md5_digest": "88685402c69cc911e611af446b603d46",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 233189,
            "upload_time": "2021-06-21T18:08:37",
            "upload_time_iso_8601": "2021-06-21T18:08:37.912919Z",
            "url": "https://files.pythonhosted.org/packages/b9/25/d742c8d07d7f9c62b552e5d374c51eb5d861bf825104ae7a75c6f9fb0114/parsearg-0.3.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2021-06-21 18:08:37",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "tharte",
    "github_project": "parsearg",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "parsearg",
    "flake8_score": {
        "E221": 8,
        "E302": 14,
        "E501": 8,
        "E231": 2,
        "E305": 2,
        "E225": 3,
        "E251": 2,
        "E303": 1,
        "E714": 1,
        "E262": 1,
        "E306": 1,
        "E201": 1,
        "E202": 1,
        "F841": 3,
        "F401": 5,
        "F821": 1,
        "W291": 6,
        "W293": 5,
        "W391": 2
    }
}
        
Elapsed time: 0.28027s