{"id":15655476,"url":"https://github.com/cdeil/python-cli-examples","last_synced_at":"2025-08-18T08:04:46.835Z","repository":{"id":142038903,"uuid":"114613885","full_name":"cdeil/python-cli-examples","owner":"cdeil","description":"Examples exploring Python command line interface (CLI) packages","archived":false,"fork":false,"pushed_at":"2018-01-02T22:06:15.000Z","size":12,"stargazers_count":26,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-05T14:52:14.519Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cdeil.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2017-12-18T08:15:22.000Z","updated_at":"2025-01-12T22:28:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"dd975a8b-15bd-429c-a227-1635d88088af","html_url":"https://github.com/cdeil/python-cli-examples","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cdeil/python-cli-examples","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdeil%2Fpython-cli-examples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdeil%2Fpython-cli-examples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdeil%2Fpython-cli-examples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdeil%2Fpython-cli-examples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cdeil","download_url":"https://codeload.github.com/cdeil/python-cli-examples/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdeil%2Fpython-cli-examples/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270962391,"owners_count":24675965,"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","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-10-03T12:59:26.845Z","updated_at":"2025-08-18T08:04:46.779Z","avatar_url":"https://github.com/cdeil.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# python-cli-examples\n\nExamples exploring Python command line interface (CLI) packages.\n\n## What I want\n\nThis is not a complete overview of ways to create CLIs in Python,\njust something rather specific.\n\nHere's what I want:\n\n* A single command line tool, lots of sub-commands.\n  Like `git` which has subcommands `git status`, `git commit`, ...\n* The cli is part of a Python package, exposed both via a\n  setuptools entry point and `__main__.py`, i.e.\n* Just calling the main cli should print some help, i.e.\n  a list of main cli arguments and available subcommands\n  (like how `git` and `git --help` print the same thing).\n* Code organisation: ideally the code for each sub-command can be\n  a separate Python file. Having \"lazy loading\", i.e. import only\n  for the subcommand that is executed, would be nice, but is not\n  a hard requirement.\n* Logging should be handled once only on the main command, avoid\n  repetitive and boilerplate code on subcommands.\n* It should be easy to write tests for each command,\n  including asserts on return code, stdout and stdin\n* It should be possible to get a list of available subcommands,\n  as well as the arguments for a given command, without actually\n  executing the command. Without any actual argument parsing or\n  command execution occurring.\n*\n* CLI documentation generation as part of Sphinx docs\n\nI do not need:\n\n* A plugin mechanism where users or other packages can add or\n  extend commands in my package.\n* Passing arguments for the main command to the subcommands.\n* An interactive way to prompt for arguments, like the FTOOLs do.\n  (although this could probably be implemented nicely using\n\n## Contents\n\nAs an example, we'll create a simple cli called `greet` in a package\ncalled `greet` that has two subcommands: `hello` and `bye`, using\nthe following Python cli packages:\n\n* https://docs.python.org/3/library/argparse.html\n  * This is the Python std library solution. Used e.g. by `conda`.\n* http://click.pocoo.org/dev/\n  * From Arnim Ronacher. Used e.g. by Flask (see http://flask.pocoo.org/docs/dev/cli/)\n  * The front page says \"arbitrary nesting of commands\" and \"supports lazy loading of subcommands at runtime\"\n    which is what we want here, and what is hard with argparse.\n* https://docs.openstack.org/cliff/latest/\n  * From Dough Hellman. Used by OpenStack.\n* http://traitlets.readthedocs.io/en/stable/config.html#command-line-arguments\n  * Used by ipython for configuration and cli\n  * Also used by ctapipe (see https://cta-observatory.github.io/ctapipe/api/ctapipe.core.Tool.html\n    and https://cta-observatory.github.io/ctapipe/core/index.html), and this investigation\n    is for what to use for http://gammapy.org/ and we want to collaborate with ctapipe.\n\n## References\n\n* https://github.com/gammapy/gammapy/pull/1235\n\n## Testing\n\nTo test, we suggest you use a virtual environment for each of the solutions presented here.\nFor example to work on the one in the `argparse` folder:\n\n    cd argparse\n    python -m venv venv\n    . venv/bin/activate\n    python -m pip install -e .\n    greet --help\n    python -m greet --help\n    python -m pytest -v\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdeil%2Fpython-cli-examples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcdeil%2Fpython-cli-examples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdeil%2Fpython-cli-examples/lists"}