cli-skel


Namecli-skel JSON
Version 0.3.1 PyPI version JSON
download
home_pageNone
SummaryGenerate CLI applications from python dictionaries.
upload_time2024-06-07 18:49:33
maintainerNone
docs_urlNone
authorNone
requires_python>=3.12
licenseMIT License Copyright (c) 2024, Michael Frank Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords cli argparse cmd repl
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # CLI Skeleton Library

Generate CLI application from python dictionaries.

A **cli-skeleton** is a python dictionary which describes the structure of a command line application.
This library may convert a cli-skeleton into either an `ArgumentParser` or a `Cmd` object.

If you write a lot of command line applications - this library can help reduce the time you spend 
writing boilerplate `argparse` and `cmd` code.


## Usage

```python
import cli_skel

print(cli_skel.__version__)
```


### Example 1: A Basic CLI Parser

```python
from cli_skel.argparse_skel import skel_to_argparse

skel = {
    'filenames': {
        'nargs': '+',
        'help': 'Filenames to do something with',
    },
    
    '--log-level': {
        'default': 'warning',
        'choices': {'debug', 'info', 'warning', 'error'},
    },
}

parser = skel_to_argparse(skel).getvalue()
ns = parser.parse_args(['file1', 'file2', 'file3', '--log-level=error'])
```

The dictionary `skel` describes the parameters of a cli application which takes positional parameters
`filenames`, and optional parameter `--log-level`. 

The keys of `skel` are parameter names and their values are dictionaries describing how the 
argument parser should handle them. Specifically, there must be at least one positional `filenames`,
as well as an optional parameter `--log-level` with a default value of `warning` and it may be one of 
four choices.

The code above is equivalent to the following pure-python implementation:
```python
import argparse

parser = argparse.ArgumentParser()

parser.add_argument(
    'filenames',
    nargs='+',
    help='Filenames to do something with',
)

parser.add_argument(
    '--log-level',
    default='warning',
    choices=['debug', 'info', 'warning', 'error'],
)

ns = parser.parse_args(['file1', 'file2', 'file3', '--log-level=error'])
```

Additionally, each cli-skeleton may be converted to a `cmd.Cmd` object.
When this object's `onecmd()` is run it will use the skeleton to navigate to the 
appropriate command to run. This notion is covered by later examples.


### Example 2: A More Advanced Use Case

```python
import argparse
from cli_skel.argparse_skel import skel_to_argparse

skel = {
    '--log-file': {
        'default': 'stdout',
        'help': 'output file for logs',
    },
    '--verbose': {
        'default': False,
        'type': bool,
        'action': argparse.BooleanOptionalAction,
    },
    '_': {
        'cmd1': {'->': lambda *_: print('cmd1 is running')},
        'cmd2': {'->': lambda *_: print('cmd2 is running')},
        'cmd3': {
            '--ignore-errors': {
                'type': bool,
                'default': False,
                'action': argparse.BooleanOptionalAction,
            },
            '->': lambda *_: print('cmd3 is running')
        },
    }
}

parser = skel_to_argparse(skel).getvalue()
ns = parser.parse_args(['cmd3', '--ignore-errors'])
ns.target_()
# 'cmd3 is running'
```

In this example `skel` is a cli-skeleton which has two optional parameters `--log-file` and `--verbose`,
and one positional parameter which may be one of `cmd1`, `cmd2` or `cmd3`. The `'_'` denotes a group of 
subparsers which are added when creating the `argparse.ArgumentParser`. Each one of `cmd1`, `cmd2` and `cmd3`
is itself a cli-skeleton. For example, `cmd3` defines the optional parameter `--ignore-errors`. 

The key `'->'` in the definitions of `cmd1`, `cmd2` and `cmd3` is the target key. If the respective command is 
selected, then the target value will be part of its payload. It may be used to dispatch commands. 
In the example above, the `cmd3` is selected. Therefore, the `argparse.Namespace` object which returns from 
`parser.parse_args()` has `target_` set to the value of `skel['_']['cmd3']['->']`.

