# How Pyutube Handles Command-Line Arguments: Inside the Typer CLI Architecture

> Learn how Pyutube handles command line arguments using Typer and declarative type hints in pyutube cli.py Map arguments to download workflows easily.

- Repository: [Ebraheem Alhetari/pyutube](https://github.com/hetari/pyutube)
- Tags: internals
- Published: 2026-03-03

---

**Pyutube leverages the Typer library to parse command-line arguments through declarative type hints in [`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py), automatically mapping positional arguments and optional flags to download workflows.**

Pyutube is an open-source YouTube downloader that exposes its functionality through a clean command-line interface. Understanding how Pyutube handles command-line arguments reveals a modern Python CLI pattern using type annotations rather than traditional parser configuration.

## Typer Foundation in [`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py)

The entire CLI architecture resides in **[`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py)** and centers on a single Typer application instance. Typer generates the argument parser automatically from Python type hints, eliminating boilerplate code while producing rich help documentation.

### Initializing the Typer Application

At module level, the code instantiates a configured Typer object that defines the CLI's identity and rendering behavior:

```python
app = typer.Typer(
    name="pyutube",
    add_completion=False,
    help="Awesome CLI …",
    rich_markup_mode="rich"
)

```

This initialization disables shell completion installation (`add_completion=False`) and enables Rich markup for colored help text.

## Defining CLI Arguments and Options

Pyutube distinguishes between **positional arguments** (required values like the YouTube URL) and **optional flags** (boolean toggles like audio-only mode). Both are declared as Python variables using Typer's `Argument()` and `Option()` factories.

### Positional Arguments (URL and Path)

The CLI accepts two positional arguments with distinct defaults and help text:

```python
url_arg = typer.Argument(
    None,
    help="YouTube URL [red]required[/red]",
    show_default=False
)

path_arg = typer.Argument(
    os.getcwd(),
    help="Path to save video [cyan]default: <current directory>[/cyan]",
    show_default=False
)

```

The **`url`** parameter defaults to `None` but is treated as required during execution. The **`path`** parameter defaults to the current working directory via `os.getcwd()`.

### Optional Flags (-a, -f, -v)

Three boolean options control download behavior and information display:

```python
audio_option = typer.Option(False, "-a", "--audio", help="Download only audio")
video_option = typer.Option(False, "-f", "--footage", help="Download only video")
version_option = typer.Option(False, "-v", "--version", help="Show the version number")

```

Each option uses short (`-a`) and long (`--audio`) forms. When present, these flags trigger specific branches in the download logic.

## Command Registration and Execution Flow

The actual command implementation binds these definitions to a Python function using Typer's decorator syntax.

### The Download Command Decorator

The `pyutube()` function serves as the command handler, registered via:

```python
@app.command(name="download", help="…")
def pyutube(
    url: str = url_arg,
    path: str = path_arg,
    audio: bool = audio_option,
    video: bool = video_option,
    version: bool = version_option
) -> None:
    # Execution logic

```

Typer injects parsed values directly into these parameters based on the user's command-line input.

### Runtime Validation and Processing

The function body implements a specific execution sequence:

1. **Version check**: If `-v` is passed, the application prints the version string and exits immediately.
2. **URL validation**: The code verifies an URL was provided, then calls `check_internet_connection()` and `URLHandler.validate()` to ensure connectivity and valid YouTube links.
3. **Mode selection**: 
   - When `-a` is set, `download_service.is_audio` becomes `True` and the audio extraction path executes.
   - When `-f` is set, the video stream preparation logic runs.
   - If neither flag is present, `download_service.asking_video_or_audio()` prompts the user interactively.
4. **Playlist handling**: If the URL resolves to a playlist, the service iterates through items automatically.

## Entry Point and Module Execution

Pyutube supports two execution methods: direct module invocation and console script entry points. The **[`pyutube/__main__.py`](https://github.com/hetari/pyutube/blob/main/pyutube/__main__.py)** file enables the `python -m pyutube` syntax:

```python
from pyutube.cli import app

if __name__ == "__main__":
    app()

```

This pattern delegates immediately to the Typer application, ensuring consistent behavior regardless of how the package is launched.

## Practical Usage Examples

Download a video with interactive prompts for audio/video selection:

```bash
pyutube https://www.youtube.com/watch?v=abc123

```

Extract audio only using the short flag:

```bash
pyutube https://www.youtube.com/watch?v=abc123 -a

```

Download video footage without audio:

```bash
pyutube https://www.youtube.com/watch?v=abc123 -f

```

Save to a specific directory by passing a second positional argument:

```bash
pyutube https://www.youtube.com/watch?v=abc123 /home/user/downloads

```

Process an entire playlist:

```bash
pyutube https://www.youtube.com/playlist?list=PLxyz

```

## Summary

- **Pyutube uses Typer** in [`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py) to eliminate manual argument parsing through Python type hints.
- **Two positional arguments** handle the YouTube URL (required) and download path (defaults to current directory).
- **Three optional flags** control output: `-a` for audio, `-f` for video footage, and `-v` for version information.
- **Runtime logic** validates URLs via `URLHandler.validate()`, checks connectivity via `check_internet_connection()`, and routes to appropriate download services based on flags.
- **Module execution** is handled by [`pyutube/__main__.py`](https://github.com/hetari/pyutube/blob/main/pyutube/__main__.py) calling the Typer app instance directly.

## Frequently Asked Questions

### What library does Pyutube use for parsing command-line arguments?

Pyutube uses **Typer**, a modern Python library that builds on Click and leverages type hints to define CLI interfaces. This approach allows the argument definitions in [`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py) to remain declarative and concise while automatically generating help documentation.

### How does Pyutube handle missing or invalid YouTube URLs?

The CLI first checks if the URL argument is `None` and exits with an error if missing. For provided URLs, it calls `URLHandler.validate()` from [`pyutube/handlers/URLHandler.py`](https://github.com/hetari/pyutube/blob/main/pyutube/handlers/URLHandler.py) to verify the link structure and determine if it points to a standard video, short, or playlist. An internet connectivity check via `check_internet_connection()` precedes validation.

### Can I download YouTube playlists with Pyutube?

Yes. When `URLHandler` identifies a playlist URL, the execution flow enters a playlist-specific branch in [`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py) that iterates through each item. The same audio (`-a`) or video (`-f`) flags apply to every item in the playlist sequence.

### Where is the CLI entry point defined for `python -m pyutube`?

The entry point resides in **[`pyutube/__main__.py`](https://github.com/hetari/pyutube/blob/main/pyutube/__main__.py)**, which imports and calls the Typer `app` instance defined in [`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py). This pattern follows Python packaging standards, allowing the package to execute as a module while maintaining the CLI logic in a separate, importable file.