Skip to main content

A modern cmd library based on prompt_toolkit

Project description

ptcmd

License PyPI Build Status PyPI - Downloads Python Version

A modern interactive command-line application building library based on prompt_toolkit

Language: English/中文

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:

pip install ptcmd

Or install from source:

git clone https://github.com/Visecy/ptcmd.git
cd ptcmd
make install

3. Quick Start

Create a simple command-line application:

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:

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:

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:

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:
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
  1. Multi-level subcommand example:
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:

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

Feature cmd (stdlib) cmd2 ptcmd
Rich Output No Basic Rich library support
Auto Completion No Yes Yes
Argument Parsing Manual argparse Automatic
Async Support No No Native
Dependencies None Several Most
Learning Curve Simple Moderate Moderate
Use Case Simple CLI Traditional CLI Modern Interactive CLI

Key Advantages:

  • cmd: Standard library, no dependencies
  • cmd2: Feature-rich traditional CLI
  • ptcmd: Modern interactive experience with best-in-class UX

6. Related Projects

  • prompt_toolkit - Foundation for building powerful interactive command lines
  • rich - Enables rich text formatting and beautiful output
  • typer - Modern CLI framework with type hints
  • cmd2 - Inspiration for many ptcmd features
  • argparse - Python's standard argument parsing library
  • cmd - Python's standard line-oriented command interpreters library

7. Special Thanks

  • cmd2 for inspiring the command completion system
  • Cline for assisting with project documentation and test cases

8 License

Apache License 2.0 - See LICENSE

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ptcmd-0.1.2.tar.gz (71.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ptcmd-0.1.2-py3-none-any.whl (30.0 kB view details)

Uploaded Python 3

File details

Details for the file ptcmd-0.1.2.tar.gz.

File metadata

  • Download URL: ptcmd-0.1.2.tar.gz
  • Upload date:
  • Size: 71.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for ptcmd-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c2ad80014c9bd10bb34d1e70d76cdca95c6fe2a7e0990e3b3d36ac47d5ab0fe3
MD5 412ecc598aa86c5e2db0715bd6a246f4
BLAKE2b-256 6decda5efe9fc9d76ab04f6f6798580688014ee80242eaf3a339f621a6dafdeb

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptcmd-0.1.2.tar.gz:

Publisher: python-publish.yml on Visecy/ptcmd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ptcmd-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: ptcmd-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 30.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for ptcmd-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 8b12f131b098deb5afa53230e14be01348f7534d70139d3ee330a399ff0f938c
MD5 b4fe7cd982f6d9410b21d0af18beaba4
BLAKE2b-256 4fe74cb51a8852cb33750b3d600b66a59cc8e06f08e041154fe7070e3b13274a

See more details on using hashes here.

Provenance

The following attestation bundles were made for ptcmd-0.1.2-py3-none-any.whl:

Publisher: python-publish.yml on Visecy/ptcmd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page