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)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|