{"id":20108768,"url":"https://github.com/janluke/cloup","last_synced_at":"2026-02-23T23:34:59.740Z","repository":{"id":39620466,"uuid":"243063232","full_name":"janluke/cloup","owner":"janluke","description":"Library to build command line interfaces based on Click. It extends click with: option groups, constraints (e.g. mutually exclusive params), command aliases, help themes, \"did you mean ...?\" suggestions and more.","archived":false,"fork":false,"pushed_at":"2025-09-28T17:50:28.000Z","size":822,"stargazers_count":126,"open_issues_count":10,"forks_count":15,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-02-19T18:54:19.028Z","etag":null,"topics":["cli","click","library","package","python"],"latest_commit_sha":null,"homepage":"https://cloup.readthedocs.io/","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/janluke.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":"CONTRIBUTING.rst","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-02-25T17:51:36.000Z","updated_at":"2026-01-29T09:04:05.000Z","dependencies_parsed_at":"2024-06-18T18:18:13.406Z","dependency_job_id":"07728bab-6e93-42a4-ae76-4add609ecde6","html_url":"https://github.com/janluke/cloup","commit_stats":{"total_commits":666,"total_committers":6,"mean_commits":111.0,"dds":0.03153153153153154,"last_synced_commit":"151123e973979d927226237ea601c7608ec599d6"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"purl":"pkg:github/janluke/cloup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janluke%2Fcloup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janluke%2Fcloup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janluke%2Fcloup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janluke%2Fcloup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/janluke","download_url":"https://codeload.github.com/janluke/cloup/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janluke%2Fcloup/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29760706,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T21:02:23.375Z","status":"ssl_error","status_checked_at":"2026-02-23T20:58:31.539Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cli","click","library","package","python"],"created_at":"2024-11-13T18:01:36.592Z","updated_at":"2026-02-23T23:34:59.723Z","avatar_url":"https://github.com/janluke.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":".. raw:: html\n\n    \u003cp align=\"center\"\u003e\n        \u003cimg\n            src=\"https://raw.githubusercontent.com/janLuke/cloup/master/docs/_static/logo-on-white.svg\"\n            width=\"50%\" /\u003e\n    \u003c/p\u003e\n\n    \u003cp align=\"center\"\u003e\n        \u003ci\u003e\n            \u003ca href=\"https://github.com/pallets/click\"\u003eClick\u003c/a\u003e\n            + option groups + constraints + aliases + help themes + ...\n        \u003c/i\u003e\n    \u003c/p\u003e\n\n    \u003cp align=\"center\"\u003e\n        \u003ca href=\"https://cloup.readthedocs.io/\"\u003ehttps://cloup.readthedocs.io/\u003c/a\u003e\n    \u003c/a\u003e\n\n----------\n\n.. docs-index-start\n\n.. |pypi-release| image:: https://img.shields.io/pypi/v/cloup.svg\n    :alt: Latest release on PyPI\n    :target: https://pypi.org/project/cloup/\n\n.. |tests-status| image:: https://github.com/janLuke/cloup/workflows/Tests/badge.svg\n    :alt: Tests status\n    :target: https://github.com/janLuke/cloup/actions?query=workflow%3ATests\n\n.. |coverage| image:: https://codecov.io/github/janLuke/cloup/coverage.svg?branch=master\n    :alt: Coverage Status\n    :target: https://app.codecov.io/github/janluke/cloup/tree/master\n\n.. |python-versions| image:: https://img.shields.io/pypi/pyversions/cloup.svg\n    :alt: Supported versions\n    :target: https://pypi.org/project/cloup\n\n.. |dev-docs| image:: https://readthedocs.org/projects/cloup/badge/?version=latest\n    :alt: Documentation Status (master branch)\n    :target: https://cloup.readthedocs.io/en/latest/\n\n.. |release-docs| image:: https://readthedocs.org/projects/cloup/badge/?version=stable\n    :alt: Documentation Status (latest release)\n    :target: https://cloup.readthedocs.io/en/stable/\n\n.. |downloads| image:: https://static.pepy.tech/personalized-badge/cloup?period=week\u0026units=international_system\u0026left_color=grey\u0026right_color=blue\u0026left_text=downloads%20/%20week\n    :alt: PyPI - Downloads\n    :target: https://pepy.tech/project/cloup\n\n========\nOverview\n========\n|pypi-release| |downloads| |tests-status| |coverage| |dev-docs|\n\n**Cloup** — originally from \"**Cl**\\ick + option gr\\ **oup**\\s\" — enriches\n`Click \u003chttps://github.com/pallets/click\u003e`_ with several features that make it\nmore expressive and configurable:\n\n- **option groups** and an (optional) help section for positional arguments\n\n- **constraints**, like ``mutually_exclusive``, that can be applied to option groups\n  or to any group of parameters, even *conditionally*\n\n- **subcommand aliases**\n\n- **subcommands sections**, i.e. the possibility of organizing the subcommands of a\n  ``Group`` in multiple help sections\n\n- a **themeable HelpFormatter**  that:\n\n  - has more parameters for adjusting widths and spacing, which can be provided\n    at the context and command level\n  - use a different layout when the terminal width is below a certain threshold\n    in order to improve readability\n\n- suggestions like \"did you mean \u003csubcommand\u003e?\" when you mistype a subcommand.\n\nMoreover, Cloup improves on **IDE support** providing decorators with *detailed*\ntype hints and adding the static methods ``Context.settings()`` and\n``HelpFormatter.settings()`` for creating dictionaries of settings.\n\nCloup is **statically type-checked** with MyPy in strict mode and extensively **tested**\nagainst multiple versions of Python with nearly 100% coverage.\n\n\nA simple example\n================\n\n.. code-block:: python\n\n    from cloup import (\n        HelpFormatter, HelpTheme, Style,\n        command, option, option_group\n    )\n    from cloup.constraints import RequireAtLeast, mutually_exclusive\n\n    # Check the docs for all available arguments of HelpFormatter and HelpTheme.\n    formatter_settings = HelpFormatter.settings(\n        theme=HelpTheme(\n            invoked_command=Style(fg='bright_yellow'),\n            heading=Style(fg='bright_white', bold=True),\n            constraint=Style(fg='magenta'),\n            col1=Style(fg='bright_yellow'),\n        )\n    )\n\n    # In a multi-command app, you can pass formatter_settings as part\n    # of your context_settings so that they are propagated to subcommands.\n    @command(formatter_settings=formatter_settings)\n    @option_group(\n        \"Cool options\",\n        option('--foo', help='This text should describe the option --foo.'),\n        option('--bar', help='This text should describe the option --bar.'),\n        constraint=mutually_exclusive,\n    )\n    @option_group(\n        \"Other cool options\",\n        \"This is the optional description of this option group.\",\n        option('--pippo', help='This text should describe the option --pippo.'),\n        option('--pluto', help='This text should describe the option --pluto.'),\n        constraint=RequireAtLeast(1),\n    )\n    def cmd(**kwargs):\n        \"\"\"This is the command description.\"\"\"\n        pass\n\n    if __name__ == '__main__':\n        cmd(prog_name='invoked-command')\n\n\n.. image:: https://raw.githubusercontent.com/janLuke/cloup/master/docs/_static/basic-example.png\n    :alt: Basic example --help screenshot\n\nIf you don't provide ``--pippo`` or ``--pluto``:\n\n.. code-block:: text\n\n    Usage: invoked-command [OPTIONS]\n    Try 'invoked-command --help' for help.\n\n    Error: at least 1 of the following parameters must be set:\n      --pippo\n      --pluto\n\nThis simple example just scratches the surface. Read more in the documentation\n(links below).\n\n.. docs-index-end\n\n\nLinks\n=====\n\n* Documentation (release_ | development_)\n* `Changelog \u003chttps://cloup.readthedocs.io/en/stable/pages/changelog.html\u003e`_\n* `GitHub repository \u003chttps://github.com/janLuke/cloup\u003e`_\n* `Q\u0026A and discussions \u003chttps://github.com/janLuke/cloup/discussions\u003e`_\n\n.. _release: https://cloup.readthedocs.io/en/stable/#user-guide\n.. _development: https://cloup.readthedocs.io/en/latest/#user-guide\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanluke%2Fcloup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjanluke%2Fcloup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanluke%2Fcloup/lists"}