arguably


Namearguably JSON
Version 1.2.5 PyPI version JSON
download
home_pagehttps://treykeown.github.io/arguably/
SummaryThe best Python CLI library, arguably.
upload_time2023-06-29 11:10:18
maintainer
docs_urlNone
authortreykeown
requires_python>=3.8,<4.0
license
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <p align="center">
      <img alt="arguably logo" src="https://raw.githubusercontent.com/treykeown/arguably/main/etc/logo/arguably_black.png">
</p>

<p align="center">
    <em>
        The best Python CLI library, arguably.
    </em>
</p>

<p align="center">
    <a href="https://github.com/treykeown/arguably/actions/workflows/python-package.yml"><img src="https://github.com/treykeown/arguably/actions/workflows/python-package.yml/badge.svg" alt="Test status"></a>
    <a href="https://treykeown.github.io/arguably/coverage/"><img src="https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/treykeown/f493b14288af4e8358ea8578c393213a/raw/arguably-coverage-badge.json" alt="Code coverage"></a>
    <a href="https://pypi.org/project/arguably/"><img src="https://shields.io/pypi/pyversions/arguably" alt="Supported Python versions"></a>
    <a href="https://pypi.org/project/arguably/"><img src="https://shields.io/pypi/v/arguably" alt="PyPI version"></a>
</p>
<hr>

