Skip to main content

Annotated command-line interfaces in Python

Project description

anci

anci is a lightweight python package that automatically converts decorated, type-annotated functions into basic or hierarchical command-line interfaces.

Installation

anci can be installed using pip

pip install anci

Or, added to your pyproject.toml using uv

uv add anci

Usage

Basic example

from anci import Arg, base, cmd, main

@base("ops")
def ops():
    """Base command for 'ops'."""
    pass

@cmd("ops", "add")
def ops_add(
    x: Arg[int],                 # A flagged argument with no help text
    y: Arg[int, "Second."],      # A flagged argument with help text
    z: Arg[int, "Third."] = 100  # A flagged argument with help text and a default value
):
    """Print the sum of three numbers."""
    print(x + y + z)

if __name__ == "__main__":
    main("A CLI tool for basic math operations.")

This example demonstrates how to create a simple CLI using only decorators and type annotations:

  • @anci.base("ops") - Creates a base command group called ops that initializes a hierarchy.
  • @anci.cmd("ops", "add") - Registers subcommand add under ops with flagged arguments.
  • usage - Usage info for each command (e.g. ops --help) are extracted from function docstrings.
  • anci.Arg - Provides type hints and help text for each parameter.
  • anci.main() - Automatically generates the CLI with help text, argument parsing, and command routing.

On the command-line, the anci command-line program can then be called as

python3 main.py ops add --help 
... usage: A CLI tool for basic math operations. ops add [-h] [--x X] [--y Y] [--z Z]
... 
... Print the sum of three numbers.
...
... options:
...   -h, --help  show this help message and exit
...   --x X
...   --y Y       Second.
...   --z Z       Third (default: 100).

python3 main.py ops add --x 2 --y 4
... 116

python3 main.py ops add --x 2 --y 4 --z 4
... 10

Or, if integrated as part of your python CLI package, then

package ops add --x 5 --y 3 --z 10
... 118

Annotated example

anci currently provides support for various annotated_types, allowing automatic enforcement of range and boundary checks on integers, containers (such as lists, sets, and tuples), and strings.

from anci import Arg, cmd, main
from anci.typing import Annotated, Gt, MaxLen

@cmd("types")
def ops_add(
    x: Arg[list[str], "A list of strings."],
    y: Arg[Annotated[int, Gt(10)], "An integer greater than 10"],
    z: Arg[Annotated[set[float], MaxLen(2)], "A set of floats with a max of 2 elements"],
):
    """Print the types of each argument."""
    print("type length")
    print(type(x), len(x))
    print(type(y), 1)
    print(type(z), len(z))

if __name__ == "__main__":
    main("A CLI for checking types.")

This example shows how anci uses type annotations to handle complex types and enforce runtime checks:

  • x: Arg[list[str], ...] - anci converts a sequence of letters into list of strings.
  • y: Arg[Annotated[int, Gt(10)], ...]: anci verifies input integer is greater than 10.
  • y: Arg[Annotated[set[float], MaxLen(2)], ...]: anci verifies set only has two elements.

When all arguments satisfy the runtime checks, the command runs without errors:

python main.py types --x a b c --y 11 --z 1
... type length
... <class 'list'> 3
... <class 'int'> 1
... <class 'set'> 1

However, since anci enforces range/length constraints directly from type annotations, the following produce errors:

python main.py types --x a b c --y 5 --z 1
... types: error: argument --y: y must be > 10, got 5

python main.py types --x a b c --y 11 --z 1 2 3
... types: error: argument --z: Expected at most 2 elements, got 3

Supported type annotations

anci currently supports the following type annotations:

  • Base types: int, str, float, bool, bytes, pathlib.Path
  • Container types: list[...], List[...], tuple[...], Tuple[...], set[...], Set[...]
  • annotated_types (typing.Annotated[...]): Gt, Ge, Lt, Le, Interval, MaxLen, MinLen, Len.

All annotated types, and pathlib.Path, can be directly imported/aliased from anci.typing if desired.

Adding custom type annotations

If you want to add your new/custom type annotations to anci, see src/anci/handlers for now or, alternatively, open an issue. Documentation on adding your own custom annotations will be added soon.

Other CLI frameworks

  • argparse - Base of anci and reliable for small scripts but very verbose otherwise.
  • click - Too. Many. Decorators. Not much else to say.
  • typer - Mature ecosystem, "type-aware" but doesn't fully take advantage of type annotations (for example, see typer's use of Annotated).

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

anci-0.1.1.tar.gz (108.0 kB view details)

Uploaded Source

Built Distribution

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

anci-0.1.1-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

Details for the file anci-0.1.1.tar.gz.

File metadata

  • Download URL: anci-0.1.1.tar.gz
  • Upload date:
  • Size: 108.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.4

File hashes

Hashes for anci-0.1.1.tar.gz
Algorithm Hash digest
SHA256 ef1b6fe46178a51b1d808b10941fb6a195540237355e9f9ba0fb974fe14d4567
MD5 4379bf99049e9e8518083b982ef78bde
BLAKE2b-256 87e35867d12461ce7e47c2bae66dae9d6ed57f574db09d5391e32edfcbe02646

See more details on using hashes here.

File details

Details for the file anci-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: anci-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 19.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.4

File hashes

Hashes for anci-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dac5529735881d965e4b0014e8f9d78cdf1ea1c35ad80e9229248c071bfa19aa
MD5 90168d9d2861f2b9ff4d1d2e12be7150
BLAKE2b-256 abb7e18eb9dde88a379082d99f17eeb3c5d8b9446a4f89e8b30c6f53346f4db4

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