| Name | foxcli JSON |
| Version |
0.4.1
JSON |
| download |
| home_page | None |
| Summary | A lightweight and minimal CLI framework |
| upload_time | 2025-10-27 20:27:14 |
| maintainer | None |
| docs_url | None |
| author | depthbomb |
| requires_python | >=3.12 |
| license | MIT |
| keywords |
cli
framework
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
from cli import UnknownCommandError> [!IMPORTANT]
> While foxcli is pre-1.0.0, breaking changes may be made without bumping the major version!
_foxcli_ is a minimal-by-design CLI framework for Python.
There are many great CLI frameworks out there, but some features I like in one aren't present in another. Likewise, one framework I like may have features that I don't like or has a bunch of extra features that I don't need.
foxcli being minimal-by-design means that it does not include any built-in commands, no TUI helpers, no command usage generation. You will have to handle all of this yourself.
This framework features:
- Class-based commands + being able to subclass its `Command` class
- Multi-level commands (like `user create`)
- Global options that can appear anywhere in command invocation
- Hooks to customize error handling
foxcli is still very much in early development but certainly usable, in fact I am using it in a testdrive with my project [WinUtils](https://github.com/depthbomb/winutils)!
Planned features include:
- Counted arguments like `-vvv`
# Installation
```shell
pip install foxcli
```
# Sample
```py
from sys import exit
from foxcli.cli import CLI
from foxcli.command import Command
from foxcli.argument import Argument
from foxcli.option import Opt, Option
class App(CLI):
# hooks to customize error handling
def on_unknown_command(self, e):
# command not found, show a custom usage message?
return 1
app = App(
name='myapp',
version='1.0.0',
description='My app',
global_options=[
# global options, accessible in commands via `self.ctx.global_options`
Option(name='verbose', short='v', default=False, help='Show verbose output'),
]
)
@app.command()
class Version(Command):
name = 'version'
description = 'Show version'
def run(self, args) -> int:
print(self.ctx.cli.version)
return 0
# subclassing `Command` to add options
class UserableCommand(Command):
arguments = [
Argument('username'), # supports `nargs` which takes int, '*', '+', and '?'. defaults to 1, which implicitly makes it required
]
@app.command()
class User(Command):
name = 'user'
aliases = ['u']
description = 'User management commands'
# multi-level command
@app.command(parent='user')
class UserCreate(UserableCommand):
name = 'create'
description = 'Creates a new user'
aliases = ['c', 'add']
arguments = [
# positional arguments
Argument('avatar', default='https://website.com/image.png'), # supports default values
]
options = [
Opt('rank', short='r', required=True) # shortcut for `Option`, `Arg` also exists
]
# `myapp user add Caim -r "Super Admin" -v`
def run(self, args) -> int:
# self.ctx.global_options.get('verbose', bool) -> True
print(self.ctx.global_options.to_dict()) # {'verbose': True}
# args.get('username', str) -> 'Caim'
# args.get('avatar', str) -> 'https://website.com/image.png'
# args.get('rank', str) -> 'Super Admin'
print(args.to_dict()) # {'username': 'Caim', 'avatar': 'https://website.com/image.png', 'rank': 'Super Admin'}
return 0
exit(app.run())
```
Raw data
{
"_id": null,
"home_page": null,
"name": "foxcli",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "cli, framework",
"author": "depthbomb",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/5b/f2/4fc4ba2a2e07e796e5f842176bece6f4d3b53f8ebb093e3531f5294e1678/foxcli-0.4.1.tar.gz",
"platform": null,
"description": "from cli import UnknownCommandError> [!IMPORTANT]\n> While foxcli is pre-1.0.0, breaking changes may be made without bumping the major version!\n\n_foxcli_ is a minimal-by-design CLI framework for Python.\n\nThere are many great CLI frameworks out there, but some features I like in one aren't present in another. Likewise, one framework I like may have features that I don't like or has a bunch of extra features that I don't need.\n\nfoxcli being minimal-by-design means that it does not include any built-in commands, no TUI helpers, no command usage generation. You will have to handle all of this yourself.\n\nThis framework features:\n\n- Class-based commands + being able to subclass its `Command` class\n- Multi-level commands (like `user create`)\n- Global options that can appear anywhere in command invocation\n- Hooks to customize error handling\n\nfoxcli is still very much in early development but certainly usable, in fact I am using it in a testdrive with my project [WinUtils](https://github.com/depthbomb/winutils)!\n\nPlanned features include:\n\n- Counted arguments like `-vvv`\n\n# Installation\n\n```shell\npip install foxcli\n```\n\n# Sample\n\n```py\nfrom sys import exit\nfrom foxcli.cli import CLI\nfrom foxcli.command import Command\nfrom foxcli.argument import Argument\nfrom foxcli.option import Opt, Option\n\nclass App(CLI):\n # hooks to customize error handling\n def on_unknown_command(self, e):\n # command not found, show a custom usage message?\n return 1\n\napp = App(\n name='myapp',\n version='1.0.0',\n description='My app',\n global_options=[\n # global options, accessible in commands via `self.ctx.global_options`\n Option(name='verbose', short='v', default=False, help='Show verbose output'),\n ]\n)\n\n@app.command()\nclass Version(Command):\n name = 'version'\n description = 'Show version'\n\n def run(self, args) -> int:\n print(self.ctx.cli.version)\n return 0\n\n# subclassing `Command` to add options\nclass UserableCommand(Command):\n arguments = [\n Argument('username'), # supports `nargs` which takes int, '*', '+', and '?'. defaults to 1, which implicitly makes it required\n ]\n\n@app.command()\nclass User(Command):\n name = 'user'\n aliases = ['u']\n description = 'User management commands'\n\n# multi-level command\n@app.command(parent='user')\nclass UserCreate(UserableCommand):\n name = 'create'\n description = 'Creates a new user'\n aliases = ['c', 'add']\n arguments = [\n # positional arguments\n Argument('avatar', default='https://website.com/image.png'), # supports default values\n ]\n options = [\n Opt('rank', short='r', required=True) # shortcut for `Option`, `Arg` also exists\n ]\n\n # `myapp user add Caim -r \"Super Admin\" -v`\n def run(self, args) -> int:\n # self.ctx.global_options.get('verbose', bool) -> True\n print(self.ctx.global_options.to_dict()) # {'verbose': True}\n\n # args.get('username', str) -> 'Caim'\n # args.get('avatar', str) -> 'https://website.com/image.png'\n # args.get('rank', str) -> 'Super Admin'\n print(args.to_dict()) # {'username': 'Caim', 'avatar': 'https://website.com/image.png', 'rank': 'Super Admin'}\n return 0\n\nexit(app.run())\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A lightweight and minimal CLI framework",
"version": "0.4.1",
"project_urls": {
"Changelog": "https://github.com/depthbomb/foxcli/blob/master/CHANGELOG.md",
"Issues": "https://github.com/depthbomb/foxcli/issues",
"Repository": "https://github.com/depthbomb/foxcli"
},
"split_keywords": [
"cli",
" framework"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "b6e25aa1c82be2d7e37527f10e709a6b0701c16ffb8a1d320616d80b7ad34606",
"md5": "0d0d598a970e9a88b0f8168d1cba4cbe",
"sha256": "4cc0436429b40f998d3836cd4a89f73dcbb783ca924fd4bedb7256e649698ed0"
},
"downloads": -1,
"filename": "foxcli-0.4.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0d0d598a970e9a88b0f8168d1cba4cbe",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 10238,
"upload_time": "2025-10-27T20:27:13",
"upload_time_iso_8601": "2025-10-27T20:27:13.416121Z",
"url": "https://files.pythonhosted.org/packages/b6/e2/5aa1c82be2d7e37527f10e709a6b0701c16ffb8a1d320616d80b7ad34606/foxcli-0.4.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5bf24fc4ba2a2e07e796e5f842176bece6f4d3b53f8ebb093e3531f5294e1678",
"md5": "52fb902fcb5403d12a62bb9b3399c0e7",
"sha256": "e5068ce97af1af63f3fb31434e1ba2e09bf7886eae593ff8304b475c1f85428c"
},
"downloads": -1,
"filename": "foxcli-0.4.1.tar.gz",
"has_sig": false,
"md5_digest": "52fb902fcb5403d12a62bb9b3399c0e7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 8007,
"upload_time": "2025-10-27T20:27:14",
"upload_time_iso_8601": "2025-10-27T20:27:14.406240Z",
"url": "https://files.pythonhosted.org/packages/5b/f2/4fc4ba2a2e07e796e5f842176bece6f4d3b53f8ebb093e3531f5294e1678/foxcli-0.4.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-27 20:27:14",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "depthbomb",
"github_project": "foxcli",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "foxcli"
}