{"id":13825313,"url":"https://github.com/treykeown/arguably","last_synced_at":"2025-07-08T21:32:02.565Z","repository":{"id":172793059,"uuid":"649782052","full_name":"treykeown/arguably","owner":"treykeown","description":"The best Python CLI library, arguably.","archived":false,"fork":false,"pushed_at":"2024-05-10T01:08:12.000Z","size":3682,"stargazers_count":378,"open_issues_count":9,"forks_count":3,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-11-20T03:32:14.037Z","etag":null,"topics":["cli","command-line","python","python3"],"latest_commit_sha":null,"homepage":"https://treykeown.github.io/arguably/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/treykeown.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-05T16:11:08.000Z","updated_at":"2024-11-12T15:03:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"da731102-08d4-4a04-8c8a-a9746f2f4f41","html_url":"https://github.com/treykeown/arguably","commit_stats":null,"previous_names":["treykeown/noarg","treykeown/arguably"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/treykeown/arguably","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/treykeown%2Farguably","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/treykeown%2Farguably/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/treykeown%2Farguably/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/treykeown%2Farguably/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/treykeown","download_url":"https://codeload.github.com/treykeown/arguably/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/treykeown%2Farguably/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264352790,"owners_count":23594971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","command-line","python","python3"],"created_at":"2024-08-04T09:01:18.310Z","updated_at":"2025-07-08T21:32:02.200Z","avatar_url":"https://github.com/treykeown.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cpicture\u003e\n      \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/treykeown/arguably/main/etc/logo/arguably_white.png\"\u003e\n      \u003cimg alt=\"arguably logo\" src=\"https://raw.githubusercontent.com/treykeown/arguably/main/etc/logo/arguably_black.png\"\u003e\n    \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cem\u003e\n        The best Python CLI library, arguably.\n    \u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/treykeown/arguably/actions/workflows/python-package.yml\"\u003e\u003cimg src=\"https://github.com/treykeown/arguably/actions/workflows/python-package.yml/badge.svg\" alt=\"Test status\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://treykeown.github.io/arguably/coverage/\"\u003e\u003cimg src=\"https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/treykeown/f493b14288af4e8358ea8578c393213a/raw/arguably-coverage-badge.json\" alt=\"Code coverage\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/arguably/\"\u003e\u003cimg src=\"https://shields.io/pypi/pyversions/arguably\" alt=\"Supported Python versions\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/arguably/\"\u003e\u003cimg src=\"https://shields.io/pypi/v/arguably\" alt=\"PyPI version\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003chr\u003e\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\u003cdiv align=\"right\"\u003e\u003csub\u003e\n    \u003ca href=\"https://github.com/treykeown/arguably/blob/main/etc/scripts/intro.py\"\u003e[source]\u003c/a\u003e\n\u003c/sub\u003e\u003c/div\u003e\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\u003cp align=\"center\"\u003e\u003cb\u003e\u003cem\u003ebecomes\u003c/em\u003e\u003c/b\u003e\u003c/p\u003e\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\u003e\u003e\u003e from intro import some_function\n\u003e\u003e\u003e 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\u003cdiv align=\"right\"\u003e\u003csub\u003e\n    \u003ca href=\"https://github.com/treykeown/arguably/blob/main/etc/scripts/build.py\"\u003e[source]\u003c/a\u003e\n\u003c/sub\u003e\u003c/div\u003e\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\u003cdiv align=\"right\"\u003e\u003csub\u003e\n    \u003ca href=\"https://github.com/treykeown/arguably/blob/main/etc/scripts/party-trick.py\"\u003e[source]\u003c/a\u003e\n\u003c/sub\u003e\u003c/div\u003e\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 one dependency:\n\n* `docstring-parser` for parsing function docstrings\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","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftreykeown%2Farguably","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftreykeown%2Farguably","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftreykeown%2Farguably/lists"}