Skip to main content

Command aliases for Typer CLI applications

Project description

CI codecov PyPI License: MIT

typer-extensions

Command aliases for Typer CLI applications with grouped help text display

Overview

Typer is great, but it could be even better!

typer-extensions extends Typer to provide simple drop-in support for command aliases. Instead of duplicating commands, hiding commands, or maintaining wrapper functions, define aliases directly and have them displayed cleanly in help text.

100% backwards compatible with Typer & existing Typer apps!

The Problem

Standard Typer requires duplicating or hiding commands to create aliases:

from typer import Typer

app = Typer()

@app.command()
def list_items():
    """List all items."""
    print("Listing...")

# Registered as separate command, hidden in help
@app.command("ls", hidden=True)
def ls_items():
    list_items()

@app.command("l")("list")  # Duplicate!

Help output:

Commands:
  list      List all items.
  l         List all items.

Issues:

  • Code duplication
  • Help text shows commands & aliases separately
  • Hidden 'aliases' not shown in help text
  • Maintenance burden

The Solution

With typer-extensions:

from typer_extensions import ExtendedTyper

app = ExtendedTyper()

@app.command_with_aliases("list", aliases=["ls", "l"])
def list_items():
    """List all items."""
    print("Listing...")

Help output:

Commands:
  list (ls, l)  List all items.

All work identically:

app list
app ls
app l

Features

Decorator-based alias registration - Clean, intuitive syntax

🔧 Programmatic API - Dynamic alias management at runtime

📋 Grouped help display - Aliases shown with their primary command

⚙️ Highly configurable - Customise format, separators, truncation

🎯 Type-safe - Full type hints and editor support

🔄 Fully backwards compatible - Works with all Typer/Click features and existing Typer apps

Shell completion ready - Alias support doesn't interfere with existing shell completion

🧪 Well-tested - Tested on Python 3.9-3.14 with 100% test coverage


Installation

pip install typer-extensions

[!NOTE] Requirements:

  • Python 3.9+
  • typer >= 0.9.0 (recommend installing the latest version)
  • click >= 8.0.0

Quick Start

Basic Usage

from typer_extensions import ExtendedTyper

app = ExtendedTyper()

@app.command_with_aliases("list", aliases=["ls", "l"])
def list_items():
    """List all items."""
    print("Listing items...")

@app.command_with_aliases("delete", aliases=["rm", "remove"])
def delete_item(name: str):
    """Delete an item."""
    print(f"Deleting {name}")

if __name__ == "__main__":
    app()

Run it:

$ python app.py --help
Commands:
  list (ls, l)         List all items.
  delete (rm, remove)  Delete an item.

$ python app.py ls
Listing items...

$ python app.py rm test.txt
Deleting test.txt

[!TIP] Want to learn more? Check the API Reference for detailed configuration options, or see the User Guide for patterns and best practices.

Drop-in Compatibility

Have an existing Typer project? Add alias support without changing your code:

# Before (regular Typer)
from typer import Typer
app = Typer()

# After (with typer-extensions)
from typer_extensions import ExtendedTyper
app = ExtendedTyper()

# That's it! Everything else stays the same.
# Existing commands, shell completion and help text configuration still work exactly as before.

Once migrated, you can add aliases to new commands using @app.command_with_aliases(), or to existing commands using the programmatic API.

[!TIP] See Migration Guide for detailed migration strategies and patterns.

Advanced Features

Programmatic alias management:

# Add aliases dynamically
app.add_alias("list", "dir")

# Remove aliases
app.remove_alias("dir")

# Query aliases
aliases = app.get_aliases("list")  # ["ls", "l"]

Custom help formatting:

app = ExtendedTyper(
    alias_display_format="[{aliases}]",   # Use brackets
    alias_separator=" | ",                # Pipe separator
    max_aliases_inline=2,                 # Show max 2, then "+N more"
)

Configuration-based aliases:

# Load aliases from config
config = {"list": ["ls", "l", "dir"]}
for cmd, aliases in config.items():
    for alias in aliases:
        app.add_alias(cmd, alias)

Documentation

📚 User Guide - Tutorials and common patterns

📖 API Reference - Complete API documentation

🔄 Migration Guide - Migrating from standard Typer


Examples

All examples are in the examples/ directory:

Run any example:

python examples/basic_usage.py --help
python examples/basic_usage.py ls

Real-World Use Cases

Git-like CLI

@app.command_with_aliases("checkout", aliases=["co"])
def checkout(branch: str):
    """Switch branches."""
    ...

@app.command_with_aliases("status", aliases=["st"])
def status():
    """Show status."""
    ...

Package Manager

@app.command_with_aliases("install", aliases=["i", "add"])
def install(package: str):
    """Install a package."""
    ...

@app.command_with_aliases("remove", aliases=["rm", "uninstall"])
def remove(package: str):
    """Remove a package."""
    ...

Cross-Platform Commands

