# Pyutube Architectural Structure: A Layered Service-Oriented Design Explained

> Discover the layered service-oriented architecture of Pyutube. Understand how modules like DownloadService handle CLI, URL validation, and file operations for efficient video downloads.

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

---

**Pyutube follows a layered service-oriented architecture that separates CLI interaction, URL validation, download orchestration, and file handling into distinct modules, with `DownloadService` acting as the central orchestrator coordinating specialized video, audio, and file services.**

Pyutube is an open-source command-line utility for downloading YouTube content (videos, shorts, playlists, and audio) maintained in the [Hetari/pyutube](https://github.com/Hetari/pyutube) repository. Its codebase is organized around a clean separation of concerns, making it accessible both as a standalone CLI tool and as a programmatic Python library.

## Layered Architecture Overview

The Pyutube architectural structure organizes functionality into five distinct layers, each with specific responsibilities and well-defined interfaces:

- **CLI / Entry Point** ([`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py)): Parses command-line arguments using Typer, validates the input URL, and dispatches execution to the appropriate service layer.
- **Handlers** (`pyutube/handlers/`): Low-level validation and playlist-specific logic reside here. [`URLHandler.py`](https://github.com/hetari/pyutube/blob/main/URLHandler.py) normalizes and classifies YouTube URLs, while [`PlaylistHandler.py`](https://github.com/hetari/pyutube/blob/main/PlaylistHandler.py) manages batch downloads.
- **Core Services** ([`pyutube/services/DownloadService.py`](https://github.com/hetari/pyutube/blob/main/pyutube/services/DownloadService.py)): Acts as the primary orchestrator, coordinating the download workflow by delegating to specialized services.
- **Specialized Services**: Individual modules handle specific concerns—[`VideoService.py`](https://github.com/hetari/pyutube/blob/main/VideoService.py) manages video streams and merging, [`AudioService.py`](https://github.com/hetari/pyutube/blob/main/AudioService.py) handles audio-only extraction, and [`FileService.py`](https://github.com/hetari/pyutube/blob/main/FileService.py) manages disk I/O and naming conflicts.
- **Utilities** ([`pyutube/utils.py`](https://github.com/hetari/pyutube/blob/main/pyutube/utils.py)): Shared infrastructure including console UI components (Rich Console), network connectivity checks, interactive prompts, and update verification.

## Data Flow Through the Architecture

Understanding how data moves through Pyutube's architectural structure reveals the relationship between these layers. The execution flow follows a pipeline from input parsing to file persistence.

### Entry Point and CLI Layer

The journey begins in [`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py), where the Typer-based interface reads arguments including `url`, `path`, `--audio`, `--footage`, and `--version`. The CLI validates basic input before instantiating the appropriate handler or service class. For module execution, [`pyutube/__main__.py`](https://github.com/hetari/pyutube/blob/main/pyutube/__main__.py) exposes the application entry point for `python -m pyutube` commands.

### URL and Playlist Handlers

Once the CLI receives a URL, control passes to [`pyutube/handlers/URLHandler.py`](https://github.com/hetari/pyutube/blob/main/pyutube/handlers/URLHandler.py). This component normalizes raw YouTube IDs or links and classifies them as video, short, or playlist. 

For single videos or shorts, execution flows directly to `DownloadService`. For playlists, [`pyutube/handlers/PlaylistHandler.py`](https://github.com/hetari/pyutube/blob/main/pyutube/handlers/PlaylistHandler.py) fetches all playlist metadata, presents an interactive selection interface to the user, and then iteratively invokes `DownloadService` for each selected video.

### Service Layer: Download Orchestration

[`pyutube/services/DownloadService.py`](https://github.com/hetari/pyutube/blob/main/pyutube/services/DownloadService.py) serves as the central coordinator. Its `download_preparing()` method initiates the workflow by calling `VideoService.search_process()`, which constructs a `pytubefix.YouTube` object to retrieve video titles and available streams.

**Resolution selection** depends on the download type:
- **Audio downloads**: `AudioService.get_audio_streams()` identifies and returns the best available audio-only stream.
- **Video downloads**: `VideoService.get_selected_stream()` queries available resolutions and prompts the user via `utils.ask_resolution` if no specific quality is provided.

### File Operations and Post-Processing

[`pyutube/services/FileService.py`](https://github.com/hetari/pyutube/blob/main/pyutube/services/FileService.py) handles the physical storage layer. `generate_filename()` creates safe filenames based on titles, resolution, and MIME types. Before writing, `handle_existing_file()` detects name collisions and offers rename, overwrite, or cancel options. Finally, `save_file()` manages the actual byte streaming to disk.

When Pyutube downloads separate video and audio streams (common for high-quality video), `VideoService.merging()` uses **moviepy**'s `ffmpeg_merge_video_audio` function to combine them into a single MP4 file, then cleans up temporary components.

### Utility and Support Functions

Throughout the pipeline, [`pyutube/utils.py`](https://github.com/hetari/pyutube/blob/main/pyutube/utils.py) provides cross-cutting concerns including Rich Console output for formatted text, Yaspin spinners for operation feedback, network connectivity verification, and interactive user prompts for resolution selection and file conflict resolution.

## Programmatic Usage Examples

Pyutube's architectural structure supports both CLI and library usage patterns.

### Command-Line Interface

```bash

# Download with interactive resolution selection

pyutube download https://www.youtube.com/watch?v=dQw4w9WgXcQ

# Audio-only extraction

pyutube download https://youtu.be/dQw4w9WgXcQ -a

# Batch playlist download with item selection

pyutube download https://www.youtube.com/playlist?list=PL12345ABCDE

```

### Python Library Integration

Using the `DownloadService` directly allows embedding Pyutube functionality in larger applications:

```python
from pyutube.services import DownloadService

# Interactive video download

service = DownloadService(
    url="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    path=".",           # Current directory

    quality=None        # Prompt user for resolution

)
success = service.download()  # Returns True on success

```

For automated audio extraction without user interaction:

```python
from pyutube.services import DownloadService

svc = DownloadService(
    url="https://youtu.be/dQw4w9WgXcQ",
    path=".", 
    quality=None,
    is_audio=True      # Force audio-only mode

)
svc.download()

```

## Summary

- **Pyutube architectural structure** implements a layered design separating CLI ([`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py)), handlers ([`URLHandler.py`](https://github.com/hetari/pyutube/blob/main/URLHandler.py), [`PlaylistHandler.py`](https://github.com/hetari/pyutube/blob/main/PlaylistHandler.py)), services ([`DownloadService.py`](https://github.com/hetari/pyutube/blob/main/DownloadService.py), [`VideoService.py`](https://github.com/hetari/pyutube/blob/main/VideoService.py), [`AudioService.py`](https://github.com/hetari/pyutube/blob/main/AudioService.py), [`FileService.py`](https://github.com/hetari/pyutube/blob/main/FileService.py)), and utilities ([`utils.py`](https://github.com/hetari/pyutube/blob/main/utils.py)).
- `DownloadService` acts as the central orchestrator, delegating to specialized services for video stream selection, audio extraction, and file operations.
- URL classification occurs in [`URLHandler.py`](https://github.com/hetari/pyutube/blob/main/URLHandler.py), while [`PlaylistHandler.py`](https://github.com/hetari/pyutube/blob/main/PlaylistHandler.py) manages batch download workflows.
- File handling includes collision detection via `FileService.handle_existing_file()` and format merging through `VideoService.merging()` using moviepy.
- The architecture supports both CLI usage through Typer and programmatic integration via direct `DownloadService` instantiation.

## Frequently Asked Questions

### What is the entry point for Pyutube's CLI?

The primary entry point is [`pyutube/cli.py`](https://github.com/hetari/pyutube/blob/main/pyutube/cli.py), which implements the Typer-based command-line interface. For module execution, [`pyutube/__main__.py`](https://github.com/hetari/pyutube/blob/main/pyutube/__main__.py) enables running the package via `python -m pyutube`.

### How does Pyutube handle different types of YouTube URLs?

[`pyutube/handlers/URLHandler.py`](https://github.com/hetari/pyutube/blob/main/pyutube/handlers/URLHandler.py) normalizes and classifies input as video, short, or playlist. Single videos route directly to `DownloadService`, while playlists trigger [`PlaylistHandler.py`](https://github.com/hetari/pyutube/blob/main/PlaylistHandler.py) to fetch metadata and manage batch selection before delegating individual downloads.

### Can Pyutube be used as a Python library rather than a CLI tool?

Yes, the architectural structure supports programmatic usage by importing `DownloadService` from `pyutube.services`. You can instantiate the service with a URL, path, and quality parameters, then call the `download()` method directly without invoking the CLI layer.

### How does Pyutube merge separate video and audio streams?

When downloading high-quality video content that comes as separate streams, `VideoService.merging()` in [`pyutube/services/VideoService.py`](https://github.com/hetari/pyutube/blob/main/pyutube/services/VideoService.py) uses moviepy's `ffmpeg_merge_video_audio` function to combine the components into a single MP4 file before cleaning up temporary files.