The code above is equivalent to the following pure-python implementation:
```python
import argparse

parser = argparse.ArgumentParser()

parser.add_argument(
    '--log-file',
    default='stdout',
    help='output file for logs',
)

parser.add_argument(
    '--verbose',
    default=False,
    type=bool,
    action=argparse.BooleanOptionalAction,
)

subparsers = parser.add_subparsers(dest='toplevel_dest', required=True)

cmd1 = subparsers.add_parser('cmd1')
cmd1.set_defaults(target_=lambda *_: print('cmd1 is running'))

cmd2 = subparsers.add_parser('cmd2')
cmd2.set_defaults(target_=lambda *_: print('cmd2 is running'))

cmd3 = subparsers.add_parser('cmd3')
cmd3.add_argument(
    '--ignore-errors',
    type=bool,
    default=False,
    action=argparse.BooleanOptionalAction,
)
cmd3.set_defaults(target_=lambda *_: print('cmd3 is running'))

ns = parser.parse_args(['cmd3', '--ignore-errors'])
ns.target_()
```


### Example 3: cli-skeletons and `cmd.Cmd`  


Cli-skeletons may also be converted to `cmd.Cmd` objects.


```python
from cli_skel.cmd_skel import skel_to_cmd

skel = {
    '_': {
        'cmd1': {'->': lambda *_: print('cmd1 is running')},
        'cmd2': {'->': lambda *_: print('cmd2 is running')},
        'cmd3': {
            '--verbose': {'type': bool, 'default': False},
            '->': lambda *_: print('cmd3 is running') },
    }
}

cmd = skel_to_cmd(
    skel,
    intro='hello - welcome...',
    outro='sad to see you go',
    prompt='>> ',
    internal_cmd_prefix='/',
)
cmd.cmdloop()
```
```shell
hello - welcome...
>> cmd1
cmd1 is running
>> cmd3 --verbose
cmd3 is running
>> /exit
sad to see you go
```


## Installation

### Install Directly from PyPI
```shell
pip install cli-skel
```

### Install Latest from GitHub
```shell
pip install 'git+https://github.com/michael-123123/cli-skel.git'
```


## License

`cli-skel` was created and owned by Michael Frank.

