Skip to main content

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

Metadata

Release files for ekta-chalk 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for ekta-chalk 0.1.0
File Interpreter ABI Platform
ekta_chalk-0.1.0-py3-none-any.whl Python 3 none any Details

Release files / ekta_chalk-0.1.0-py3-none-any.whl

Download URL ekta_chalk-0.1.0-py3-none-any.whl
Size 7.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
84b56c254dbf24549be58899ea0d585656daddd1f7dd6d16a0e1de668fb33579
BLAKE2b-256 checksum
How to use checksums
6ca71d272d5db7f8e268adf56d329919570c86b4e350b67bcc388abcf519d793
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.1.0 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page