# ptcmd
[](LICENSE)
[](https://pypi.python.org/pypi/ptcmd)
[](https://github.com/Visecy/ptcmd/actions)


A modern interactive command-line application building library based on `prompt_toolkit`
**Language: English/[δΈζ](README_cn.md)**
## 1. Features
- π Built on `prompt_toolkit` for powerful interactive experiences
- π Automatic parameter parsing and completion
- π Rich text output support (using `rich` library)
- β‘ Native async command support
- π Built-in command completion and shortcut keys
## 2. Installation
Install from PyPI:
```bash
pip install ptcmd
```
Or install from source:
```bash
git clone https://github.com/Visecy/ptcmd.git
cd ptcmd
make install
```
## 3. Quick Start
Create a simple command-line application:
```python
import sys
from ptcmd import Cmd
class MyApp(Cmd):
def do_hello(self, argv: list[str]) -> None:
"""Hello World!"""
if argv:
name = argv[0]
else:
name = "World"
self.poutput(f"Hello, {name}!")
if __name__ == "__main__":
sys.exit(MyApp().cmdloop())
```
In this basic example:
1. We create a `MyApp` class inheriting from `Cmd`
2. Define a `do_hello` command method
3. The command accepts an optional name parameter
4. Uses "World" if no parameter is provided
5. Output greeting using `self.poutput()`
6. Start the CLI with `cmdloop()`
This example demonstrates:
- Command definition syntax
- Parameter handling
- Output display
- Application startup process
Run the program and try the `hello` command:
```
(Cmd) hello
Hello, World!
(Cmd) hello Alice
Hello, Alice!
```
## 4. Advanced Features
### 4.1 Auto Argument Parsing
For complex commands, use the `auto_argument` decorator with type hints for automatic argument parsing:
```python
from ptcmd import Cmd, Arg, auto_argument
class MathApp(Cmd):
@auto_argument
def do_add(
self,
x: float,
y: float,
*,
verbose: Arg[bool, "-v", "--verbose"] = False
) -> None:
"""Add two numbers"""
result = x + y
if verbose:
self.poutput(f"{x} + {y} = {result}")
else:
self.poutput(result)
```
This approach automatically generates equivalent argparse code:
- Converts positional parameters to required arguments
- Converts keyword parameters to optional flags
- Handles type conversion and validation
### 4.2 Rich Text Output
Leverage rich library for styled output:
```python
class RichApp(Cmd):
def do_hello(self, argv: list[str]) -> None:
self.poutput(f"[bold blue]Hello, World![/bold blue]")
```
For advanced formatting, access the console directly:
```python
class RichApp(Cmd):
def do_hello(self, argv: list[str]) -> None:
with self.console.pager(styles=True):
self.console.print("Hello, World!", style="bold blue")
```
### 4.3 Subcommand Support
For command functions that use the automatic parameter parsing feature, `ptcmd` allows you to add any number of sub-commands to them in a simple way. The execution order of command functions is starting from the root command and then executing them one by one.
1. Single-level subcommand example:
```python
from ptcmd import Cmd, auto_argument
class App(Cmd):
@auto_argument
def do_math(self):
"""Math operations"""
@do_math.add_subcommand("add")
def add(self, x: float, y: float):
"""Addition"""
self.poutput(f"{x} + {y} = {x + y}")
```
Usage examples:
```
(Cmd) math add 5 3
5.0 + 3.0 = 8.0
(Cmd) math sub 5 3
5.0 - 3.0 = 2.0
```
2. Multi-level subcommand example:
```python
from ptcmd import Cmd, auto_argument
class App(Cmd):
@auto_argument
def do_server(self):
"""Server management"""
@do_server.add_subcommand("db")
def db(self):
"""Database management"""
@db.add_subcommand("migrate")
def migrate(self, version: str):
"""Execute database migration"""
self.poutput(f"Migrating to version {version}...")
@do_server.add_subcommand("cache")
def cache(self):
"""Cache management"""
@cache.add_subcommand("clear")
def clear(self, confirm: bool = False):
"""Clear cache"""
if confirm:
self.poutput("Cache cleared")
else:
self.poutput("Please add --confirm to proceed")
```
Usage examples:
```
(Cmd) server db migrate v1.2.0
Migrating to version v1.2.0...
(Cmd) server cache clear --confirm
Cache cleared
```
### 4.4 Async Command Support
Native async/await support for I/O bound operations:
```python
import aiohttp
from ptcmd import Cmd, auto_argument
class AsyncApp(Cmd):
@auto_argument
async def do_get(self, url: str):
"""Fetch URL content"""
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
self.poutput(await resp.text(), markup=False)
```
## 5. Library Comparison
The following table compares the advantages and disadvantages of three libraries: cmd (standard library), cmd2, and ptcmd:
| Feature | cmd | cmd2 | ptcmd |
| ----------------------- | ------------- | ------------------------------- | ------------------------- |
| **Feature Richness** | Basic | Most Feature-Rich | Moderately Feature-Rich |
| **Learning Curve** | Simple | Medium | Medium |
| **Interactive Experience** | Basic | Good | Excellent (based on `prompt_toolkit`) |
| **Auto Completion** | None | Supported | Supported |
| **Argument Parsing** | Manual Handling | Requires building `ArgumentParser` | Auto Parsing |
| **Async Support** | None | None | Native Support |
| **Rich Text Output** | None | Uses `cmd2.ansi` module | Uses `rich` library |
| **Dependencies** | None | More | Most |
| **Performance** | High | Medium | Medium |
| **Use Case** | Simple CLI | Complex CLI | Modern CLI |
Key Advantages:
- **cmd**: Python standard library, no dependencies, suitable for simple CLI applications
- **cmd2**: Comprehensive features, good community support, compatible with `cmd`, suitable for traditional CLIs requiring rich features
- **ptcmd**: Provides the best interactive experience, native async support, suitable for modern CLI applications
## 6. Related Projects
- [prompt_toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) - Foundation for building powerful interactive command lines
- [rich](https://github.com/Textualize/rich) - Enables rich text formatting and beautiful output
- [typer](https://github.com/tiangolo/typer) - Modern CLI framework with type hints
- [cmd2](https://github.com/python-cmd2/cmd2) - Inspiration for many ptcmd features
- [argparse](https://docs.python.org/3/library/argparse.html) - Python's standard argument parsing library
- [cmd](https://docs.python.org/3/library/cmd.html) - Python's standard line-oriented command interpreters library
## 7. Special Thanks
- [cmd2](https://github.com/python-cmd2/cmd2) for inspiring the command completion system
- [Cline](https://cline.bot/) for assisting with project documentation and test cases
## 8 License
Apache License 2.0 - See [LICENSE](LICENSE)
Raw data
{
"_id": null,
"home_page": null,
"name": "ptcmd",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "Ovizro <ovizro@visecy.org>",
"keywords": "Python, cmd, interactive, prompt",
"author": null,
"author_email": "Visecy <Visecy@visecy.org>",
"download_url": "https://files.pythonhosted.org/packages/0c/49/5630021e8804ae5bd18f1136aae58e56e2306b10ba8462145d1a09106f0e/ptcmd-0.2.0.tar.gz",
"platform": null,
"description": "# ptcmd\n\n[](LICENSE)\n[](https://pypi.python.org/pypi/ptcmd)\n[](https://github.com/Visecy/ptcmd/actions)\n\n\n\nA modern interactive command-line application building library based on `prompt_toolkit`\n\n**Language: English/[\u4e2d\u6587](README_cn.md)**\n\n## 1. Features\n\n- \ud83d\ude80 Built on `prompt_toolkit` for powerful interactive experiences\n- \ud83d\udcdd Automatic parameter parsing and completion \n- \ud83c\udf08 Rich text output support (using `rich` library)\n- \u26a1 Native async command support\n- \ud83d\udd0d Built-in command completion and shortcut keys\n\n## 2. Installation\n\nInstall from PyPI:\n\n```bash\npip install ptcmd\n```\n\nOr install from source:\n\n```bash\ngit clone https://github.com/Visecy/ptcmd.git\ncd ptcmd\nmake install\n```\n\n## 3. Quick Start\n\nCreate a simple command-line application:\n\n```python\nimport sys\nfrom ptcmd import Cmd\n\nclass MyApp(Cmd):\n def do_hello(self, argv: list[str]) -> None:\n \"\"\"Hello World!\"\"\"\n if argv:\n name = argv[0]\n else:\n name = \"World\"\n self.poutput(f\"Hello, {name}!\")\n\nif __name__ == \"__main__\":\n sys.exit(MyApp().cmdloop())\n```\n\nIn this basic example:\n\n1. We create a `MyApp` class inheriting from `Cmd`\n2. Define a `do_hello` command method\n3. The command accepts an optional name parameter\n4. Uses \"World\" if no parameter is provided\n5. Output greeting using `self.poutput()`\n6. Start the CLI with `cmdloop()`\n\nThis example demonstrates:\n- Command definition syntax\n- Parameter handling\n- Output display\n- Application startup process\n\nRun the program and try the `hello` command:\n\n```\n(Cmd) hello\nHello, World!\n(Cmd) hello Alice\nHello, Alice!\n```\n\n## 4. Advanced Features\n\n### 4.1 Auto Argument Parsing\n\nFor complex commands, use the `auto_argument` decorator with type hints for automatic argument parsing:\n\n```python\nfrom ptcmd import Cmd, Arg, auto_argument\n\nclass MathApp(Cmd):\n @auto_argument\n def do_add(\n self,\n x: float,\n y: float,\n *,\n verbose: Arg[bool, \"-v\", \"--verbose\"] = False\n ) -> None:\n \"\"\"Add two numbers\"\"\"\n result = x + y\n if verbose:\n self.poutput(f\"{x} + {y} = {result}\")\n else:\n self.poutput(result)\n```\n\nThis approach automatically generates equivalent argparse code:\n- Converts positional parameters to required arguments\n- Converts keyword parameters to optional flags\n- Handles type conversion and validation\n\n### 4.2 Rich Text Output\n\nLeverage rich library for styled output:\n\n```python\nclass RichApp(Cmd):\n def do_hello(self, argv: list[str]) -> None:\n self.poutput(f\"[bold blue]Hello, World![/bold blue]\")\n```\n\nFor advanced formatting, access the console directly:\n\n```python\nclass RichApp(Cmd):\n def do_hello(self, argv: list[str]) -> None:\n with self.console.pager(styles=True):\n self.console.print(\"Hello, World!\", style=\"bold blue\")\n```\n\n### 4.3 Subcommand Support\n\nFor command functions that use the automatic parameter parsing feature, `ptcmd` allows you to add any number of sub-commands to them in a simple way. The execution order of command functions is starting from the root command and then executing them one by one.\n\n1. Single-level subcommand example:\n\n```python\nfrom ptcmd import Cmd, auto_argument\n\nclass App(Cmd):\n @auto_argument\n def do_math(self):\n \"\"\"Math operations\"\"\"\n \n @do_math.add_subcommand(\"add\")\n def add(self, x: float, y: float):\n \"\"\"Addition\"\"\"\n self.poutput(f\"{x} + {y} = {x + y}\")\n```\n\nUsage examples:\n```\n(Cmd) math add 5 3\n5.0 + 3.0 = 8.0\n(Cmd) math sub 5 3\n5.0 - 3.0 = 2.0\n```\n\n2. Multi-level subcommand example:\n\n```python\nfrom ptcmd import Cmd, auto_argument\n\nclass App(Cmd):\n @auto_argument\n def do_server(self):\n \"\"\"Server management\"\"\"\n \n @do_server.add_subcommand(\"db\")\n def db(self):\n \"\"\"Database management\"\"\"\n \n @db.add_subcommand(\"migrate\")\n def migrate(self, version: str):\n \"\"\"Execute database migration\"\"\"\n self.poutput(f\"Migrating to version {version}...\")\n\n @do_server.add_subcommand(\"cache\")\n def cache(self):\n \"\"\"Cache management\"\"\"\n \n @cache.add_subcommand(\"clear\")\n def clear(self, confirm: bool = False):\n \"\"\"Clear cache\"\"\"\n if confirm:\n self.poutput(\"Cache cleared\")\n else:\n self.poutput(\"Please add --confirm to proceed\")\n```\n\nUsage examples:\n```\n(Cmd) server db migrate v1.2.0\nMigrating to version v1.2.0...\n(Cmd) server cache clear --confirm \nCache cleared\n```\n\n### 4.4 Async Command Support\n\nNative async/await support for I/O bound operations:\n\n```python\nimport aiohttp\nfrom ptcmd import Cmd, auto_argument\n\nclass AsyncApp(Cmd):\n @auto_argument\n async def do_get(self, url: str):\n \"\"\"Fetch URL content\"\"\"\n async with aiohttp.ClientSession() as session:\n async with session.get(url) as resp:\n self.poutput(await resp.text(), markup=False)\n```\n\n## 5. Library Comparison\n\nThe following table compares the advantages and disadvantages of three libraries: cmd (standard library), cmd2, and ptcmd:\n\n| Feature | cmd | cmd2 | ptcmd |\n| ----------------------- | ------------- | ------------------------------- | ------------------------- |\n| **Feature Richness** | Basic | Most Feature-Rich | Moderately Feature-Rich |\n| **Learning Curve** | Simple | Medium | Medium |\n| **Interactive Experience** | Basic | Good | Excellent (based on `prompt_toolkit`) |\n| **Auto Completion** | None | Supported | Supported |\n| **Argument Parsing** | Manual Handling | Requires building `ArgumentParser` | Auto Parsing |\n| **Async Support** | None | None | Native Support |\n| **Rich Text Output** | None | Uses `cmd2.ansi` module | Uses `rich` library |\n| **Dependencies** | None | More | Most |\n| **Performance** | High | Medium | Medium |\n| **Use Case** | Simple CLI | Complex CLI | Modern CLI |\n\nKey Advantages:\n\n- **cmd**: Python standard library, no dependencies, suitable for simple CLI applications\n- **cmd2**: Comprehensive features, good community support, compatible with `cmd`, suitable for traditional CLIs requiring rich features\n- **ptcmd**: Provides the best interactive experience, native async support, suitable for modern CLI applications\n\n## 6. Related Projects\n\n- [prompt_toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) - Foundation for building powerful interactive command lines\n- [rich](https://github.com/Textualize/rich) - Enables rich text formatting and beautiful output\n- [typer](https://github.com/tiangolo/typer) - Modern CLI framework with type hints\n- [cmd2](https://github.com/python-cmd2/cmd2) - Inspiration for many ptcmd features\n- [argparse](https://docs.python.org/3/library/argparse.html) - Python's standard argument parsing library\n- [cmd](https://docs.python.org/3/library/cmd.html) - Python's standard line-oriented command interpreters library\n\n## 7. Special Thanks\n\n- [cmd2](https://github.com/python-cmd2/cmd2) for inspiring the command completion system\n- [Cline](https://cline.bot/) for assisting with project documentation and test cases\n\n## 8 License\n\nApache License 2.0 - See [LICENSE](LICENSE)\n",
"bugtrack_url": null,
"license": "Apache 2.0",
"summary": "A modern cmd library based on prompt_toolkit",
"version": "0.2.0",
"project_urls": {
"Homepage": "https://github.com/Visecy/ptcmd",
"source_archive": "https://github.com/org/repo/archive/faad76517c7b20e0cbe85fdd09e1f1f868e922af.zip"
},
"split_keywords": [
"python",
" cmd",
" interactive",
" prompt"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "a689345e1d5d1c85e47444168bdccd1db49ebb512950e15709be3c61dac9e68d",
"md5": "15f87e83953585d73cd5b52b514d0526",
"sha256": "9e7c9eceb72640d9d7ce54a9fe281e8fa46cfc67f365cb3d20f3f258b54d9dc8"
},
"downloads": -1,
"filename": "ptcmd-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "15f87e83953585d73cd5b52b514d0526",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 31051,
"upload_time": "2025-07-13T08:55:20",
"upload_time_iso_8601": "2025-07-13T08:55:20.795720Z",
"url": "https://files.pythonhosted.org/packages/a6/89/345e1d5d1c85e47444168bdccd1db49ebb512950e15709be3c61dac9e68d/ptcmd-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "0c495630021e8804ae5bd18f1136aae58e56e2306b10ba8462145d1a09106f0e",
"md5": "0c22c49a71ee30942e81e85ca4222a33",
"sha256": "c48306a2942afe996caa5b604b5124c459faa1f8084b70e6b1dbdcb6d5184aa2"
},
"downloads": -1,
"filename": "ptcmd-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "0c22c49a71ee30942e81e85ca4222a33",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 74033,
"upload_time": "2025-07-13T08:55:22",
"upload_time_iso_8601": "2025-07-13T08:55:22.189565Z",
"url": "https://files.pythonhosted.org/packages/0c/49/5630021e8804ae5bd18f1136aae58e56e2306b10ba8462145d1a09106f0e/ptcmd-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-13 08:55:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Visecy",
"github_project": "ptcmd",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "prompt_toolkit",
"specs": [
[
">=",
"3.0.0"
]
]
},
{
"name": "rich",
"specs": [
[
">=",
"13.0.0"
]
]
},
{
"name": "pygments",
"specs": [
[
">=",
"2.15.0"
]
]
},
{
"name": "typing_extensions",
"specs": [
[
">=",
"4.5.0"
]
]
},
{
"name": "ruff",
"specs": [
[
">=",
"0.9.0"
]
]
},
{
"name": "pytest",
"specs": [
[
">=",
"6.0.0"
]
]
},
{
"name": "pytest-asyncio",
"specs": [
[
">=",
"0.20.0"
]
]
},
{
"name": "coverage",
"specs": [
[
">=",
"7.2.0"
]
]
}
],
"lcname": "ptcmd"
}