Skip to main content

Automatic command-line interface generation for Python functions using type hints and docstrings

Project description

aap

PyPI version Coverage

Automatic command-line interface generation for Python functions using type hints and docstrings.

Overview

aap is a Python package that automatically generates command-line interfaces from Python functions. It leverages type hints to determine argument types and parses docstrings to provide helpful descriptions, eliminating the need to manually write argparse boilerplate code.

Features

  • Automatic CLI generation from function signatures
  • Type inference from Python type hints (str, int, float, bool, List, Optional)
  • Help text extraction from docstrings (Google, NumPy, and reStructuredText styles)
  • Support for default values and optional parameters
  • Boolean flags with automatic handling
  • Sequence mode (list): Execute multiple functions in order with merged parameters
  • Command mode (set): Create subcommands for different operations
  • Automatic conflict resolution for parameter names in sequences
  • Warning system for missing type annotations

Installation

pip install aap2

Or with uv:

uv pip install aap2

Quick Start

Single Function CLI

from aap import autoarg

def greet(name: str, age: int, greeting: str = "Hello"):
    """Greet a person.
    
    Args:
        name: Person's name
        age: Person's age
        greeting: Greeting message to use
    """
    return f"{greeting} {name}, you are {age} years old"

if __name__ == "__main__":
    cli = autoarg(greet)
    result = cli()
    print(result)

Run it:

python script.py --name Alice --age 30
# Output: Hello Alice, you are 30 years old

python script.py --name Bob --age 25 --greeting Hi
# Output: Hi Bob, you are 25 years old

Sequence of Functions (List)

Execute multiple functions in order with a single flat CLI. All parameters are merged, and conflicting names are automatically prefixed with the function name.

from aap import autoarg

def fetch_data(url: str, timeout: int = 30):
    """Fetch data from URL.
    
    Args:
        url: URL to fetch from
        timeout: Request timeout in seconds
    """
    return f"Fetched from {url}"

def process_data(format: str = "json"):
    """Process the fetched data.
    
    Args:
        format: Output format
    """
    return f"Processed as {format}"

if __name__ == "__main__":
    # Default: returns last result (unix-style)
    cli = autoarg([fetch_data, process_data])
    result = cli()
    print(result)
    
    # Or get all results as a list
    cli = autoarg([fetch_data, process_data], return_type="list")
    results = cli()
    print(results)  # [result1, result2]
    
    # Or get results as a dict
    cli = autoarg([fetch_data, process_data], return_type="dict")
    results = cli()
    print(results)  # {"fetch_data": result1, "process_data": result2}

Run it:

python script.py --url https://api.example.com --timeout 60 --format xml
# Executes both functions in order

Handling Parameter Conflicts

When multiple functions share parameter names, they are automatically prefixed:

def step1(name: str, count: int):
    """First step."""
    return f"Step1: {name} x {count}"

def step2(name: str, value: float):
    """Second step."""
    return f"Step2: {name} = {value}"

cli = autoarg([step1, step2])

Run it:

python script.py --step1-name Alice --count 5 --step2-name Bob --value 3.14

Command Mode (Set)

Create subcommands for different operations (like git, docker, etc.):

from aap import autoarg

def add(a: int, b: int):
    """Add two numbers.
    
    Args:
        a: First number
        b: Second number
    """
    return a + b

def multiply(a: int, b: int):
    """Multiply two numbers.
    
    Args:
        a: First number
        b: Second number
    """
    return a * b

if __name__ == "__main__":
    # Use a set for commands
    cli = autoarg({add, multiply})
    result = cli()
    print(result)

Run it:

python script.py add --a 5 --b 3
# Output: 8

python script.py multiply --a 5 --b 3
# Output: 15

Supported Types

  • Basic types: str, int, float, bool
  • Optional types: Optional[T] for optional parameters
  • List types: List[T] for multiple values
  • Default values: Automatically detected from function signatures

Boolean Flags

Boolean parameters are automatically converted to flags:

