# Creating CLIs with Click

## Quick Start
```python
import click
from your_library import process_data

@click.command()
@click.argument('input_file', type=click.Path(exists=True))
@click.option('--format', '-f', default='json', help='Output format')
@click.option('--verbose', '-v', is_flag=True, help='Verbose output')
def cli(input_file, format, verbose):
    """Process a data file."""
    try:
        result = process_data(input_file, format=format)
        click.echo(f"✓ Processed {len(result)} records")
    except Exception as e:
        click.echo(f"✗ Error: {e}", err=True)
        raise click.ClickException(str(e))
```

## Multi-Command CLI
```python
@click.group()
@click.option('--debug/--no-debug', default=False)
@click.pass_context
def cli(ctx, debug):
    """My awesome CLI tool."""
    ctx.ensure_object(dict)
    ctx.obj['DEBUG'] = debug

@cli.command()
@click.argument('name')
def greet(name):
    """Greet someone."""
    click.echo(f"Hello {name}!")

@cli.command()
@click.option('--count', '-c', default=1, help='Number of times')
def repeat(count):
    """Repeat a message."""
    for _ in range(count):
        click.echo("Message")
```

## Common Patterns

### 1. Progress Bars
```python
@click.command()
def process():
    items = get_items()
    with click.progressbar(items, label='Processing') as bar:
        for item in bar:
            process_item(item)
```

### 2. Confirmation Prompts
```python
@click.command()
@click.confirmation_option(prompt='Are you sure?')
def delete():
    """Delete all data."""
    delete_everything()
```

### 3. File I/O
```python
@click.command()
@click.argument('input', type=click.File('r'))
@click.argument('output', type=click.File('w'))
def convert(input, output):
    """Convert file format."""
    data = process(input.read())
    output.write(data)
```

### 4. Error Handling
```python
def handle_errors(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except ValidationError as e:
            click.echo(f"✗ Validation error: {e}", err=True)
            raise click.ClickException("Invalid input")
        except NetworkError as e:
            click.echo(f"✗ Network error: {e}", err=True)
            raise click.ClickException("Connection failed")
    return wrapper

@click.command()
@handle_errors
def risky_command():
    """Command that might fail."""
    do_risky_operation()
```

### 5. Configuration Files
```python
@click.command()
@click.option('--config', type=click.Path(),
              default='~/.myapp/config.json',
              help='Config file path')
def app(config):
    """App with config file."""
    config_path = Path(config).expanduser()
    if config_path.exists():
        settings = json.loads(config_path.read_text())
        apply_settings(settings)
```

## Best Practices
1. Use `click.echo()` instead of `print()`
2. Provide helpful `--help` text
3. Use appropriate exit codes (0=success, 1+=error)
4. Keep CLI layer thin - delegate to library
5. Add `--verbose` and `--quiet` options
6. Use colors sparingly: `click.style(text, fg='green')`
