{"id":36564828,"url":"https://github.com/marcusfrdk/click-extended","last_synced_at":"2026-02-23T14:17:19.061Z","repository":{"id":322987085,"uuid":"1091656654","full_name":"marcusfrdk/click-extended","owner":"marcusfrdk","description":"An extension of the Click library with additional features like aliasing, asynchronous support, an extended decorator API and more.","archived":false,"fork":false,"pushed_at":"2026-02-05T13:10:34.000Z","size":997,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-06T00:36:07.167Z","etag":null,"topics":["alias","async","cli","click","decorator","decorators","extension","python"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/click-extended/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcusfrdk.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-07T10:24:59.000Z","updated_at":"2026-02-05T13:10:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"03538077-726f-475c-a549-5895147fe562","html_url":"https://github.com/marcusfrdk/click-extended","commit_stats":null,"previous_names":["marcusfrdk/click-extended"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/marcusfrdk/click-extended","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusfrdk%2Fclick-extended","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusfrdk%2Fclick-extended/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusfrdk%2Fclick-extended/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusfrdk%2Fclick-extended/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcusfrdk","download_url":"https://codeload.github.com/marcusfrdk/click-extended/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcusfrdk%2Fclick-extended/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29179619,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T22:12:24.066Z","status":"ssl_error","status_checked_at":"2026-02-06T22:12:09.859Z","response_time":59,"last_error":"SSL_read: 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":["alias","async","cli","click","decorator","decorators","extension","python"],"created_at":"2026-01-12T06:56:30.201Z","updated_at":"2026-02-06T23:07:31.840Z","avatar_url":"https://github.com/marcusfrdk.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Banner](./assets/click-extended-banner.png)\n\n# Click Extended\n\n![top language](https://img.shields.io/github/languages/top/marcusfrdk/click-extended)\n![code size](https://img.shields.io/github/languages/code-size/marcusfrdk/click-extended)\n![last commit](https://img.shields.io/github/last-commit/marcusfrdk/click-extended)\n![tests](https://github.com/marcusfrdk/click-extended/actions/workflows/tests.yml/badge.svg)\n![release](https://github.com/marcusfrdk/click-extended/actions/workflows/release.yml/badge.svg)\n![issues](https://img.shields.io/github/issues/marcusfrdk/click-extended)\n![contributors](https://img.shields.io/github/contributors/marcusfrdk/click-extended)\n![pypi](https://img.shields.io/pypi/v/click-extended)\n![license](https://img.shields.io/github/license/marcusfrdk/click-extended)\n![downloads](https://static.pepy.tech/badge/click-extended)\n![monthly downloads](https://static.pepy.tech/badge/click-extended/month)\n\nAn extension of the [Click](https://github.com/pallets/click) library with additional features like aliasing, asynchronous support, an extended decorator API and more.\n\n## Features\n\n- **Decorator API**: Extend the functionality your command line by adding custom data sources, data processing pipelines, and more.\n- **Aliasing**: Use aliases for groups and commands to reduce boilerplate and code repetition.\n- **Tags**: Use tags to group several data sources together to apply batch processing.\n- **Async Support**: Native support for declaring functions and methods asynchronous.\n- **Environment Variables**: Built-in support for loading and using environment variables as a data source.\n- **Full Type Support**: Built with type-hinting from the ground up, meaning everything is fully typed.\n- **Improved Errors**: Improved error output like tips, debugging, and more.\n- **Short Flag Concatenation**: Automatically support concatenating short hand flags where `-r -f` is the same as `-rf`.\n- **Global state**: Access global state through the context's `data` property.\n- **Hook API**: Hook into various points and run custom functions in the lifecycle.\n\n## Installation\n\n```bash\npip install click-extended\n```\n\n## Requirements\n\n- **Python**: 3.10 or higher\n\n## Quick Start\n\n### Basic Command\n\n```python\nfrom click_extended import command, argument, option\n\n@command(aliases=\"ping\")\n@argument(\"value\")\n@option(\"--count\", \"-c\", default=1)\ndef my_function(value: str, count: int):\n    \"\"\"This is the help message for my_function.\"\"\"\n    if _ in range(count):\n        print(value)\n\nif __name__ == \"__main__\":\n    my_function()\n```\n\n```bash\n$ python cli.py \"Hello world\"\nHello world\n```\n\n```bash\n$ python cli.py \"Hello world\" --count 3\nHello world\nHello world\nHello world\n```\n\n### Basic Command Line Interface\n\n```python\nfrom click_extended import group, argument, option\n\n@group()\ndef my_group():\n    \"\"\"This is the help message for my_group.\"\"\"\n    print(\"Running initialization code...\")\n\n@my_group.command(aliases=[\"ping\", \"repeat\"])\n@argument(\"value\")\n@option(\"--count\", \"-c\", default=1)\ndef my_function(value: str, count: int):\n    \"\"\"This is the help message for my_function.\"\"\"\n    if _ in range(count):\n        print(value)\n\nif __name__ == \"__main__\":\n    my_group()\n```\n\n```bash\n$ python cli.py my_function \"Hello world\"\nRunning initialization code...\nHello world\n```\n\n```bash\n$ python cli.py my_function \"Hello world\" --count 3\nRunning initialization code...\nHello world\nHello world\nHello world\n```\n\n### Using Environment Variables\n\n```python\nfrom click_extended import group, command, env\n\n@group()\ndef my_group():\n    \"\"\"This is the help message for my_group.\"\"\"\n\n@my_group.command()\n@env(\"API_KEY\")\ndef my_function_1(api_key: str | None):\n    \"\"\"This is the help message for my_function.\"\"\"\n    print(f\"The API key is: {api_key}\")\n\n@my_group.command()\n@env(\"API_KEY\", required=True)\ndef my_function_2(api_key: str):\n    \"\"\"This is the help message for my_function.\"\"\"\n    print(f\"The API key is: {api_key}\")\n\nif __name__ == \"__main__\":\n    my_group()\n```\n\n```bash\n$ python cli.py my_function_1\nThe API key is: None\n```\n\n```bash\n$ API_KEY=api-key python cli.py my_function_1\nThe API key is: api-key\n```\n\n```bash\n$ python cli.py my_function_2\nProcessError (my_function_2): Required environment variable 'API_KEY' is not set.\n```\n\n```bash\n$ API_KEY=api-key python cli.py my_function_2\nThe API key is: api-key\n```\n\n### Load CSV Data\n\n```python\nimport pandas as pd\nfrom click_extended import command, argument\nfrom click_extended.decorators import to_path, load_csv\n\n@command()\n@argument(\"file\", param=\"data\")\n@to_path(extensions=[\"csv\"], exists=True)\n@load_csv()\ndef my_command(data: dict[str, Any], *args: Any, **kwargs: Any) -\u003e None:\n    df = pd.DataFrame(data)\n    print(df.head())\n```\n\n_Note: `pandas` is not installed in this library and must be installed manually due to size._\n\n### Pre-Built Children\n\nThis library includes a vast number of pre-built children, everything from checking values to transforming values.\n\n```python\nfrom click_extended import command, argument, option\nfrom click_extended.decorators import to_snake_case, strip, is_email, minimum, dependencies\n\n@command()\n@dependencies(\"username\", \"email\", \"password\")\n@argument(\"username\")\n@to_snake_case()\n@strip()\n@option(\"email\")\n@is_email()\n@option(\"password\")\n@minimum(8)\ndef create_account(username: str, email: str, password: str) -\u003e None:\n    print(\"Username:\", username)\n    print(\"Email:\", email)\n    print(\"Password:\", password)\n```\n\n### Custom Nodes\n\nIf the library does not include a decorator you need, you can easily create your own. Read more about creating your own [children](./docs/core/CHILD_NODE.md), [validators](./docs/core/VALIDATION_NODE.md), [child validators](./docs/core/CHILD_VALIDATION_NODE.md) or [parents](./docs/core/PARENT_NODE.md).\n\n```python\nfrom typing import Any\n\nfrom click_extended import group, argument, option\nfrom click_extended.classes import ChildNode\nfrom click_extended.types import Context, Decorator\n\nclass MyCustomChild(ChildNode):\n    def handle_string(\n        self,\n        value: str,\n        context: Context,\n        *args: Any,\n        **kwargs: Any,\n    ) -\u003e str:\n        if value == \"invalid\":\n            raise ValueError(\"The value 'invalid' is not valid\")\n\n        return value.upper()\n\ndef my_custom_child() -\u003e Decorator:\n    \"\"\"Checks if the value is invalid and converts it to uppercase.\"\"\"\n    return MyCustomChild.as_decorator()\n\n\n@group()\ndef my_group():\n    \"\"\"This is the help message for my_group.\"\"\"\n    print(\"Running initialization code...\")\n\n@my_group.command(aliases=[\"ping\", \"repeat\"])\n@argument(\"value\")\n@my_custom_child()\ndef my_function(value: str):\n    \"\"\"This is the help message for my_function.\"\"\"\n    print(f\"The value '{value}' should be uppercase.\")\n\nif __name__ == \"__main__\":\n    my_group()\n```\n\n```bash\n$ python cli.py my_function valid\nThe value 'VALID' should be uppercase.\n```\n\n```bash\n$ python cli.py my_function invalid\nValueError (my_function): \"The value 'invalid' is not valid\"\n```\n\n## Documentation\n\nThe full documentation is [available here](./docs/README.md) and goes through the full library, from explaining design choices, how to use the library, and much more.\n\n## Contributing\n\nContributors are more than welcome to work on this project. Read the [contribution documentation](./CONTRIBUTING.md) to learn more.\n\n## License\n\nThis project is licensed under the MIT License, see the [license file](./LICENSE) for details.\n\n## Acknowledgements\n\nThis project is built on top of the [Click](https://github.com/pallets/click) library.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcusfrdk%2Fclick-extended","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcusfrdk%2Fclick-extended","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcusfrdk%2Fclick-extended/lists"}