Skip to main content

A simple command-line argument parser inspired by Commander.js

Project description

ekta_chalk

A simple, elegant command-line argument parser for Python inspired by Commander.js.

Installation

pip install ekta_chalk

Quick Start

from ekta_chalk import Program

program = Program()
program.name("greet")
program.version("1.0.0")
program.description("A friendly greeting CLI")

program.option("-n, --name <name>", "Name to greet", "World")
program.option("-l, --loud", "Greet loudly")

@program.action
def main(options):
    greeting = f"Hello, {options.name}!"
    if options.loud:
        greeting = greeting.upper()
    print(greeting)

program.parse()
$ python greet.py --name Alice --loud
HELLO, ALICE!

$ python greet.py --help
Usage: greet [options]

A friendly greeting CLI

Options:
  -n, --name <name>       Name to greet (default: World)
  -l, --loud              Greet loudly
  -h, --help              Display help for command
  -V, --version           Output the version number

Features

  • Fluent, chainable API
  • Automatic help generation
  • Options with short and long flags
  • Required and optional arguments
  • Subcommands
  • Variadic arguments
  • Type hints included

API

Options

Add options with short (-s) and/or long (--long) flags:

program.option("-d, --debug", "Enable debug mode")
program.option("-c, --config <path>", "Path to config file")
program.option("-o, --output <file>", "Output file", "out.txt")  # with default
program.required_option("-k, --key <key>", "API key (required)")

Options that take values use <value> syntax. Without a value placeholder, options are boolean flags.

Arguments

Add positional arguments:

program.argument("<file>", "Input file (required)")
program.argument("[output]", "Output file (optional)")
program.argument("<files...>", "Multiple input files (variadic)")
  • <name> - Required argument
  • [name] - Optional argument
  • <name...> - Variadic (collects remaining args as list)

Subcommands

Create subcommands for complex CLIs:

from ekta_chalk import Program

program = Program()
program.name("git-clone")
program.version("1.0.0")

# Add a subcommand
clone = program.command("clone", "Clone a repository")
clone.argument("<repo>", "Repository URL")
clone.option("-b, --branch <branch>", "Branch to clone", "main")

@clone.action
def clone_action(repo, options):
    print(f"Cloning {repo} (branch: {options.branch})")

# Add another subcommand
init = program.command("init", "Initialize a repository")
init.option("--bare", "Create a bare repository")

@init.action
def init_action(options):
    print(f"Initializing {'bare ' if options.bare else ''}repository")

program.parse()
$ python git-clone.py clone https://github.com/user/repo -b develop
Cloning https://github.com/user/repo (branch: develop)

$ python git-clone.py init --bare
Initializing bare repository

Action Handlers

The action handler receives positional arguments in order, followed by an Options object:

program.argument("<input>", "Input file")
program.argument("[output]", "Output file")
program.option("-v, --verbose", "Verbose output")

@program.action
def main(input_file, output_file, options):
    print(f"Input: {input_file}")
    print(f"Output: {output_file}")
    print(f"Verbose: {options.verbose}")

Command Aliases

Add aliases for subcommands:

install = program.command("install", "Install packages")
install.alias("i")  # Now 'myapp i' works like 'myapp install'

Complete Example

from ekta_chalk import Program

program = Program()
program.name("file-tool")
program.version("2.0.0")
program.description("A file manipulation tool")

# Global options
program.option("-v, --verbose", "Enable verbose output")

# Copy command
copy = program.command("copy", "Copy files")
copy.alias("cp")
copy.argument("<source>", "Source file")
copy.argument("<dest>", "Destination")
copy.option("-f, --force", "Overwrite existing files")

@copy.action
def copy_files(source, dest, options):
    print(f"Copying {source} to {dest}")
    if options.force:
        print("(overwriting if exists)")

# List command
ls = program.command("list", "List directory contents")
ls.alias("ls")
ls.argument("[dir]", "Directory to list", ".")
ls.option("-a, --all", "Show hidden files")

@ls.action
def list_dir(directory, options):
    print(f"Listing {directory}")
    if options.all:
        print("(including hidden files)")

program.parse()

Requirements

  • Python 3.10+

License

MIT

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

ekta_chalk-0.1.0-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

Details for the file ekta_chalk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ekta_chalk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for ekta_chalk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 84b56c254dbf24549be58899ea0d585656daddd1f7dd6d16a0e1de668fb33579
MD5 2444fa8bdc380f3648ebc7d9d4161a33
BLAKE2b-256 6ca71d272d5db7f8e268adf56d329919570c86b4e350b67bcc388abcf519d793

See more details on using hashes here.

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