@app.command("list")
def list_files():
    """List files."""
    ...

# Add platform-specific aliases
if platform.system() == "Windows":
    app.add_alias("list", "dir")
else:
    app.add_alias("list", "ls")

API Overview

Decorator Registration

@app.command_with_aliases(name, aliases=[...])

Programmatic Registration

app.add_aliased_command(func, name, aliases=[...])

Alias Management

app.add_alias(command, alias)            # Add alias
app.remove_alias(alias)  bool           # Remove alias
app.get_aliases(command)  list          # Query aliases
app.list_commands_with_aliases()  dict  # All mappings

Configuration

ExtendedTyper(
    alias_case_sensitive=None,           # Case-sensitive (default True, matching Typer)
    show_aliases_in_help=True,           # Display aliases in help
    alias_display_format="({aliases})",  # Display format
    alias_separator=", ",                # Between aliases
    max_num_aliases=3,                   # Before truncation
)

Development

Setup

Standard setup with pip:

git clone https://github.com/rdawebb/typer-extensions.git
cd typer-extensions
python -m venv venv
source venv/bin/activate  # or venv\Scripts\activate on Windows
pip install -e ".[dev]"

Or with uv (recommended):

git clone https://github.com/rdawebb/typer-extensions.git
cd typer-extensions
uv sync --all-extras
source .venv/bin/activate

Quick commands with justfile:

If you have just installed (included in [dev]), common tasks are available:

just test          # Run tests
just lint          # Run linter
just format        # Format code
just type          # Check type safety
just test-cov      # Full test suite with coverage
just help          # List all available commands

[!NOTE] If you prefer to use just without the dev setup, you can install it globally via pip install rust-just or your system package manager.

[!TIP] See Justfile for all available commands.

Testing

With justfile (recommended):

just check       # Run linting, formatting, and type checks
just test        # Run tests
just test-cov    # Run tests with coverage report
just pre         # Full pre-commit check (all checks + tests)

Or with direct commands:

pytest                   # Run all tests
pytest --cov             # With coverage
pytest -v                # Verbose output
ruff check .             # Lint
ruff format .            # Format
ty check src/            # Type check

Contributing

Contributions are welcome! Please open an issue, ask a question, or submit a pull request.


Project Status

Current Version: 0.2.1 (Beta)

Core Features Complete:

  • Alias registration (decorator + programmatic)
  • Help text formatting
  • Dynamic alias management
  • Full test coverage

🚧 In Development:

  • Dynamic config file loading with import/export
  • Shell completion enhancement and typo suggestions
  • Documentation site
  • Performance optimisations

📋 Planned Features:

  • Shared & chained subcommand aliases
  • Per-alias help text
  • Dataclass, Pydantic & Attrs support
  • Custom themes and help text formatting
  • Argument & Option customisation

[!NOTE] See CHANGELOG.md for version history.


Why typer-extensions?

For Users:

  • ⚡ Faster workflows with short aliases
  • 🎯 Familiar commands (git-like shortcuts)
  • 📖 Clear help text showing all options

For Developers:

  • 🧹 DRY - no code duplication
  • 🔧 Flexible - static or dynamic aliases
  • 🎨 Customisable - match your style
  • ✅ Tested - reliable, stable, and type-safe

Compared to Alternatives:

  • Plain Typer: Requires command duplication or hiding
  • click-aliases: Click-specific, no Typer integration
  • Custom solutions: Reinventing the wheel

Related Projects

  • Typer - The CLI framework this extends
  • Click - The underlying library
  • Rich - Beautiful terminal formatting (used by Typer)

License

MIT License - see LICENSE file for details.


Acknowledgments

Built on the excellent Typer framework by Sebastián Ramírez.

Inspired by Git's command aliasing and various CLI tools that make shortcuts feel natural.


Support


Links


Making CLI aliases natural and maintainable

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

typer_extensions-0.2.2.tar.gz (34.2 kB view details)

Uploaded Source

Built Distribution

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

typer_extensions-0.2.2-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file typer_extensions-0.2.2.tar.gz.

File metadata

  • Download URL: typer_extensions-0.2.2.tar.gz
  • Upload date:
  • Size: 34.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for typer_extensions-0.2.2.tar.gz
Algorithm Hash digest
SHA256 1c2f17fc4e26cd4013ef6a30ecf0403ef331990a5a910fd124671ae4496afe7a
MD5 ba563bafe98949cd5c5f4dbb24aeed6f
BLAKE2b-256 3bc70d37b0b2a077722a36ad8aba044d43fa244bc70460137450a1427521a895

See more details on using hashes here.

File details

Details for the file typer_extensions-0.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for typer_extensions-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6510b90fa87b25088bc24cd693b9294d1eb96460991a6b0451e18d17ac68b335
MD5 0e0d3bc680ac1c4a0211e17c8aff2f42
BLAKE2b-256 deeb4945c731a0102cfa386341e064a50b69292ddb1dd660f14496021ba573e5

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