`cli-skel` is licensed under the terms of the MIT license (see [LICENSE](LICENSE) file for details.)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "cli-skel",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": "Michael Frank <frankm@post.bgu.ac.il>",
    "keywords": "cli, argparse, cmd, repl",
    "author": null,
    "author_email": "Michael Frank <frankm@post.bgu.ac.il>",
    "download_url": "https://files.pythonhosted.org/packages/84/13/431354219a44def558d551391c472114a30cef11403f9e4ff518a213d54f/cli_skel-0.3.1.tar.gz",
    "platform": null,
    "description": "# CLI Skeleton Library\n\nGenerate CLI application from python dictionaries.\n\nA **cli-skeleton** is a python dictionary which describes the structure of a command line application.\nThis library may convert a cli-skeleton into either an `ArgumentParser` or a `Cmd` object.\n\nIf you write a lot of command line applications - this library can help reduce the time you spend \nwriting boilerplate `argparse` and `cmd` code.\n\n\n## Usage\n\n```python\nimport cli_skel\n\nprint(cli_skel.__version__)\n```\n\n\n### Example 1: A Basic CLI Parser\n\n```python\nfrom cli_skel.argparse_skel import skel_to_argparse\n\nskel = {\n    'filenames': {\n        'nargs': '+',\n        'help': 'Filenames to do something with',\n    },\n    \n    '--log-level': {\n        'default': 'warning',\n        'choices': {'debug', 'info', 'warning', 'error'},\n    },\n}\n\nparser = skel_to_argparse(skel).getvalue()\nns = parser.parse_args(['file1', 'file2', 'file3', '--log-level=error'])\n```\n\nThe dictionary `skel` describes the parameters of a cli application which takes positional parameters\n`filenames`, and optional parameter `--log-level`. \n\nThe keys of `skel` are parameter names and their values are dictionaries describing how the \nargument parser should handle them. Specifically, there must be at least one positional `filenames`,\nas well as an optional parameter `--log-level` with a default value of `warning` and it may be one of \nfour choices.\n\nThe code above is equivalent to the following pure-python implementation:\n```python\nimport argparse\n\nparser = argparse.ArgumentParser()\n\nparser.add_argument(\n    'filenames',\n    nargs='+',\n    help='Filenames to do something with',\n)\n\nparser.add_argument(\n    '--log-level',\n    default='warning',\n    choices=['debug', 'info', 'warning', 'error'],\n)\n\nns = parser.parse_args(['file1', 'file2', 'file3', '--log-level=error'])\n```\n\nAdditionally, each cli-skeleton may be converted to a `cmd.Cmd` object.\nWhen this object's `onecmd()` is run it will use the skeleton to navigate to the \nappropriate command to run. This notion is covered by later examples.\n\n\n### Example 2: A More Advanced Use Case\n\n```python\nimport argparse\nfrom cli_skel.argparse_skel import skel_to_argparse\n\nskel = {\n    '--log-file': {\n        'default': 'stdout',\n        'help': 'output file for logs',\n    },\n    '--verbose': {\n        'default': False,\n        'type': bool,\n        'action': argparse.BooleanOptionalAction,\n    },\n    '_': {\n        'cmd1': {'->': lambda *_: print('cmd1 is running')},\n        'cmd2': {'->': lambda *_: print('cmd2 is running')},\n        'cmd3': {\n            '--ignore-errors': {\n                'type': bool,\n                'default': False,\n                'action': argparse.BooleanOptionalAction,\n            },\n            '->': lambda *_: print('cmd3 is running')\n        },\n    }\n}\n\nparser = skel_to_argparse(skel).getvalue()\nns = parser.parse_args(['cmd3', '--ignore-errors'])\nns.target_()\n# 'cmd3 is running'\n```\n\nIn this example `skel` is a cli-skeleton which has two optional parameters `--log-file` and `--verbose`,\nand one positional parameter which may be one of `cmd1`, `cmd2` or `cmd3`. The `'_'` denotes a group of \nsubparsers which are added when creating the `argparse.ArgumentParser`. Each one of `cmd1`, `cmd2` and `cmd3`\nis itself a cli-skeleton. For example, `cmd3` defines the optional parameter `--ignore-errors`. \n\nThe key `'->'` in the definitions of `cmd1`, `cmd2` and `cmd3` is the target key. If the respective command is \nselected, then the target value will be part of its payload. It may be used to dispatch commands. \nIn the example above, the `cmd3` is selected. Therefore, the `argparse.Namespace` object which returns from \n`parser.parse_args()` has `target_` set to the value of `skel['_']['cmd3']['->']`.\n\nThe code above is equivalent to the following pure-python implementation:\n```python\nimport argparse\n\nparser = argparse.ArgumentParser()\n\nparser.add_argument(\n    '--log-file',\n    default='stdout',\n    help='output file for logs',\n)\n\nparser.add_argument(\n    '--verbose',\n    default=False,\n    type=bool,\n    action=argparse.BooleanOptionalAction,\n)\n\nsubparsers = parser.add_subparsers(dest='toplevel_dest', required=True)\n\ncmd1 = subparsers.add_parser('cmd1')\ncmd1.set_defaults(target_=lambda *_: print('cmd1 is running'))\n\ncmd2 = subparsers.add_parser('cmd2')\ncmd2.set_defaults(target_=lambda *_: print('cmd2 is running'))\n\ncmd3 = subparsers.add_parser('cmd3')\ncmd3.add_argument(\n    '--ignore-errors',\n    type=bool,\n    default=False,\n    action=argparse.BooleanOptionalAction,\n)\ncmd3.set_defaults(target_=lambda *_: print('cmd3 is running'))\n\nns = parser.parse_args(['cmd3', '--ignore-errors'])\nns.target_()\n```\n\n\n### Example 3: cli-skeletons and `cmd.Cmd`  \n\n\nCli-skeletons may also be converted to `cmd.Cmd` objects.\n\n\n```python\nfrom cli_skel.cmd_skel import skel_to_cmd\n\nskel = {\n    '_': {\n        'cmd1': {'->': lambda *_: print('cmd1 is running')},\n        'cmd2': {'->': lambda *_: print('cmd2 is running')},\n        'cmd3': {\n            '--verbose': {'type': bool, 'default': False},\n            '->': lambda *_: print('cmd3 is running') },\n    }\n}\n\ncmd = skel_to_cmd(\n    skel,\n    intro='hello - welcome...',\n    outro='sad to see you go',\n    prompt='>> ',\n    internal_cmd_prefix='/',\n)\ncmd.cmdloop()\n```\n```shell\nhello - welcome...\n>> cmd1\ncmd1 is running\n>> cmd3 --verbose\ncmd3 is running\n>> /exit\nsad to see you go\n```\n\n\n## Installation\n\n### Install Directly from PyPI\n```shell\npip install cli-skel\n```\n\n### Install Latest from GitHub\n```shell\npip install 'git+https://github.com/michael-123123/cli-skel.git'\n```\n\n\n## License\n\n`cli-skel` was created and owned by Michael Frank.\n\n`cli-skel` is licensed under the terms of the MIT license (see [LICENSE](LICENSE) file for details.)\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2024, Michael Frank  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  ",
    "summary": "Generate CLI applications from python dictionaries.",
    "version": "0.3.1",
    "project_urls": {
        "Homepage": "https://github.com/michael-123123/cli-skel",
        "Issues": "https://github.com/michael-123123/cli-skel/issues",
        "Repository": "https://github.com/michael-123123/cli-skel.git"
    },
    "split_keywords": [
        "cli",
        " argparse",
        " cmd",
        " repl"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "16fe6f911891462bb7284020e8d3042322c236859c4ace61fa07a91b2f46237d",
                "md5": "7561312e88cf59f824b196af8274983e",
                "sha256": "c6fa660e09b30ddcc91f20567a39d0b804d6fc98de9b463448753352e378cf97"
            },
            "downloads": -1,
            "filename": "cli_skel-0.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7561312e88cf59f824b196af8274983e",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 15687,
            "upload_time": "2024-06-07T18:49:31",
            "upload_time_iso_8601": "2024-06-07T18:49:31.469830Z",
            "url": "https://files.pythonhosted.org/packages/16/fe/6f911891462bb7284020e8d3042322c236859c4ace61fa07a91b2f46237d/cli_skel-0.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8413431354219a44def558d551391c472114a30cef11403f9e4ff518a213d54f",
                "md5": "0d1e5893d3591059e16a2d56b80449dc",
                "sha256": "734f2a1ff68df6dfad4d37b9dc263d94583be2a7b7425c5251ac7cf8be37eb69"
            },
            "downloads": -1,
            "filename": "cli_skel-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "0d1e5893d3591059e16a2d56b80449dc",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 26888,
            "upload_time": "2024-06-07T18:49:33",
            "upload_time_iso_8601": "2024-06-07T18:49:33.192544Z",
            "url": "https://files.pythonhosted.org/packages/84/13/431354219a44def558d551391c472114a30cef11403f9e4ff518a213d54f/cli_skel-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-06-07 18:49:33",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "michael-123123",
    "github_project": "cli-skel",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [],
    "lcname": "cli-skel"
}
        
Elapsed time: 0.27005s