# Your first CLI

To get started with `tyro`, let's compare it with a traditional `argparse`-based command-line
interface:

```python
"""Sum two numbers from argparse."""
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--a", type=int, required=True)
parser.add_argument("--b", type=int, default=3)
args = parser.parse_args()

total = args.a + args.b

print(total)
```

This is dramatically cleaner than manually parsing `sys.argv`, but has several
issues:

- It requires significant parsing-specific boilerplate.
- It lacks type checking and IDE support (no jumping to definitions, finding
  references, docstrings, refactoring or renaming tools).
- It becomes difficult to manage for larger projects with many parameters.
- It doesn't automatically generate comprehensive help text.

:func:`tyro.cli()` aims to solve these issues by building CLIs directly from type annotations.

## Command-line interfaces from functions

We can write the same script as above using `tyro.cli()`:

```python
"""Sum two numbers by calling a function with tyro."""
import tyro

def add(a: int, b: int = 3) -> int:
    """Add two numbers together.

    Args:
        a: First number to add.
        b: Second number to add. Defaults to 3.
    """
    return a + b

# Populate the inputs of add(), call it, then return the output.
total = tyro.cli(add)

print(total)
```

Using this script from the command line would look like:

```
$ python script.py --a 5
8

$ python script.py --a 5 --b 7
12

$ python script.py --help
usage: script.py [-h] --a INT [--b INT]

Add two numbers together.

╭─ options ───────────────────────────────────────────────────────────╮
│ -h, --help        show this help message and exit                   │
│ --a INT           First number to add. (required)                   │
│ --b INT           Second number to add. Defaults to 3. (default: 3) │
╰─────────────────────────────────────────────────────────────────────╯
```

A more succinct version that combines the function call with printing:

```python
"""Sum two numbers by calling a function with tyro."""
import tyro

def add(a: int, b: int = 3) -> None:
    """Add two numbers together and print the result."""
    print(a + b)

tyro.cli(add)  # Parses arguments, calls add(), and returns None.
```

## Command-line interfaces from config objects

A class in Python can be treated as a function that returns an instance. This is
particularly useful for more complex configurations:

```python
"""Sum two numbers by instantiating a dataclass with tyro."""
from dataclasses import dataclass

import tyro

@dataclass
class Args:
    """Configuration for adding two numbers."""

    a: int  # First number to add
    b: int = 3  # Second number to add (default: 3)

args = tyro.cli(Args)
print(args.a + args.b)
```

From the command line, this would look identical to the function example:

```
$ python script.py --a 5
8

$ python script.py --help
usage: script.py [-h] --a INT [--b INT]

Configuration for adding two numbers.

╭─ options ────────────────────────────────────────────────────────╮
│ -h, --help        show this help message and exit                │
│ --a INT           First number to add (required)                 │
│ --b INT           Second number to add (default: 3) (default: 3) │
╰──────────────────────────────────────────────────────────────────╯
```

## Benefits over `argparse`

Unlike directly using `argparse`, both the function-based and dataclass-based
approaches provide:

1. **Static type checking** - Parameters have real types that can be checked.
2. **IDE support** - Jump to definitions, find references, see docstrings, and use refactoring tools.
3. **Automatic helptext** - Generated from docstrings and comments.
4. **Less boilerplate** - No need to manually define every argument.
5. **Hierarchical configuration** - Easily nest parameters in complex structures.

By incorporating standard type annotations, tyro can handle a broad range of advanced behaviors:
nested structures, variable-length inputs, unions over types, subcommands, and more.
Our examples walk through these features in detail.
