Metadata-Version: 2.4
Name: argss
Version: 0.2.6
Summary: Write type-annotated Python functions, get a CLI with argparse's native `--help` — no magic, no bloat. Flat commands only, synchronous execution
Project-URL: Homepage, https://github.com/Fkernel653/argss
Project-URL: Repository, https://github.com/Fkernel653/argss.git
Project-URL: Documentation, https://github.com/Fkernel653/argss#readme
Author: Fkernel653
License-Expression: MIT
License-File: LICENSE
Keywords: argparse,cli,command-line,framework,lib,libraries,library,lightweight,mit-license
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Terminals
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: ruff; extra == 'dev'
Description-Content-Type: text/markdown

# argss — Stupidly Simple CLI builder

[![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://python.org)
[![PyPI](https://img.shields.io/pypi/v/argss.svg)](https://pypi.org/project/argss/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![Platform](https://img.shields.io/badge/platform-linux%20%7C%20macOS%20%7C%20windows-lightgrey)]()
[![Ruff](https://img.shields.io/badge/code%20style-ruff-261230?logo=ruff&logoColor=white)](https://docs.astral.sh/ruff/)

**argss** is a lightweight fork of [arg-kiss](https://github.com/Fkernel653/arg-kiss) — stripped down to the essentials.

Write type-annotated Python functions, get a CLI with argparse's native `--help` — no magic, no bloat. Flat commands only, synchronous execution.

## 🎯 Why argss?

| Feature | arg-kiss | argss |
|---------|----------|-------|
| `@cli.command()` | ✅ | ✅ |
| `@cli.argument()` | ✅ | ✅ |
| Type inference | ✅ | ✅ |
| Boolean flags | ✅ | ✅ |
| Global arguments | ✅ | ✅ |
| Command groups | ✅ | ❌ |
| Async support | ✅ | ❌ |
| `color` parameter (Python 3.14+ coloured help) | ✅ | ❌ |
| Dependencies | none | none |

Use **argss** when you want:
- Minimal code footprint
- No asyncio overhead
- Flat command structure (no sub-subcommands)
- Faster import time (~30% faster than arg-kiss)

## 🚀 Quick Start

```bash
pip install argss
```

```python
from argss import Argss

cli = Argss(name="todo", description="Task manager")

@cli.command()
def add(task: str, priority: int = 1, done: bool = False):
    """Add a task."""
    status = "✓" if done else "○"
    print(f"[{status}] {task} (priority: {priority})")

@cli.command()
def list_all():
    """Show all tasks."""
    print("Nothing yet!")

cli.run()
```

```bash
$ python todo.py add "Buy milk" --priority 2
[○] Buy milk (priority: 2)

$ python todo.py list-all
Nothing yet!

$ python todo.py --help
usage: todo [-h] {add,list-all} ...

Task manager

positional arguments:
  {add,list-all}
    add           Add a task.
    list-all      Show all tasks.

options:
  -h, --help      show this help message and exit
```

## 📋 Commands & Features

### `@cli.command()` — Define commands from functions

```python
@cli.command()
def fetch(url: str, retries: int = 3):
    """Download from URL with retries"""
    print(f"Fetched {url} (retries: {retries})")
```

### `@cli.argument()` — Customize command arguments

Override or add explicit arguments for a command. Multiple decorators can be stacked.

```python
@cli.argument("-u", "--uppercase", action="store_true", help="Shout it")
@cli.argument("-n", "--name", help="Your name")
@cli.command()
def greet(name: str, uppercase: bool = False):
    """Greet someone."""
    result = f"Hello, {name}!"
    return result.upper() if uppercase else result
```

```bash
$ python greet.py greet -n Alice -u
HELLO, ALICE!

$ python greet.py greet --help
usage: greet greet [-h] [-u] [-n NAME]

Greet someone.

options:
  -h, --help            show this help message and exit
  -u, --uppercase       Shout it
  -n NAME, --name NAME  Your name
```

### `@cli.argument()` — Override inferred argument

You can also override auto-inferred arguments by matching the parameter name via `dest`:

```python
@cli.argument("--output", dest="file", help="Output file")
@cli.command()
def process(file: str):
    """Process a file."""
    print(f"Processing {file}")
```

### Type → CLI mapping

| Function signature | CLI argument |
|--------------------|---------------|
| `name: str` | Positional `name` |
| `count: int = 1` | `--count 1` |
| `verbose: bool = False` | `--verbose` / `--no-verbose` |
| `mode: str \| None = None` | `--mode MODE` |

### Boolean flags control

The `boolean_optional` parameter controls how boolean flags are handled:

```python
# Default: boolean_optional=True — uses argparse.BooleanOptionalAction
cli = Argss(name="mycli", boolean_optional=True)

@cli.command()
def deploy(force: bool = False):
    """Deploy with optional force flag."""
    print(f"Deploying {'with force' if force else 'normally'}")

# Results in: --force / --no-force
```

```python
# boolean_optional=False — separate --flag and --no-flag
cli = Argss(name="mycli", boolean_optional=False)

@cli.command()
def deploy(force: bool = False):
    """Deploy with optional force flag."""
    print(f"Deploying {'with force' if force else 'normally'}")

# Results in: --force (sets True) and --no-force (sets False)
```

**Comparison:**

| `boolean_optional` | CLI interface | Example |
|-------------------|---------------|---------|
| `True` (default) | Single `--flag` with built-in negation | `--force` / `--no-force` |
| `False` | Two separate flags | `--force` (True) and `--no-force` (False) |

The default (`True`) is recommended for cleaner CLI design, while `False` provides explicit control for each state.

## 🎨 CLI Configuration

```python
cli = Argss(
    name="mycli",                       # Program name (default: None)
    description="Does amazing things",  # Description in help (default: None)
    version="2.0.0",                    # Adds --version flag (default: None)
    boolean_optional=True,              # Boolean flags behavior (default: True)
)
```

| Option | Description |
|--------|-------------|
| `name` | Program name in help (default: `None`) |
| `description` | Description in help (default: `None`) |
| `version` | Adds `--version` flag (default: `None`) |
| `boolean_optional` | Controls boolean flags behavior: `True` uses `BooleanOptionalAction` (default), `False` uses separate `--flag` and `--no-flag` |

### Global arguments

Share arguments across all commands:

```python
cli.add_global_argument("-v", "--verbose", action="store_true", help="Enable verbose output")

@cli.command()
def add(task: str):
    if cli._global_args:  # Access via parsed args
        print(f"Verbose: adding {task}")
    print(f"Added: {task}")
```

## 📄 License & Acknowledgments

MIT License — Built with Python standard library:

| Module | Purpose |
|--------|---------|
| `argparse` | CLI parsing engine |
| `inspect` | Signature introspection |

**Forked from:** [arg-kiss](https://github.com/Fkernel653/arg-kiss) by [Fkernel653](https://github.com/Fkernel653)

**argss author:** [Fkernel653](https://github.com/Fkernel653)

**Project:** [GitHub](https://github.com/Fkernel653/argss) • [PyPI](https://pypi.org/project/argss/)