def process(name: str, verbose: bool = False, enabled: bool = True):
    """Process with flags.
    
    Args:
        name: Item name
        verbose: Enable verbose output
        enabled: Whether processing is enabled
    """
    pass

Usage:

# verbose defaults to False, use --verbose to set True
python script.py --name test --verbose

# enabled defaults to True, use --no-enabled to set False
python script.py --name test --no-enabled

Docstring Support

autoarg supports multiple docstring formats:

Google Style

def func(param1: str, param2: int):
    """Function description.
    
    Args:
        param1: Description of param1
        param2: Description of param2
    """
    pass

NumPy Style

def func(param1: str, param2: int):
    """Function description.
    
    Parameters
    ----------
    param1 : str
        Description of param1
    param2 : int
        Description of param2
    """
    pass

reStructuredText Style

def func(param1: str, param2: int):
    """Function description.
    
    :param param1: Description of param1
    :param param2: Description of param2
    """
    pass

Advanced Example

from typing import List, Optional
from aap import autoarg

def backup_database(
    host: str,
    database: str,
    output_file: str,
    port: int = 5432,
    username: Optional[str] = None,
    compress: bool = True,
    tables: Optional[List[str]] = None
):
    """Backup a PostgreSQL database.
    
    Args:
        host: Database host
        database: Database name
        output_file: Output backup file path
        port: Database port
        username: Database username
        compress: Compress the backup file
        tables: Specific tables to backup
    """
    # Implementation here
    pass

if __name__ == "__main__":
    cli = autoarg(backup_database)
    cli()

Usage:

# Basic backup
python backup.py --host localhost --database mydb --output-file backup.sql

# Advanced backup with options
python backup.py --host db.example.com --database prod \
    --output-file backup.sql --port 3306 --username admin \
    --no-compress --tables users orders products

Type Annotations

Type hints are required for proper CLI generation. If a parameter lacks a type annotation, autoarg will issue a warning and default to str type:

def func(typed_param: int, untyped_param):
    pass
# Warning: Parameter 'untyped_param' has no type annotation. Defaulting to str type.

Development

Running Tests

pytest tests/ -v --cov=autoarg --cov-report=term-missing

Building the Package

python -m build

License

MIT License

Contributing

Contributions are welcome. Please ensure all tests pass and maintain 100% code coverage for new features.

Generative Artificial Intelligence Disclosure

This package was created using Cline and claude-sonnet-4-5 starting from the following prompt:

Create a python package in this directory called aap. Auto arg parse has one functionality. That functionality is to take a callable or a list of callables and return another call, which wraps the input callable and uses python built-in argparse library to receive all input parameters to the call from command line input. Use the python type hints to figure out the type of the input parameters, and use the callable's documentation to figure out descriptions or help messages for the parameters. Throw a warning if a input parameter is not typed. If there are multiple callables passed to aap, create commands for each, with their own parameters parsed.

Create a professional concise read me with no emojis.

Create tests that use pytest and have a coverage of 100%.

Create a pyproject.toml and package for pypi for distribution through pip or uv.

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

aap2-0.2.0.tar.gz (20.4 kB view details)

Uploaded Source

Built Distribution

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

aap2-0.2.0-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

File details

Details for the file aap2-0.2.0.tar.gz.

File metadata

  • Download URL: aap2-0.2.0.tar.gz
  • Upload date:
  • Size: 20.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for aap2-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2cdce9b0fb4a0ed14bbc3bf049885118f7e2684c42f23da0f1019013956b3c95
MD5 9c6df3d62c9ea58226384d4483f737d8
BLAKE2b-256 3e71edeff34fd9f7bda5ac467f29ab2a566ea487d67d53da0f75e4809b157e14

See more details on using hashes here.

File details

Details for the file aap2-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: aap2-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 10.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for aap2-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3486d168366299787962c5946504b40a7ce478f4cec434d90a6e0c14dc3f03ad
MD5 f747eaa929ef9e599a72006641c9b6ba
BLAKE2b-256 fb08a7e953e667df2e050cbf4c9cfa87f17ce0eb89be05be55b729545cd524c5

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