`arguably` turns functions and docstrings into command line interfaces (CLIs). `arguably` has a tiny API and is
extremely easy to integrate. You can also use it directly through `python3 -m arguably your_script.py`, more on that
[here](#no-integration-required).

To use `arguably` in a script, decorate any functions that should appear on the command line with `@arguably.command`,
then call `arguably.run()`. If multiple functions are decorated, they'll all appear as subcommands. You can even have
*multiple levels* of subcommands: `def s3__ls()` becomes `s3 ls`.

<div align="right"><sub>
    <a href="https://github.com/treykeown/arguably/blob/main/etc/scripts/intro.py">[source]</a>
</sub></div>

```python
#!/usr/bin/env python3
import arguably

@arguably.command
def some_function(required, not_required=2, *others: int, option: float = 3.14):
    """
    this function is on the command line!

    Args:
        required: a required argument
        not_required: this one isn't required, since it has a default value
        *others: all the other positional arguments go here
        option: [-x] keyword-only args are options, short name is in brackets
    """
    print(f"{required=}, {not_required=}, {others=}, {option=}")

if __name__ == "__main__":
    arguably.run()
```

<p align="center"><b><em>becomes</em></b></p>

```console
user@machine:~$ ./intro.py -h
usage: intro.py [-h] [-x OPTION] required [not-required] [others ...]

this function is on the command line!

positional arguments:
  required             a required argument (type: str)
  not-required         this one isn't required, since it has a default value (type: int, default: 2)
  others               all the other positional arguments go here (type: int)

options:
  -h, --help           show this help message and exit
  -x, --option OPTION  keyword-only args are options, short name is in brackets (type: float, default: 3.14)
```

Arguments to the CLI look just like calling the Python function.

```pycon
>>> from intro import some_function
>>> some_function("asdf", 0, 7, 8, 9, option=2.71)
required='asdf', not_required=0, others=(7, 8, 9), option=2.71
```

```console
user@machine:~$ ./intro.py asdf 0 7 8 9 --option 2.71
required='asdf', not_required=0, others=(7, 8, 9), option=2.71
```

`arguably` uses your docstrings to automatically generate help messages. It supports all major formats for docstrings:
reStructuredText, Google, Numpydoc, and Epydoc.

Type annotations are optional, but `arguably` can use them to automatically convert arguments. It has smart handling for
mapping built-in types to the command line, including `tuple`, `list`, `enum.Enum`, and `enum.Flag`.

There are also a few special behaviors you can attach to a parameter via `Annotated[]` and the `arguably.arg.*`
functions. Using `arguably.arg.builder()`, you can even build an object to pass in from the command line (using syntax
inspired by QEMU):

<div align="right"><sub>
    <a href="https://github.com/treykeown/arguably/blob/main/etc/scripts/build.py">[source]</a>
</sub></div>

```console
user@machine:~$ ./build.py --nic tap,model=e1000 --nic user,hostfwd=tcp::10022-:22
nic=[TapNic(model='e1000'), UserNic(hostfwd='tcp::10022-:22')]
```

## No integration required

Don't want to write any code? Simply pass any Python script to `arguably` to give it a command line interface.

<div align="right"><sub>
    <a href="https://github.com/treykeown/arguably/blob/main/etc/scripts/party-trick.py">[source]</a>
</sub></div>

```console
user@machine:~$ python3 -m arguably party-trick.py -h
usage: party-trick [-h] [--version] command ...

this is the docstring for the whole script

positional arguments:
  command
    hello                   this is hello's docstring
    goodbye                 any function from a script can be called
    some-class              so can any __init__ for objects defined in the script
    some-class.func-static  a @staticmethod on a class can be called
    some-class.func-cls     so can a @classmethod

options:
  -h, --help                show this help message and exit
  --version                 show program's version number and exit
```

## Installation

Install using `pip install arguably`. If you want to install using `conda`, please comment on
[this issue](https://github.com/treykeown/arguably/issues/12).

## Documentation

* Why arguably?: [https://treykeown.github.io/arguably/why/](https://treykeown.github.io/arguably/why/)
* Examples: [https://treykeown.github.io/arguably/examples/](https://treykeown.github.io/arguably/examples/)
* Tutorial: [https://treykeown.github.io/arguably/tutorial/intro/](https://treykeown.github.io/arguably/tutorial/intro/)
* API Reference: [https://treykeown.github.io/arguably/api-reference/](https://treykeown.github.io/arguably/api-reference/)

## Dependencies

All of `arguably` is built on top of `argparse`. It has two dependencies:

* `docstring-parser` for parsing function docstrings
* `typing-extensions` for `Annotated[]` support in Python 3.8 (only needed for that version)

## Contributing

Ideas and help are very much appreciated! There's a guide for getting started with contributing to `arguably` that shows
you how to run tests and pre-commit hooks.

* Contributing: [https://treykeown.github.io/arguably/contributing/](https://treykeown.github.io/arguably/contributing/)

## Future roadmap

If you have any interest in these (either as a user or implementer), please leave a comment!

* [#8 - Display all enum options in a command group](https://github.com/treykeown/arguably/issues/8)
* [#9 - Both positive and negative boolean flags](https://github.com/treykeown/arguably/issues/9)
* [#10 - Take inputs from environment variables](https://github.com/treykeown/arguably/issues/10)
* [#13 - Implement config interface](https://github.com/treykeown/arguably/issues/13)
* [#16 - Integration with rich for formatted CLI output](https://github.com/treykeown/arguably/issues/16)

            

Raw data

            {
    "_id": null,
    "home_page": "https://treykeown.github.io/arguably/",
    "name": "arguably",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8,<4.0",
    "maintainer_email": "",
    "keywords": "",
    "author": "treykeown",
    "author_email": "2755914+treykeown@users.noreply.github.com",
    "download_url": "https://files.pythonhosted.org/packages/ff/87/a11fd8a613f4da31057a7408d4eb257e7bec87254a4ed46d2944ea36a6cf/arguably-1.2.5.tar.gz",
    "platform": null,
    "description": "<p align=\"center\">\n      <img alt=\"arguably logo\" src=\"https://raw.githubusercontent.com/treykeown/arguably/main/etc/logo/arguably_black.png\">\n</p>\n\n<p align=\"center\">\n    <em>\n        The best Python CLI library, arguably.\n    </em>\n</p>\n\n<p align=\"center\">\n    <a href=\"https://github.com/treykeown/arguably/actions/workflows/python-package.yml\"><img src=\"https://github.com/treykeown/arguably/actions/workflows/python-package.yml/badge.svg\" alt=\"Test status\"></a>\n    <a href=\"https://treykeown.github.io/arguably/coverage/\"><img src=\"https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/treykeown/f493b14288af4e8358ea8578c393213a/raw/arguably-coverage-badge.json\" alt=\"Code coverage\"></a>\n    <a href=\"https://pypi.org/project/arguably/\"><img src=\"https://shields.io/pypi/pyversions/arguably\" alt=\"Supported Python versions\"></a>\n    <a href=\"https://pypi.org/project/arguably/\"><img src=\"https://shields.io/pypi/v/arguably\" alt=\"PyPI version\"></a>\n</p>\n<hr>\n\n`arguably` turns functions and docstrings into command line interfaces (CLIs). `arguably` has a tiny API and is\nextremely easy to integrate. You can also use it directly through `python3 -m arguably your_script.py`, more on that\n[here](#no-integration-required).\n\nTo use `arguably` in a script, decorate any functions that should appear on the command line with `@arguably.command`,\nthen call `arguably.run()`. If multiple functions are decorated, they'll all appear as subcommands. You can even have\n*multiple levels* of subcommands: `def s3__ls()` becomes `s3 ls`.\n\n<div align=\"right\"><sub>\n    <a href=\"https://github.com/treykeown/arguably/blob/main/etc/scripts/intro.py\">[source]</a>\n</sub></div>\n\n```python\n#!/usr/bin/env python3\nimport arguably\n\n@arguably.command\ndef some_function(required, not_required=2, *others: int, option: float = 3.14):\n    \"\"\"\n    this function is on the command line!\n\n    Args:\n        required: a required argument\n        not_required: this one isn't required, since it has a default value\n        *others: all the other positional arguments go here\n        option: [-x] keyword-only args are options, short name is in brackets\n    \"\"\"\n    print(f\"{required=}, {not_required=}, {others=}, {option=}\")\n\nif __name__ == \"__main__\":\n    arguably.run()\n```\n\n<p align=\"center\"><b><em>becomes</em></b></p>\n\n```console\nuser@machine:~$ ./intro.py -h\nusage: intro.py [-h] [-x OPTION] required [not-required] [others ...]\n\nthis function is on the command line!\n\npositional arguments:\n  required             a required argument (type: str)\n  not-required         this one isn't required, since it has a default value (type: int, default: 2)\n  others               all the other positional arguments go here (type: int)\n\noptions:\n  -h, --help           show this help message and exit\n  -x, --option OPTION  keyword-only args are options, short name is in brackets (type: float, default: 3.14)\n```\n\nArguments to the CLI look just like calling the Python function.\n\n```pycon\n>>> from intro import some_function\n>>> some_function(\"asdf\", 0, 7, 8, 9, option=2.71)\nrequired='asdf', not_required=0, others=(7, 8, 9), option=2.71\n```\n\n```console\nuser@machine:~$ ./intro.py asdf 0 7 8 9 --option 2.71\nrequired='asdf', not_required=0, others=(7, 8, 9), option=2.71\n```\n\n`arguably` uses your docstrings to automatically generate help messages. It supports all major formats for docstrings:\nreStructuredText, Google, Numpydoc, and Epydoc.\n\nType annotations are optional, but `arguably` can use them to automatically convert arguments. It has smart handling for\nmapping built-in types to the command line, including `tuple`, `list`, `enum.Enum`, and `enum.Flag`.\n\nThere are also a few special behaviors you can attach to a parameter via `Annotated[]` and the `arguably.arg.*`\nfunctions. Using `arguably.arg.builder()`, you can even build an object to pass in from the command line (using syntax\ninspired by QEMU):\n\n<div align=\"right\"><sub>\n    <a href=\"https://github.com/treykeown/arguably/blob/main/etc/scripts/build.py\">[source]</a>\n</sub></div>\n\n```console\nuser@machine:~$ ./build.py --nic tap,model=e1000 --nic user,hostfwd=tcp::10022-:22\nnic=[TapNic(model='e1000'), UserNic(hostfwd='tcp::10022-:22')]\n```\n\n## No integration required\n\nDon't want to write any code? Simply pass any Python script to `arguably` to give it a command line interface.\n\n<div align=\"right\"><sub>\n    <a href=\"https://github.com/treykeown/arguably/blob/main/etc/scripts/party-trick.py\">[source]</a>\n</sub></div>\n\n```console\nuser@machine:~$ python3 -m arguably party-trick.py -h\nusage: party-trick [-h] [--version] command ...\n\nthis is the docstring for the whole script\n\npositional arguments:\n  command\n    hello                   this is hello's docstring\n    goodbye                 any function from a script can be called\n    some-class              so can any __init__ for objects defined in the script\n    some-class.func-static  a @staticmethod on a class can be called\n    some-class.func-cls     so can a @classmethod\n\noptions:\n  -h, --help                show this help message and exit\n  --version                 show program's version number and exit\n```\n\n## Installation\n\nInstall using `pip install arguably`. If you want to install using `conda`, please comment on\n[this issue](https://github.com/treykeown/arguably/issues/12).\n\n## Documentation\n\n* Why arguably?: [https://treykeown.github.io/arguably/why/](https://treykeown.github.io/arguably/why/)\n* Examples: [https://treykeown.github.io/arguably/examples/](https://treykeown.github.io/arguably/examples/)\n* Tutorial: [https://treykeown.github.io/arguably/tutorial/intro/](https://treykeown.github.io/arguably/tutorial/intro/)\n* API Reference: [https://treykeown.github.io/arguably/api-reference/](https://treykeown.github.io/arguably/api-reference/)\n\n## Dependencies\n\nAll of `arguably` is built on top of `argparse`. It has two dependencies:\n\n* `docstring-parser` for parsing function docstrings\n* `typing-extensions` for `Annotated[]` support in Python 3.8 (only needed for that version)\n\n## Contributing\n\nIdeas and help are very much appreciated! There's a guide for getting started with contributing to `arguably` that shows\nyou how to run tests and pre-commit hooks.\n\n* Contributing: [https://treykeown.github.io/arguably/contributing/](https://treykeown.github.io/arguably/contributing/)\n\n## Future roadmap\n\nIf you have any interest in these (either as a user or implementer), please leave a comment!\n\n* [#8 - Display all enum options in a command group](https://github.com/treykeown/arguably/issues/8)\n* [#9 - Both positive and negative boolean flags](https://github.com/treykeown/arguably/issues/9)\n* [#10 - Take inputs from environment variables](https://github.com/treykeown/arguably/issues/10)\n* [#13 - Implement config interface](https://github.com/treykeown/arguably/issues/13)\n* [#16 - Integration with rich for formatted CLI output](https://github.com/treykeown/arguably/issues/16)\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "The best Python CLI library, arguably.",
    "version": "1.2.5",
    "project_urls": {
        "Homepage": "https://treykeown.github.io/arguably/",
        "Repository": "https://github.com/treykeown/arguably"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "27b4f5277af855a1a06e2106fbc72bcd937e2856f159e7d4e12f7e2bff872862",
                "md5": "50b94c6071e637703737853a8c7a9a88",
                "sha256": "ab6667a0c6762fd79e78fae38eafe61dcf2295ebccef24a350298cd1068b4994"
            },
            "downloads": -1,
            "filename": "arguably-1.2.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "50b94c6071e637703737853a8c7a9a88",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8,<4.0",
            "size": 35329,
            "upload_time": "2023-06-29T11:10:16",
            "upload_time_iso_8601": "2023-06-29T11:10:16.384482Z",
            "url": "https://files.pythonhosted.org/packages/27/b4/f5277af855a1a06e2106fbc72bcd937e2856f159e7d4e12f7e2bff872862/arguably-1.2.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ff87a11fd8a613f4da31057a7408d4eb257e7bec87254a4ed46d2944ea36a6cf",
                "md5": "7fb501d20887ee5d7fdadc80a48482d6",
                "sha256": "d55963abbab823b8ad1da798216cd6a7106b3238178855d6ad495beed60ab423"
            },
            "downloads": -1,
            "filename": "arguably-1.2.5.tar.gz",
            "has_sig": false,
            "md5_digest": "7fb501d20887ee5d7fdadc80a48482d6",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8,<4.0",
            "size": 30786,
            "upload_time": "2023-06-29T11:10:18",
            "upload_time_iso_8601": "2023-06-29T11:10:18.405327Z",
            "url": "https://files.pythonhosted.org/packages/ff/87/a11fd8a613f4da31057a7408d4eb257e7bec87254a4ed46d2944ea36a6cf/arguably-1.2.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-06-29 11:10:18",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "treykeown",
    "github_project": "arguably",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "arguably"
}
        
Elapsed time: 0.08253s