YT-DL-CLI Video downloader documentation

Main Module

YT-DL-CLI Video Downloader Main Application Module.

This module contains the primary VideoDownloader class that serves as the main orchestrator for the entire video downloading process. It integrates all components of the application including configuration management, dependency injection, asynchronous orchestration, and comprehensive error handling.

The module is designed with a clean architecture approach, separating concerns between configuration, logging, orchestration, and execution. It provides a high-level interface that abstracts away the complexity of concurrent downloads, internationalization, and error management.

Key Features:
  • Command-line argument parsing and configuration management

  • Dependency injection for clean component integration

  • Asynchronous download orchestration for optimal performance

  • Comprehensive error handling with user-friendly messages

  • Internationalization support for multi-language environments

  • Graceful handling of user interruptions and system errors

Architecture:

The module follows the dependency injection pattern to ensure loose coupling between components. The VideoDownloader class acts as a facade that coordinates between different subsystems without being tightly coupled to their implementations.

The application architecture consists of several layers:

  1. Presentation Layer (CLI Interface): - Command-line argument parsing - User interaction and feedback - Progress reporting and error messages

  2. Application Layer (Main Orchestration): - VideoDownloader class (main entry point) - Configuration management and validation - High-level workflow coordination

  3. Domain Layer (Business Logic): - AsyncOrchestrator for concurrent operations - Download core functionality - Business rules and validation

  4. Infrastructure Layer (External Dependencies): - File system operations - Network communication - Logging and monitoring - Internationalization services

Design Patterns:
  • Facade Pattern: VideoDownloader provides simplified interface to complex subsystems

  • Dependency Injection: Promotes loose coupling and enhances testability

  • Context Manager: Ensures proper resource management and cleanup

  • Observer Pattern: Progress tracking and event notification

  • Strategy Pattern: Multiple download strategies and quality options

Error Handling Strategy:

The module implements a comprehensive error handling approach:

  • Graceful Degradation: Continues operation when possible, falls back to defaults

  • User-Friendly Messages: Translates technical errors into understandable feedback

  • Logging Hierarchy: Different log levels for different audiences (user vs developer)

  • Resource Cleanup: Ensures proper cleanup even in error scenarios

  • Interruption Handling: Responds appropriately to user cancellation requests

Performance Considerations:
  • Asynchronous I/O operations to prevent blocking

  • Concurrent downloads with configurable limits

  • Memory-efficient streaming for large files

  • Progress tracking without performance impact

  • Lazy loading of heavy dependencies

Internationalization:

The module supports multiple languages through the i18n system: - Dynamic language detection from system locale - Runtime language switching capability - Localized error messages and user feedback - Cultural adaptation of date/time formats - Support for right-to-left languages

Security Considerations:
  • Input validation for URLs and file paths

  • Safe file naming to prevent directory traversal

  • Secure temporary file handling

  • Network request validation and sanitization

  • Proper handling of sensitive configuration data

Example Usage:

Command-line usage:

$ python main.py –url “https://youtube.com/watch?v=example” –quality 720p $ python main.py –playlist “https://youtube.com/playlist?list=example” –format mp3 $ python main.py –url “https://youtube.com/watch?v=example” –save-dir “/custom/path”

Programmatic usage:

>>> from main import VideoDownloader
>>>
>>> # Basic usage with defaults
>>> downloader = VideoDownloader()
>>> downloader.download()
>>>
>>> # Custom configuration
>>> from yt_dl_cli.config.config import Config
>>> config = Config(save_dir="/downloads", quality="1080p", format="mp4")
>>> downloader = VideoDownloader(config=config)
>>> downloader.download()
>>>
>>> # With custom logger and language
>>> import logging
>>> logger = logging.getLogger("custom_downloader")
>>> downloader = VideoDownloader(config=config, logger=logger, language="ru")
>>> downloader.download()
Module Dependencies:
Core Dependencies:
  • asyncio: Asynchronous I/O operations and event loop management

  • logging: Comprehensive logging infrastructure

  • traceback: Exception tracking and debugging information

  • typing: Type hints for better code documentation and IDE support

Application Dependencies:
  • yt_dl_cli.config.config: Configuration management and validation

  • yt_dl_cli.utils.logger: Logger factory and configuration utilities

  • yt_dl_cli.core.orchestration: Asynchronous orchestration and DI container

  • yt_dl_cli.utils.parser: Command-line argument parsing utilities

  • yt_dl_cli.i18n.init: Internationalization initialization

  • yt_dl_cli.i18n.messages: Localized message management

Testing:

The module is designed with testability in mind: - Dependency injection allows for easy mocking - Separation of concerns enables unit testing of individual components - Error handling can be tested through exception simulation - Configuration can be provided programmatically for test scenarios

Compatibility:
  • Python 3.8+: Utilizes modern async/await syntax and type hints

  • Cross-platform: Works on Windows, macOS, and Linux

  • Unicode support: Handles international characters in filenames and paths

  • Network protocols: Supports HTTP/HTTPS with proxy configuration

Author: Oleksandr Kharhenko License: MIT Created: 2025 Last Modified: 20245

See Also:
  • yt_dl_cli.config.config: Configuration management documentation

  • yt_dl_cli.core.orchestration: Asynchronous orchestration details

  • yt_dl_cli.utils.logger: Logging configuration and best practices

  • yt_dl_cli.i18n: Internationalization and localization guide

class yt_dl_cli.main.VideoDownloader(config: Config | None = None, logger: ILogger | None = None, language: str | None = None)

Bases: object

Main orchestrator class for the YouTube video downloading application.

This class serves as the primary entry point and coordinator for the entire download process. It encapsulates the complexity of managing configuration, dependency injection, asynchronous orchestration, and error handling while providing a simple interface for initiating downloads.

The class follows the facade pattern, providing a simplified interface to a complex subsystem of downloaders, parsers, loggers, and orchestrators. It ensures proper initialization order, resource management, and graceful error handling throughout the application lifecycle.

Responsibilities:
  1. Parse and validate command-line arguments

  2. Initialize configuration and logging systems

  3. Create and configure the dependency injection container

  4. Orchestrate asynchronous download operations

  5. Handle user interruptions and system errors gracefully

  6. Manage resource cleanup and proper shutdown procedures

Design Patterns:
  • Facade: Simplifies interaction with complex subsystems

  • Dependency Injection: Promotes loose coupling and testability

  • Context Manager: Ensures proper resource management

Thread Safety:

This class is not thread-safe by design. Each instance should be used in a single thread context. For concurrent operations, the class delegates to AsyncOrchestrator which handles async/await patterns.

Attributes:
config (Config): Application configuration object containing all

settings for download operations, paths, and preferences.

logger (logging.Logger): Configured logger instance for the application,

set up with appropriate handlers and formatters.

Example:

Basic usage with default configuration:

>>> downloader = VideoDownloader()
>>> downloader.download()

Usage with custom configuration:

>>> custom_config = Config(save_dir="/custom/path", quality="1080p")
>>> custom_logger = logging.getLogger("custom")
>>> downloader = VideoDownloader(config=custom_config, logger=custom_logger)
>>> downloader.download()
See Also:

Config: Configuration management class AsyncOrchestrator: Handles concurrent download operations DIContainer: Dependency injection container for component creation LoggerFactory: Factory for creating configured logger instances

download() None

Execute the complete video download process with comprehensive error handling.

This method orchestrates the entire download workflow from initialization to completion. It serves as the main entry point for the download process, coordinating between multiple subsystems including dependency injection, asynchronous orchestration, resource management, and error handling.

The method implements a sophisticated error handling strategy that provides different responses for different types of failures, ensuring graceful degradation and proper user feedback. It uses context managers to guarantee resource cleanup regardless of how the process terminates.

Process Architecture:

The download process follows a well-defined workflow:

  1. Dependency Resolution: Creates the downloader core through the dependency injection container, ensuring all required components are properly initialized and configured.

  2. Orchestrator Setup: Initializes the AsyncOrchestrator with the core components and configuration, preparing for concurrent operations.

  3. Resource Management: Enters a context manager that ensures proper resource allocation and cleanup, including file handles, network connections, and temporary files.

  4. Asynchronous Execution: Launches the main download orchestration using asyncio, enabling concurrent downloads and efficient I/O operations.

  5. Completion Handling: Manages successful completion, user interruption, or error scenarios with appropriate logging and cleanup procedures.

Error Handling Strategy:

The method implements a multi-layered error handling approach:

  • User Interruption (KeyboardInterrupt): Caught when the user presses Ctrl+C or sends SIGINT. Logs a localized warning message and performs graceful shutdown, allowing for cleanup of partial downloads and temporary files.

  • Critical System Errors (Exception): Catches all other unexpected exceptions, logs them as critical errors with full stack traces for debugging, and terminates the application with a non-zero exit code to indicate failure to calling processes.

  • Resource Management: The context manager pattern ensures that resources are properly cleaned up even if exceptions occur during the download process, preventing resource leaks and corruption.

Concurrency and Performance:
  • Utilizes asyncio event loop for efficient concurrent operations

  • Delegates heavy I/O operations to specialized async components

  • Implements proper backpressure handling to prevent memory exhaustion

  • Provides real-time progress tracking without performance overhead

  • Manages connection pooling and rate limiting for optimal throughput

Returns:
None: This method operates through side effects and does not return

a value. Success is indicated by completion without exceptions, while failures are communicated through logging, user messages, and appropriate exit codes for process management.

Raises:
SystemExit: May be raised by underlying components for critical errors

that require immediate application termination. This typically occurs for configuration errors, permission issues, or unrecoverable system states. The exit code indicates the type of failure for process management and scripting.

Side Effects:
File System:
  • Creates downloaded video/audio files in the configured directory

  • Generates temporary files during the download process

  • Creates and updates log files with operation details

  • May create directory structures for organized storage

Network:
  • Establishes connections to video hosting services

  • Downloads video metadata and content streams

  • May configure proxy settings and authentication

  • Implements rate limiting and retry mechanisms

User Interface:
  • Displays progress indicators and download statistics

  • Shows real-time status updates and completion notifications

  • Provides error messages and troubleshooting information

  • Updates terminal title and status (where supported)

System Resources:
  • Manages memory usage for concurrent operations

  • Utilizes available CPU cores for parallel processing

  • Monitors disk space and prevents over-allocation

  • Handles system signals for graceful shutdown

Performance Characteristics:
  • Memory Usage: Scales with concurrent download count and video quality

  • CPU Usage: Minimal except during transcoding operations

  • Network Usage: Optimized with connection pooling and compression

  • Disk I/O: Efficient streaming writes to minimize disk thrashing

  • Response Time: Real-time progress updates every 100ms

Example Usage:

Basic download execution:

>>> downloader = VideoDownloader()
>>> downloader.download()
# Output: Progress bars, status messages, completion notification

Error handling in scripts:

>>> import sys
>>> try:
...     downloader = VideoDownloader()
...     downloader.download()
...     print("Download completed successfully")
... except SystemExit as e:
...     print(f"Download failed with exit code: {e.code}")
...     sys.exit(e.code)

Integration with exception handling:

>>> try:
...     downloader.download()
... except KeyboardInterrupt:
...     print("Download cancelled by user")
... except Exception as e:
...     print(f"Unexpected error: {e}")
...     # Error details are already logged by the method
Monitoring and Debugging:

The method provides extensive logging at multiple levels: - INFO: General progress and status information - WARNING: Non-critical issues and user interruptions - ERROR: Recoverable errors and retry attempts - CRITICAL: Unrecoverable errors requiring termination - DEBUG: Detailed internal state for troubleshooting

Thread Safety:

This method is not thread-safe and should only be called once per VideoDownloader instance. The internal AsyncOrchestrator handles concurrency through async/await patterns within a single thread. For multi-threaded applications, create separate VideoDownloader instances for each thread.

Note:

This method is designed to be called once per VideoDownloader instance and represents the complete lifecycle of a download session. Multiple calls may result in undefined behavior due to resource state management and configuration handling. Create a new VideoDownloader instance for each independent download session.

See Also:

DIContainer.create_downloader_core: Creates configured download engine AsyncOrchestrator: Manages concurrent download operations and scheduling Messages.CLI: Internationalized user interface messages and error texts Config: Configuration options that affect download behavior LoggerFactory: Logging configuration and output management

yt_dl_cli.main.main() None

Main entry point function for command-line execution.

This function serves as the primary entry point when the module is executed directly from the command line. It provides a clean interface for script execution and handles the complete lifecycle of a download session.

The function creates a VideoDownloader instance with default configuration (parsed from command-line arguments) and initiates the download process. It’s designed to be simple and straightforward for command-line usage.

Process Flow:
  1. Create VideoDownloader instance with default configuration

  2. Parse command-line arguments automatically

  3. Initialize logging and internationalization

  4. Execute the download process

  5. Handle completion or errors appropriately

Returns:
None: This function operates through side effects and process exit codes.

Success is indicated by normal completion, while errors result in non-zero exit codes.

Raises:
SystemExit: Raised by the VideoDownloader.download() method for critical

errors that require immediate termination. The exit code indicates the type of failure.

Side Effects:
  • Parses command-line arguments from sys.argv

  • Creates VideoDownloader instance with parsed configuration

  • Executes complete download process with all associated side effects

  • May exit the process with non-zero code on failure

Example:

Command-line usage:

$ python main.py –url “https://youtube.com/watch?v=example” $ python main.py –help $ python main.py –url “https://youtube.com/watch?v=example” –quality 720p

Note:

This function is specifically designed for command-line execution. For programmatic usage, create VideoDownloader instances directly rather than calling this function.

See Also:

VideoDownloader: Main orchestrator class for download operations parse_arguments: Command-line argument parsing implementation

Configuration

Configuration Management Module

This module provides configuration management functionality for the video downloader application. It defines the Config dataclass that holds all application settings including download paths, quality preferences, concurrency controls, and validation logic.

The module ensures configuration integrity through automatic validation and type conversion, providing a centralized way to manage application settings with proper error handling.

Classes:

Config: Main configuration dataclass with validation

class yt_dl_cli.config.config.Config(save_dir: ~pathlib.Path, max_workers: int, quality: str, audio_only: bool, urls: ~typing.List[str] = <factory>)

Bases: object

Configuration data class containing all application settings.

This class holds all the configuration parameters needed for the YouTube downloader application, including download paths, quality settings, and concurrency controls. It provides automatic validation of configuration values and type conversion where appropriate.

Attributes:
save_dir (Path): Directory where downloaded files will be saved.

Automatically converted to Path object if string is provided.

max_workers (int): Maximum number of concurrent download threads.

Must be at least 1.

quality (str): Video quality preference. Valid options are:

‘best’, ‘worst’, ‘720’, ‘480’, ‘360’.

audio_only (bool): Whether to download only audio (MP3) instead of video. urls (List[str]): List of URLs to download. Defaults to empty list.

Raises:

ValueError: If max_workers is less than 1 or quality is not in valid options.

Example:
>>> from pathlib import Path
>>> config = Config(
...     save_dir=Path("/downloads"),
...     max_workers=4,
...     quality="720",
...     audio_only=False,
...     urls=["https://example.com/video1", "https://example.com/video2"]
... )
audio_only: bool
max_workers: int
quality: str
save_dir: Path
urls: List[str]

Core

YT-DL-CLI Video Downloader Core Module.

This module contains the core components responsible for the actual video downloading process. It provides a clean separation of concerns between video information extraction, download execution, and the orchestration of the complete download workflow.

The module is built around the principle of single responsibility, with each class handling a specific aspect of the download process. This design promotes testability, maintainability, and allows for easy extension and modification of individual components.

Architecture Overview:

The module implements a layered architecture with clear separation between:

  1. Information Layer (VideoInfoExtractor): - Extracts video metadata without downloading content - Validates video availability and accessibility - Retrieves video information for processing decisions

  2. Execution Layer (DownloadExecutor): - Handles the actual download operations - Manages yt-dlp interactions and configurations - Provides error handling for download failures

  3. Orchestration Layer (DownloaderCore): - Coordinates the complete download workflow - Integrates all components and dependencies - Manages resource lifecycle and cleanup - Handles file system operations and statistics

Key Components:
  • VideoInfoExtractor: Metadata extraction and video validation

  • DownloadExecutor: Core download execution engine

  • DownloaderCore: Main orchestrator and workflow manager

Design Patterns:
  • Strategy Pattern: Format selection through IFormatStrategy interface

  • Dependency Injection: All dependencies injected through constructor

  • Context Manager: Resource management with __enter__/__exit__ methods

  • Facade Pattern: DownloaderCore provides simplified interface to complex operations

  • Template Method: Standardized download workflow with extensible steps

Error Handling Philosophy:

The module implements defensive programming practices: - All external API calls are wrapped in try-catch blocks - Errors are logged but don’t crash the application - Graceful degradation when individual downloads fail - Resource cleanup is guaranteed through context managers - Detailed error messages for troubleshooting and debugging

Performance Considerations:
  • Efficient metadata extraction without unnecessary downloads

  • File existence checking to avoid redundant operations

  • Resource pooling and cleanup to prevent memory leaks

  • Asynchronous-friendly design for concurrent operations

  • Minimal I/O operations through smart caching strategies

Integration Points:

The module integrates with several external systems: - yt-dlp: Primary download engine and video platform interface - File System: Through IFileChecker for file operations - Logging: Through ILogger for monitoring and debugging - Statistics: Through IStatsCollector for progress tracking - Configuration: Through Config for user preferences and settings - Internationalization: Through Messages for localized user feedback

Usage Patterns:

The module is designed to be used in several contexts:

  1. Single Download Operations: - Extract video information - Check file existence - Execute download if needed - Update statistics and logs

  2. Batch Download Operation: - Process multiple URLs concurrently - Maintain statistics across operations - Handle individual failures gracefully

  3. Integration with Async Systems: - Compatible with asyncio event loops - Non-blocking operations where possible - Resource cleanup compatible with async contexts

Security Considerations:
  • Input validation for URLs and file paths

  • Safe filename sanitization to prevent directory traversal

  • Secure handling of temporary files and downloads

  • Validation of video information before processing

  • Protection against malicious URLs and content

Thread Safety:
  • VideoInfoExtractor: Thread-safe, creates isolated yt-dlp instances

  • DownloadExecutor: Thread-safe, each operation uses separate context

  • DownloaderCore: Not thread-safe, designed for single-thread usage

  • Resource management: Requires careful coordination in multi-threaded environments

Example Usage:

Basic usage with dependency injection:

>>> from yt_dl_cli.config.config import Config
>>> from yt_dl_cli.utils.logger import LoggerFactory
>>>
>>> # Setup dependencies
>>> config = Config(save_dir="/downloads", audio_only=False)
>>> logger = LoggerFactory.get_logger("/downloads")
>>>
>>> # Create core components
>>> info_extractor = VideoInfoExtractor(logger)
>>> download_executor = DownloadExecutor(logger)
>>>
>>> # Create and use downloader core
>>> with DownloaderCore(config, strategy, stats, logger,
...                    file_checker, info_extractor, download_executor) as core:
...     core.download_single("https://youtube.com/watch?v=example")
Dependencies:
External Libraries:
  • yt-dlp: Video downloading and information extraction

  • typing: Type hints for better code documentation

Internal Modules:
  • yt_dl_cli.i18n.messages: Internationalized user messages

  • yt_dl_cli.interfaces.interfaces: Core interface definitions

  • yt_dl_cli.interfaces.strategies: Format selection strategies

  • yt_dl_cli.utils.utils: Utility functions and helpers

  • yt_dl_cli.config.config: Configuration management

Error Types:

The module handles several categories of errors: - Network errors: Connection timeouts, DNS failures - Platform errors: Video unavailable, private videos, geo-blocking - File system errors: Permission denied, disk full, invalid paths - Format errors: Unsupported formats, codec issues - Configuration errors: Invalid settings, missing dependencies

Monitoring and Observability:
  • Detailed logging at multiple levels (DEBUG, INFO, WARNING, ERROR)

  • Statistics collection for success/failure rates

  • Progress tracking for individual downloads

  • Resource usage monitoring and cleanup verification

  • Performance metrics for optimization opportunities

Testing Considerations:

The module is designed with testability in mind: - Dependency injection allows for easy mocking - Clear separation of concerns enables unit testing - Context managers ensure proper test cleanup - Error handling can be tested through exception simulation - Statistics tracking provides measurable test outcomes

Version Compatibility:
  • Python 3.8+: Uses modern type hints and context managers

  • yt-dlp: Compatible with latest stable versions

  • Cross-platform: Works on Windows, macOS, and Linux

  • Unicode support: Handles international characters in titles and paths

See Also:
  • yt_dl_cli.core.orchestration: Asynchronous orchestration layer

  • yt_dl_cli.interfaces.interfaces: Core interface definitions

  • yt_dl_cli.config.config: Configuration management documentation

  • yt_dl_cli.utils.utils: Utility functions and helpers

  • yt-dlp documentation: https://harley029.github.io/yt_dl_cli/

class yt_dl_cli.core.core.DownloadExecutor(logger: ILogger)

Bases: object

Handles the actual download execution using yt-dlp.

This class provides a clean interface to yt-dlp’s download functionality, focusing specifically on executing download operations with comprehensive error handling and logging. It serves as the execution engine for the download workflow, handling the actual file transfer and storage operations.

The class implements robust error handling to ensure that download failures are properly managed and don’t crash the application. It provides detailed logging for monitoring download progress and troubleshooting issues.

Key Responsibilities:
  • Execute video/audio downloads using yt-dlp

  • Handle download-related errors and exceptions

  • Provide detailed logging for monitoring and debugging

  • Manage yt-dlp configuration and options

  • Support multiple output formats and quality settings

Design Principles:
  • Single Responsibility: Only handles download execution

  • Defensive Programming: Comprehensive error handling

  • Logging Integration: Detailed progress and error reporting

  • Configuration Flexibility: Supports various yt-dlp options

Error Categories:

The class handles several types of download errors: - Network errors: Connection issues, timeouts, bandwidth problems - Storage errors: Disk full, permission denied, invalid paths - Format errors: Unsupported formats, codec issues - Platform errors: Video removed, geo-blocked, private content

Thread Safety:

This class is thread-safe as it creates isolated yt-dlp instances for each download operation and doesn’t maintain mutable state. Multiple threads can safely use the same DownloadExecutor instance.

Performance Characteristics:
  • I/O intensive: Performance depends on network and disk speed

  • Memory efficient: Streaming downloads minimize memory usage

  • Resumable: Supports partial download resumption where possible

  • Concurrent friendly: Designed for use in concurrent environments

Attributes:
logger (ILogger): Logger instance for error reporting and progress tracking.

Used to record download attempts, progress updates, completion status, and detailed error information.

Example:

Basic usage for single download:

>>> from yt_dl_cli.utils.logger import LoggerFactory
>>> logger = LoggerFactory.get_logger("/downloads")
>>> executor = DownloadExecutor(logger)
>>>
>>> # Configure download options
>>> opts = {
...     "format": "best[height<=720]",
...     "outtmpl": "/downloads/%(title)s.%(ext)s",
...     "writeinfojson": True
... }
>>>
>>> # Execute download
>>> success = executor.execute_download("https://youtube.com/watch?v=example", opts)
>>> if success:
...     print("Download completed successfully")
... else:
...     print("Download failed - check logs")

Batch download example:

>>> urls = ["https://youtube.com/watch?v=video1", "https://youtube.com/watch?v=video2"]
>>> success_count = 0
>>> for url in urls:
...     if executor.execute_download(url, opts):
...         success_count += 1
>>> print(f"Successfully downloaded {success_count}/{len(urls)} videos")
See Also:

yt_dlp.YoutubeDL: Primary download engine ILogger: Logging interface for progress tracking Messages.Executor: Localized error and status messages

execute_download(url: str, opts: Dict[str, Any]) bool

Execute a download operation for a single URL.

This method performs the actual download using yt-dlp with the provided configuration options. It handles the complete download process including format selection, quality negotiation, file transfer, and storage operations. The method implements comprehensive error handling to ensure that failures are properly managed and logged.

The download process is designed to be robust and handle various error conditions gracefully, ensuring that individual download failures don’t crash the entire application. This makes it suitable for batch operations and concurrent download scenarios.

Process Flow:
  1. Create yt-dlp instance with provided options

  2. Initiate download operation for the specified URL

  3. Monitor download progress and handle any errors

  4. Log success or failure with appropriate details

  5. Return status indicator for calling code

Args:
url (str): Video URL to download. Should be a valid URL pointing to

a video on a platform supported by yt-dlp. The URL will be processed by yt-dlp’s URL recognition system to determine the appropriate extractor and download strategy.

opts (Dict[str, Any]): yt-dlp configuration options for the download.

These options control all aspects of the download process including: - “format”: Quality and format selection - “outtmpl”: Output filename template - “writeinfojson”: Save metadata to JSON file - “writesubtitles”: Download subtitle files - “embedsubs”: Embed subtitles in video file - “extractaudio”: Extract audio only - “audioformat”: Audio format specification - “postprocessors”: Post-processing operations

Returns:
bool: True if the download completed successfully, False if it failed.

Success is determined by yt-dlp completing the download process without raising exceptions. The return value allows calling code to track success/failure rates and handle batch operations appropriately.

Error Handling:

The method catches and handles several types of exceptions:

  • yt_dlp.DownloadError: Raised when yt-dlp encounters download-specific errors such as network issues, format unavailability, or storage problems. These are logged with detailed error information including the URL and specific error details.

  • Exception: Catches all other unexpected errors to prevent application crashes. This includes system-level errors, memory issues, and other unforeseen problems. All exceptions are logged with full details for debugging purposes.

Side Effects:
  • Creates downloaded files in the specified output directory

  • May create temporary files during the download process

  • Updates file system with video/audio content and metadata

  • Generates log entries for monitoring and debugging

  • May modify network settings (proxy, user agent) during download

Performance Considerations:
  • Network intensive: Download speed depends on connection bandwidth

  • Disk intensive: File writing performance affects overall speed

  • Memory efficient: Streaming downloads minimize memory usage

  • CPU usage: Varies with post-processing operations (transcoding, etc.)

  • Resumable: Supports partial download resumption where possible

Example:

Basic download with minimal options:

>>> executor = DownloadExecutor(logger)
>>> opts = {"format": "best", "outtmpl": "/downloads/%(title)s.%(ext)s"}
>>> success = executor.execute_download("https://youtube.com/watch?v=example", opts)

High-quality video download with metadata:

>>> opts = {
...     "format": "best[height<=1080]",
...     "outtmpl": "/downloads/%(uploader)s - %(title)s.%(ext)s",
...     "writeinfojson": True,
...     "writesubtitles": True,
...     "writeautomaticsub": True
... }
>>> success = executor.execute_download(url, opts)

Audio-only download with format conversion:

>>> opts = {
...     "format": "bestaudio/best",
...     "outtmpl": "/music/%(title)s.%(ext)s",
...     "extractaudio": True,
...     "audioformat": "mp3",
...     "audioquality": "192K"
... }
>>> success = executor.execute_download(url, opts)

Error handling in batch operations:

>>> urls = ["https://youtube.com/watch?v=video1", "https://youtube.com/watch?v=video2"]
>>> failed_urls = []
>>> for url in urls:
...     if not executor.execute_download(url, opts):
...         failed_urls.append(url)
>>> print(f"Failed downloads: {len(failed_urls)}")
Note:

This method is designed to be called multiple times with different URLs and options. Each call creates a fresh yt-dlp instance to ensure isolation and prevent state contamination between downloads.

All exceptions are caught and logged, ensuring that one failed download doesn’t crash the entire application. This makes the method safe for use in concurrent environments and batch processing scenarios.

See Also:

yt_dlp.YoutubeDL: Primary download engine documentation yt_dlp.DownloadError: Download-related error handling Messages.Executor: Localized error and status message definitions Config: Configuration options that affect download behavior

class yt_dl_cli.core.core.DownloaderCore(config: Config, strategy: IFormatStrategy, stats: IStatsCollector, logger: ILogger, file_checker: IFileChecker, info_extractor: VideoInfoExtractor, download_executor: DownloadExecutor)

Bases: object

Core download logic coordinator that orchestrates the download process.

This class brings together all the components needed for downloading: configuration, format strategies, statistics, file checking, and the actual download execution. It handles the complete workflow for a single download operation.

download_single(url: str) None

Download a single video from the provided URL.

This method orchestrates the complete download process for a single URL: 1. Extract video information to get title and check availability 2. Create sanitized filename and check if file already exists 3. Skip download if file exists, otherwise proceed with download 4. Update statistics based on the outcome

Args:

url (str): Video URL to download

Note:

This method handles all error conditions gracefully and updates statistics appropriately. It’s designed to be called concurrently for multiple URLs.

register_resource(resource)

Register a resource for automatic cleanup.

Args:

resource: Any object with a close() method that needs cleanup

class yt_dl_cli.core.core.VideoInfoExtractor(logger: ILogger)

Bases: object

Handles extraction of video metadata without downloading content.

This class provides a clean interface to yt-dlp’s information extraction capabilities, focusing specifically on retrieving video metadata without performing actual downloads. It serves as the first step in the download workflow, validating video availability and extracting necessary information for processing decisions.

The class implements robust error handling to ensure that metadata extraction failures don’t crash the application. It provides detailed logging for troubleshooting and monitoring purposes.

Key Responsibilities:
  • Extract video metadata from URLs using yt-dlp

  • Validate video availability and accessibility

  • Handle platform-specific errors and limitations

  • Provide structured error reporting and logging

  • Support multiple video platforms through yt-dlp

Design Principles:
  • Single Responsibility: Only handles information extraction

  • Defensive Programming: Extensive error handling and validation

  • Logging Integration: Comprehensive error reporting

  • Platform Agnostic: Works with any yt-dlp supported platform

Error Handling:

The class handles several categories of errors: - Network errors: Connection timeouts, DNS failures - Platform errors: Video unavailable, private videos, geo-blocking - Parsing errors: Invalid URLs, malformed responses - Authentication errors: Age-restricted content, login required

Thread Safety:

This class is thread-safe as it creates isolated yt-dlp instances for each operation and doesn’t maintain mutable state between calls. Multiple threads can safely use the same VideoInfoExtractor instance.

Performance Characteristics:
  • Lightweight operations: Only extracts metadata, no downloads

  • Network dependent: Performance varies with connection speed

  • Caching friendly: Results can be cached by calling code

  • Memory efficient: Minimal memory footprint per operation

Attributes:
logger (ILogger): Logger instance for error reporting and debugging.

Used to record extraction attempts, failures, and detailed error information for troubleshooting.

Example:

Basic usage for video information extraction:

>>> from yt_dl_cli.utils.logger import LoggerFactory
>>> logger = LoggerFactory.get_logger("/tmp")
>>> extractor = VideoInfoExtractor(logger)
>>>
>>> # Extract video information
>>> opts = {"quiet": True, "no_warnings": True}
>>> info = extractor.extract_info("https://youtube.com/watch?v=example", opts)
>>>
>>> if info:
...     print(f"Title: {info.get('title')}")
...     print(f"Duration: {info.get('duration')} seconds")
...     print(f"Uploader: {info.get('uploader')}")
... else:
...     print("Failed to extract video information")

Error handling example:

>>> info = extractor.extract_info("https://invalid-url", opts)
>>> if info is None:
...     print("Extraction failed - check logs for details")
See Also:

yt_dlp.YoutubeDL: Primary extraction engine ILogger: Logging interface for error reporting Messages.Extractor: Localized error messages

extract_info(url: str, opts: Dict[str, Any]) Any

Extract video information from a URL without downloading.

This method uses yt-dlp to retrieve comprehensive metadata about a video including title, duration, available formats, uploader information, and other platform-specific details. The extraction is performed without downloading any actual video content, making it efficient for validation and preprocessing tasks.

The method implements robust error handling to ensure that extraction failures are properly logged and don’t crash the application. It handles various error conditions including network failures, video unavailability, and platform-specific restrictions.

Process Flow:
  1. Create yt-dlp instance with provided options

  2. Attempt to extract video information from URL

  3. Validate that information was successfully retrieved

  4. Handle any errors that occur during extraction

  5. Log appropriate messages for monitoring and debugging

  6. Return structured information or None on failure

Args:
url (str): Video URL to extract information from. Should be a valid

URL pointing to a video on a platform supported by yt-dlp. Examples include YouTube, Vimeo, Dailymotion, and hundreds of other video platforms.

opts (Dict[str, Any]): yt-dlp configuration options for the extraction.

Common options include: - “quiet”: Suppress output messages - “no_warnings”: Disable warning messages - “extractaudio”: Audio extraction settings - “format”: Preferred format selection - “ignoreerrors”: Continue on errors

Returns:
Any: Video information dictionary from yt-dlp containing comprehensive

metadata about the video, or None if extraction failed. The dictionary typically includes: - “title”: Video title - “duration”: Video length in seconds - “uploader”: Channel or user name - “upload_date”: Publication date - “view_count”: Number of views - “formats”: Available quality/format options - “thumbnail”: Thumbnail image URL - “description”: Video description text - Platform-specific additional metadata

Error Handling:

The method catches and handles several types of exceptions:

  • yt_dlp.DownloadError: Raised when yt-dlp encounters download-related errors such as network issues, authentication problems, or video unavailability. These are logged as extraction errors.

  • yt_dlp.utils.ExtractorError: Raised when yt-dlp’s extractor encounters platform-specific issues such as parsing errors, unsupported URLs, or API changes. These are logged with detailed error information.

  • Exception: Catches all other unexpected errors to prevent application crashes. These are logged as general extraction errors with full exception details for debugging.

Performance Considerations:
  • Network dependent: Extraction time varies with connection speed

  • Lightweight operation: Only retrieves metadata, no file downloads

  • Caching opportunity: Results can be cached by calling code

  • Rate limiting: Respects platform rate limits automatically

Example:

Basic information extraction:

>>> extractor = VideoInfoExtractor(logger)
>>> opts = {"quiet": True, "no_warnings": True}
>>> info = extractor.extract_info("https://youtube.com/watch?v=dQw4w9WgXcQ", opts)
>>>
>>> if info:
...     print(f"Title: {info['title']}")
...     print(f"Duration: {info['duration']} seconds")
...     print(f"Uploader: {info['uploader']}")
... else:
...     print("Failed to extract information")

Handling extraction failures:

>>> urls = ["https://youtube.com/watch?v=valid", "https://invalid-url"]
>>> for url in urls:
...     info = extractor.extract_info(url, opts)
...     if info:
...         print(f"Successfully extracted: {info['title']}")
...     else:
...         print(f"Failed to extract from: {url}")

Custom options for specific needs:

>>> opts = {
...     "quiet": False,
...     "no_warnings": False,
...     "extract_flat": True,  # For playlists
...     "ignoreerrors": True
... }
>>> info = extractor.extract_info(playlist_url, opts)
Note:

This method is designed to be called multiple times with different URLs and options. Each call creates a fresh yt-dlp instance to ensure isolation and prevent state contamination between extractions.

Errors are logged but not raised, allowing the calling code to handle None return values gracefully and continue processing other URLs in batch operations.

See Also:

yt_dlp.YoutubeDL: Primary extraction engine documentation yt_dlp.DownloadError: Download-related error handling yt_dlp.utils.ExtractorError: Extractor-specific error handling Messages.Extractor: Localized error message definitions

Orchestration

Asynchronous Download Orchestration Module

This module provides the main orchestration layer for managing concurrent video downloads. It contains the AsyncOrchestrator class for coordinating multiple downloads and the DIContainer class for dependency injection and component creation.

The module implements asynchronous processing using asyncio and ThreadPoolExecutor to efficiently handle multiple downloads while respecting concurrency limits and providing comprehensive statistics reporting.

Classes:

AsyncOrchestrator: Main orchestrator for managing concurrent downloads DIContainer: Dependency injection container for component creation

Key Features:
  • Asynchronous download coordination with configurable concurrency

  • Thread-based execution to avoid blocking the event loop

  • Comprehensive timing and statistics reporting

  • Dependency injection pattern for clean component composition

  • Proper resource management with context managers

Dependencies:
  • asyncio: For asynchronous execution and event loop management

  • concurrent.futures: For thread pool execution

  • logging: For logger type hints and configuration

  • time: For performance timing measurements

  • typing: For type hints and annotations

  • Various yt_dl_cli modules: For core functionality and configuration

class yt_dl_cli.core.orchestration.AsyncOrchestrator(core: DownloaderCore, config: Config)

Bases: object

Manages asynchronous execution of multiple downloads with concurrency control.

This class handles the coordination of multiple concurrent downloads using asyncio and ThreadPoolExecutor, providing efficient parallel processing while respecting the configured worker limits. It serves as the main orchestration layer for the download application.

The orchestrator manages the entire download lifecycle from initialization through completion, including timing measurements and final reporting.

Attributes:

core (DownloaderCore): The core downloader instance used for each download config (Config): Configuration containing URLs and concurrency settings

Example:
>>> import asyncio
>>> from yt_dl_cli.config.config import Config
>>> from pathlib import Path
>>>
>>> config = Config(
...     save_dir=Path("/downloads"),
...     max_workers=4,
...     quality="720",
...     audio_only=False,
...     urls=["https://example.com/video1", "https://example.com/video2"]
... )
>>> core = DIContainer.create_downloader_core(config)
>>> orchestrator = AsyncOrchestrator(core, config)
>>> asyncio.run(orchestrator.run())
async run() None

Execute all configured downloads asynchronously with timing and reporting.

This method orchestrates the complete download process: 1. Validates that there are URLs to download 2. Logs the start of operations with worker and URL counts 3. Creates a thread pool with the configured number of workers 4. Submits all download tasks to the thread pool using run_in_executor 5. Waits for all downloads to complete using asyncio.gather 6. Measures total elapsed time and generates final statistics report

The method uses asyncio.gather() to wait for all downloads to complete, ensuring that statistics are only reported after all work is done. Downloads run in threads to avoid blocking the asyncio event loop, since yt-dlp operations are CPU and I/O intensive.

Raises:
Exception: Any exception from individual downloads will be propagated

after other downloads complete (due to asyncio.gather behavior).

Note:

If no URLs are configured, the method logs a warning and returns early without performing any downloads.

Example:
>>> orchestrator = AsyncOrchestrator(core, config)
>>> await orchestrator.run()
# Logs: "Starting download of 5 URLs with 4 workers"
# ... downloads execute concurrently ...
# Logs: Final statistics report with timing information
class yt_dl_cli.core.orchestration.DIContainer

Bases: object

Dependency injection container for creating fully configured downloader instances.

This class acts as a factory and dependency injection container, implementing the composition root pattern. It creates all the required components and wires them together to produce a ready-to-use downloader core with all dependencies properly injected.

The container centralizes dependency creation and management, making the system more testable and maintainable by removing direct dependencies between components.

Static Methods:

create_downloader_core: Factory method for creating configured DownloaderCore instances

Design Pattern:

This class implements the Dependency Injection Container pattern and Composition Root pattern, providing a single place where all object composition happens.

static create_downloader_core(config: Config, logger: ILogger | None = None) DownloaderCore

Create a fully configured DownloaderCore with all dependencies injected.

This factory method creates and wires together all the components needed for a functioning downloader system. It handles the complete object graph construction, ensuring all components are properly configured and connected.

Components created and wired: - Logger: Configured for the specified save directory - Format strategy: Selected based on audio_only configuration - Statistics manager: For tracking download results - File system checker: For file existence validation - Video info extractor: For metadata retrieval - Download executor: For actual download operations - DownloaderCore: Main coordinator with all dependencies injected

Args:
config (Config): Application configuration to use for component setup.

Must contain valid save_dir, quality, audio_only settings.

logger (Optional[logging.Logger], optional): Custom logger instance.

If None, creates a new logger using LoggerFactory. Defaults to None.

Returns:
DownloaderCore: Fully configured and ready-to-use downloader instance

with all dependencies properly injected and initialized.

Example:
>>> from pathlib import Path
>>> config = Config(
...     save_dir=Path("/downloads"),
...     max_workers=4,
...     quality="720",
...     audio_only=False
... )
>>> core = DIContainer.create_downloader_core(config)
>>> # core is now ready to use with all dependencies configured
Note:

This method implements the composition root pattern, centralizing all dependency creation and injection in one place. This makes the system more testable and maintainable by providing a single point of object graph construction.

Internationalization

Internationalization (i18n) utilities for application localization.

This module provides a simple interface for setting up GNU gettext-based internationalization in Python applications. It automatically detects the system locale, searches for translation files in common directory structures, and gracefully falls back to English when translations are unavailable.

The module is designed to work with standard GNU gettext .po/.mo file formats and follows common localization directory conventions used in many open-source projects.

Note:

After calling setup_i18n(), the _() function becomes globally available for string translation throughout your application.

yt_dl_cli.i18n.init.get_system_lang() str

Detect and return the system’s default language code.

This function attempts to determine the user’s preferred language by examining the system locale settings. It extracts the language portion from the full locale string and returns a standardized 2-character language code.

The function uses Python’s built-in locale module to query the system’s current locale configuration. If no locale is detected or an error occurs, it defaults to English (“en”).

Returns:
str: A 2-character language code (ISO 639-1 format).

Examples: “en” for English, “de” for German. Always returns “en” as fallback if system locale cannot be determined.

Example:
>>> get_system_lang()
'en'
Note:

The function truncates longer locale strings to just the language code. For example, “en_US.UTF-8” becomes “en”, “de_DE” becomes “de”.

yt_dl_cli.i18n.init.setup_i18n(domain: str = 'messages', localedir: str | None = None, language: str | None = None) None

Set up internationalization (i18n) for the application.

This function configures the GNU gettext internationalization system by: 1. Detecting the system’s default locale 2. Loading the appropriate translation catalog 3. Installing the translation function globally

The function automatically falls back to English if the system locale cannot be determined or if translation files are not found.

Args:
domain (str, optional): The translation domain name, typically matching

the base name of .po/.mo files. Defaults to “messages”.

localedir (str, optional): Directory path containing locale subdirectories

with translation files. Expected structure: localedir/ ├── en/ │ └── LC_MESSAGES/ │ ├── messages.po │ └── messages.mo └── … Defaults to “locales”.

Returns:

None: This function has no return value but installs translation functions globally, making _() function available for string translation.

Raises:

No exceptions are raised. If translation files are not found, the function gracefully falls back to installing a null translation that returns strings unchanged.

Note:

After calling this function, the _() function becomes globally available for translating strings. The detected language is truncated to a 2-character language code (e.g., “en_US” becomes “en”) for compatibility with most translation file naming conventions.

Internationalization and message handling for user-facing text.

This module provides a comprehensive system for managing all user-facing messages in the application with support for internationalization (i18n). It implements lazy translation loading to ensure messages are translated at display time rather than at module import time, which is crucial for proper localization support.

The module is organized into logical message groups corresponding to different application components, making it easy to maintain and extend. Each message uses the LazyTranslation pattern to defer translation until the message is actually needed, ensuring the correct locale is used.

Key Features:
  • Lazy translation loading for proper i18n support

  • Organized message groups by application component

  • Colorized console output with cross-platform support

  • Template-based messages with parameter substitution

  • Clean separation between message definitions and display logic

Example:

Basic usage of messages and console output:

>>> from messages import Messages, console_printer
>>>
>>> # Display a configuration error
>>> error_msg = Messages.Config.INVALID_WORKERS(workers=0)
>>> console_printer.printout("red", error_msg)
>>>
>>> # Display download progress
>>> start_msg = Messages.Core.START_DOWNLOAD(title="Example Video")
>>> console_printer.printout("blue", start_msg)
class yt_dl_cli.i18n.messages.LazyTranslation(template: str)

Bases: object

Deferred translation wrapper for internationalization support.

This class implements lazy evaluation of translatable strings, ensuring that translation occurs at display time rather than at module load time. This is essential for proper internationalization because:

  1. The user’s locale may not be determined at import time

  2. The translation system may not be initialized when modules are loaded

  3. The same message may need to be displayed in different locales during runtime

The class stores the message template and defers both translation and string formatting until the message is actually needed for display.

Attributes:

template (str): The original message template with optional format placeholders.

Example:
>>> msg = LazyTranslation("Hello {name}!")
>>> # Translation and formatting happen when called:
>>> translated_msg = msg(name="World")
>>> print(translated_msg)  # "Hello World!" (or translated equivalent)
class yt_dl_cli.i18n.messages.Messages

Bases: object

Container for all user-facing messages in the application.

This class serves as a centralized registry for all translatable strings used throughout the application. Messages are organized into nested classes that correspond to different application components, making it easy to locate and maintain related messages.

Each message is wrapped in a LazyTranslation object to support proper internationalization. The hierarchical organization allows for:

  • Easy maintenance and updates of message text

  • Clear association between messages and application components

  • Efficient organization for translation tools and translators

  • Type-safe access to messages through the class hierarchy

The message groups are designed to match the application’s architecture, with separate groups for configuration, core functionality, CLI interface, statistics, and various processing components.

Example:
>>> # Access configuration-related messages
>>> error = Messages.Config.INVALID_WORKERS(workers=0)
>>>
>>> # Access download progress messages
>>> start = Messages.Core.START_DOWNLOAD(title="My Video")
>>> done = Messages.Core.DONE_DOWNLOAD(title="My Video")
class CLI

Bases: object

Messages used in the command-line interface.

This group contains messages specific to the command-line interface, including file handling errors, user interaction messages, and CLI-specific error conditions.

CRITICAL_ERROR = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed for critical errors that cause application termination.

FILE_NOT_FOUND = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when a specified input file cannot be found.

FILE_READ_ERROR = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when there’s an error reading an input file.

USER_INTERRUPT = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when the user interrupts the download process (Ctrl+C).

class Config

Bases: object

Messages for configuration validation and errors.

This group contains all messages related to application configuration, including validation errors, invalid parameter notifications, and configuration-related warnings. These messages are typically displayed during application startup or when processing command-line arguments.

INVALID_QUALITY = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when an unsupported quality setting is specified.

INVALID_WORKERS = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when an invalid worker count is specified.

class Core

Bases: object

Messages used by the core downloader component.

This group contains messages related to the primary download functionality, including progress updates, completion notifications, and core operational messages. These are the most frequently displayed messages during normal application operation.

DONE_DOWNLOAD = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when a download completes successfully.

ERROR_RESOURCE_CLOSE = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when there’s an error during resource cleanup.

SKIP_EXISTS = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when a download is skipped because the file already exists.

START_DOWNLOAD = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when beginning a download operation.

class Executor

Bases: object

Messages used by the download executor component.

This group contains messages related to the actual download execution process, including error messages for failed downloads and executor-specific operational messages.

ERROR_DOWNLOAD = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when a download operation fails.

class Extractor

Bases: object

Messages used by the video extractor component.

This group contains messages related to video information extraction, which occurs before the actual download process. These messages help users understand issues with URL processing and metadata extraction.

ERROR_EXTRACT = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when video information extraction fails for a specific URL.

ERROR_NO_INFO = <yt_dl_cli.i18n.messages.LazyTranslation object>

Generic message displayed when video information cannot be extracted.

class Orchestrator

Bases: object

Messages used by the async orchestrator.

This group contains messages related to the high-level coordination of download operations, including startup messages and orchestration status updates.

NO_URLS = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when no URLs are provided for download.

STARTING = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message displayed when beginning a batch download operation.

class Stats

Bases: object

Messages and formatting used for statistics reporting.

This group contains both translatable messages and formatting constants used to display download statistics and summary reports. The constants (HEADER, FOOTER) are not translatable as they are decorative elements.

ELAPSED = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message showing total elapsed time for the operation.

FAILED = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message showing number of failed downloads.

FOOTER = '========================================'

Decorative footer line for statistics reports.

HEADER = '========================================'

Decorative header line for statistics reports.

PROCESSED = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message showing total number of items processed.

SKIPPED = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message showing number of skipped downloads.

SUCCESSFUL = <yt_dl_cli.i18n.messages.LazyTranslation object>

Message showing number of successful downloads.

TITLE = <yt_dl_cli.i18n.messages.LazyTranslation object>

Title heading for the statistics summary.

Interfaces

Protocol interfaces for dependency injection and abstraction.

This module defines Protocol classes that establish contracts for various components used throughout the application. These protocols enable loose coupling, easier testing through mock implementations, and flexible architecture by defining clear interfaces without concrete implementations.

The protocols follow the Dependency Inversion Principle, allowing high-level modules to depend on abstractions rather than concrete implementations.

class yt_dl_cli.interfaces.interfaces.IFileChecker(*args, **kwargs)

Bases: Protocol

Protocol defining the interface for file system operations.

This abstraction allows for easy testing and alternative file system implementations while maintaining a consistent interface. It provides a minimal contract for file existence checking, which is commonly needed for validation, conditional processing, and avoiding duplicate operations.

Implementations can range from direct file system access to mock implementations for testing, remote file system adapters, or cached implementations that optimize repeated checks.

The protocol focuses on existence checking as this is often the primary file system query needed in download managers, file processors, and similar applications.

exists(filepath: Path) bool

Check if a file exists at the given path.

This method should return True if a regular file exists at the specified path, and False otherwise. The behavior for directories, symbolic links, or other file system objects is implementation-defined but should be documented clearly.

Implementations should handle edge cases gracefully, such as: - Permission denied errors (typically return False) - Network timeouts for remote file systems - Invalid path formats - Non-existent parent directories

Args:
filepath (Path): A Path object representing the file location

to check. Should be an absolute or relative path that can be resolved by the underlying file system implementation.

Returns:
bool: True if the file exists and is accessible, False otherwise.

Does not distinguish between “file doesn’t exist” and “file exists but is not accessible”.

class yt_dl_cli.interfaces.interfaces.ILogger(*args, **kwargs)

Bases: Protocol

Protocol defining the interface for logger objects.

This protocol ensures that any logger implementation provides the necessary logging methods with consistent signatures for dependency injection. It abstracts the logging functionality to allow for different logging backends (standard library logging, custom loggers, or mock loggers for testing).

The protocol supports the standard logging levels and accepts flexible arguments to accommodate various logging patterns including string formatting, structured logging, and additional context via keyword arguments.

Methods should follow standard logging conventions where higher-level methods (critical, error) typically indicate more severe issues than lower-level ones (info, warning).

critical(msg: Any, *args: Any, **kwargs: Any) None

Log a critical error message.

Used for very serious error conditions that may cause the program to terminate or indicate system-level failures that require immediate attention.

Args:
msg (Any): The critical error message to log. Can be a string

with format placeholders or any object with a string representation.

*args (Any): Positional arguments for string formatting,

following Python’s % formatting convention.

**kwargs (Any): Additional keyword arguments for detailed

error reporting, stack traces, or system context.

Returns:

None

error(msg: Any, *args: Any, **kwargs: Any) None

Log an error message.

Used for error conditions that prevented a specific operation from completing successfully but don’t necessarily terminate the entire program.

Args:
msg (Any): The error message to log. Can be a string with

format placeholders or any object with a string representation.

*args (Any): Positional arguments for string formatting,

following Python’s % formatting convention.

**kwargs (Any): Additional keyword arguments such as exc_info

for exception details or stack_info for call stack.

Returns:

None

info(msg: Any, *args: Any, **kwargs: Any) None

Log an informational message.

Used for general information about program execution flow, successful operations, or non-critical status updates.

Args:
msg (Any): The message to log. Can be a string with format

placeholders or any object with a string representation.

*args (Any): Positional arguments for string formatting,

following Python’s % formatting convention.

**kwargs (Any): Additional keyword arguments that may be

used by specific logger implementations (e.g., extra context, stack info, etc.).

Returns:

None

warning(msg: Any, *args: Any, **kwargs: Any) None

Log a warning message.

Used for potentially problematic situations that don’t prevent the program from continuing but may indicate issues that should be addressed or monitored.

Args:
msg (Any): The warning message to log. Can be a string with

format placeholders or any object with a string representation.

*args (Any): Positional arguments for string formatting,

following Python’s % formatting convention.

**kwargs (Any): Additional keyword arguments for logger-specific

features like stack traces or contextual information.

Returns:

None

class yt_dl_cli.interfaces.interfaces.IStatsCollector(*args, **kwargs)

Bases: Protocol

Protocol defining the interface for statistics collection.

This protocol ensures consistent statistics tracking across different implementations, allowing for easy testing and alternative stat collectors. It provides a simple interface for recording different types of operations and generating summary reports.

Implementations should maintain internal counters for each type of recorded event and provide meaningful statistics through the report method. The protocol is designed to be thread-safe in implementations where concurrent access is expected.

The statistics collected can be used for monitoring application performance, generating user feedback, debugging issues, or creating audit trails.

record_failure() None

Record a failed operation.

This method should be called whenever an operation fails due to errors, exceptions, or other issues that prevent successful completion. Implementations should increment their failure counter and may store additional context about the failure type or cause.

Returns:

None

record_skip() None

Record a skipped operation.

This method should be called when an operation is intentionally skipped rather than attempted. Common reasons include: file already exists, operation not needed due to current state, or user-defined filtering rules that exclude the operation.

Skipped operations are distinct from failures as they represent intentional non-execution rather than failed attempts.

Returns:

None

record_success() None

Record a successful operation.

This method should be called whenever an operation (such as a download, file processing, or data transformation) completes successfully without errors. Implementations should increment their success counter and may also record additional metadata like timestamps or operation details.

Returns:

None

report(logger: ILogger, elapsed: float) None

Generate and log a comprehensive summary report of collected statistics.

This method should compile all recorded statistics into a human-readable summary and output it using the provided logger. The report typically includes counts for each operation type, percentages, rates, and timing information.

Args:
logger (ILogger): The logger instance to use for outputting the

statistics report. Should typically use info level for normal reporting.

elapsed (float): The total elapsed time in seconds for the

operations being reported. Used to calculate rates and performance metrics.

Returns:

None

Format strategy implementations for media download configuration.

This module implements the Strategy design pattern to provide flexible format selection for media downloads. It abstracts the complexity of format specification into discrete strategy classes, allowing for easy extension and testing of different download configurations.

The module provides strategies for both video and audio-only downloads, with configurable quality settings and format preferences optimized for compatibility and user experience. The factory function enables clean separation between configuration parsing and strategy instantiation.

Classes:

IFormatStrategy: Abstract base class defining the strategy interface VideoFormatStrategy: Concrete strategy for video downloads with quality control AudioFormatStrategy: Concrete strategy for audio-only downloads

Functions:

get_strategy: Factory function for creating appropriate strategy instances

Design Patterns:
  • Strategy Pattern: Encapsulates format selection algorithms

  • Factory Pattern: Provides centralized strategy instantiation

  • Abstract Base Class: Ensures consistent interface across strategies

Example:

Basic usage with different configurations:

>>> from format_strategies import get_strategy
>>>
>>> # Audio download configuration
>>> class AudioConfig:
...     audio_only = True
...     quality = "best"
>>>
>>> audio_strategy = get_strategy(AudioConfig())
>>> audio_opts = audio_strategy.get_opts()
>>> print(audio_opts)
{'format': 'bestaudio/best', 'extractaudio': True, 'audioformat': 'mp3'}
>>> # High-quality video configuration
>>> class VideoConfig:
...     audio_only = False
...     quality = "1080"
>>>
>>> video_strategy = get_strategy(VideoConfig())
>>> video_opts = video_strategy.get_opts()
>>> print(video_opts)
{'format': 'best[height<=1080][ext=mp4]', 'merge_output_format': 'mp4'}
Note:

The strategies are designed to work with yt-dlp library format specifications, but the pattern can be adapted for other download libraries by modifying the option dictionaries returned by get_opts() methods.

class yt_dl_cli.interfaces.strategies.AudioFormatStrategy

Bases: IFormatStrategy

Strategy for downloading audio-only content in MP3 format.

This strategy extracts and converts audio streams to MP3 format, providing a consistent audio-only download experience regardless of the source video format.

get_opts() Dict[str, Any]

Generate audio-only download options.

Configures the download to extract the best available audio stream and convert it to MP3 format for universal compatibility.

Returns:
Dict[str, Any]: Download options dictionary containing:
  • “format”: Audio format selector for best quality audio

  • “extractaudio”: Boolean flag to enable audio extraction

  • “audioformat”: Target audio format (MP3)

Example:
>>> strategy = AudioFormatStrategy()
>>> opts = strategy.get_opts()
>>> print(opts)
{'format': 'bestaudio/best', 'extractaudio': True, 'audioformat': 'mp3'}
class yt_dl_cli.interfaces.strategies.IFormatStrategy

Bases: ABC

Abstract base class defining the interface for download format strategies.

This interface follows the Strategy pattern to encapsulate different format selection algorithms for media downloads. Each concrete strategy implements specific logic for choosing appropriate download formats and options.

abstractmethod get_opts() Dict[str, Any]

Get download options dictionary for the specific format strategy.

Returns:

Dict[str, Any]: A dictionary containing format-specific options that can be passed to a download library (e.g., yt-dlp).

Raises:

NotImplementedError: If called on the abstract base class.

class yt_dl_cli.interfaces.strategies.VideoFormatStrategy(quality: str)

Bases: IFormatStrategy

Strategy for downloading video content with configurable quality settings.

This strategy handles video downloads with quality preferences ranging from best available quality to specific resolution limits. It prioritizes MP4 format for better compatibility across devices and platforms.

Attributes:
quality (str): Quality setting that determines format selection.

Supported values: - “best”: Downloads highest quality video+audio - “worst”: Downloads lowest quality video - Numeric string (e.g., “720”): Downloads best video up to specified height

get_opts() Dict[str, Any]

Generate video download options based on the quality setting.

Creates format selector strings optimized for video downloads: - For “best”: Selects best video+audio combination in MP4 - For “worst”: Selects lowest quality MP4 video - For numeric values: Selects best video up to specified height

Returns:
Dict[str, Any]: Download options dictionary containing:
  • “format”: Format selector string for video selection

  • “merge_output_format”: Output container format (MP4)

Example:
>>> strategy = VideoFormatStrategy("720")
>>> opts = strategy.get_opts()
>>> print(opts)
{'format': 'best[height<=720][ext=mp4]', 'merge_output_format': 'mp4'}
yt_dl_cli.interfaces.strategies.get_strategy(config) IFormatStrategy

Factory function to create appropriate format strategy based on configuration.

This function implements the Factory pattern to instantiate the correct strategy based on the provided configuration object. It abstracts the strategy selection logic from the client code.

Args:
config: Configuration object that must have at least the following attributes:
  • audio_only (bool): Flag indicating if only audio should be downloaded

  • quality (str): Video quality setting (used only when audio_only is False)

Returns:

IFormatStrategy: An instance of either AudioFormatStrategy or VideoFormatStrategy based on the configuration.

Example:
>>> class Config:
...     def __init__(self, audio_only=False, quality="best"):
...         self.audio_only = audio_only
...         self.quality = quality
>>>
>>> audio_config = Config(audio_only=True)
>>> strategy = get_strategy(audio_config)
>>> isinstance(strategy, AudioFormatStrategy)
True
>>>
>>> video_config = Config(audio_only=False, quality="720")
>>> strategy = get_strategy(video_config)
>>> isinstance(strategy, VideoFormatStrategy)
True

Scripts

Command Line Interface Entry Point Module for YT-DL-CLI Tool.

This module serves as the primary entry point for the video downloader command-line interface application. It provides a simple interface to initialize and execute the video downloading functionality through the main VideoDownloader class.

The module implements a clean separation of concerns by delegating the actual downloading logic to the main application module while providing a lightweight CLI wrapper for user interaction.

Example:

This module is typically executed as a script or called from a package entry point:

$ python scripts/cli.py

Or when installed as a package:

$ yt-dl-cli

yt_dl_cli.scripts.cli.main()

Main entry point function for the YT-DL-CLI application.

This function serves as the primary interface between the command-line environment and the core downloading functionality. It instantiates the VideoDownloader class and initiates the download process.

The function follows the single responsibility principle by focusing solely on application initialization and delegation to the core downloader logic. It handles the high-level orchestration while leaving specific download operations to the VideoDownloader class.

Workflow:
  1. Creates a new VideoDownloader instance

  2. Calls the download method to start the download process

  3. The VideoDownloader handles all user interaction, configuration, and actual downloading operations

Returns:
NoReturn: This function typically runs indefinitely or exits the

program upon completion, so it doesn’t return a value.

Raises:
SystemExit: May be raised by the VideoDownloader if a critical error

occurs or when the user requests to exit the application.

KeyboardInterrupt: May be raised if the user interrupts the process

with Ctrl+C, though this should be handled by the VideoDownloader class.

ImportError: May be raised if the main module or VideoDownloader

class cannot be imported due to missing dependencies or incorrect module structure.

Note:

This function expects the VideoDownloader class to handle all user interaction, error handling, and graceful shutdown procedures. Any configuration or initialization parameters should be handled within the VideoDownloader class itself.

See Also:

main.VideoDownloader: The core class that handles all download operations config.config: Configuration management for the application core.orchestration: Main orchestration logic for download workflows

Utils

Logging configuration factory module for the video downloader application.

This module provides a centralized logging configuration system that ensures consistent logging behavior across the entire application. It sets up both console and file-based logging with proper formatting and encoding support.

The module follows the factory pattern to create properly configured logger instances while preventing common logging pitfalls such as duplicate handlers and configuration conflicts.

Key Features: - Dual output logging (console + file) - Automatic log directory creation - UTF-8 encoding support for international characters - Singleton-like behavior to prevent handler duplication - Consistent timestamp and level formatting - Thread-safe logging operations

The logging system is designed to be robust and handle various edge cases including missing directories, encoding issues, and multiple initialization attempts.

Example:

Basic usage of the logger factory:

>>> from pathlib import Path
>>> logger = LoggerFactory.get_logger(Path("logs"))
>>> logger.info("Download started")
>>> logger.error("Failed to process video")
>>> logger.warning("Quality not available, using fallback")
Dependencies:
  • logging: Python standard library logging framework

  • pathlib: Cross-platform path handling

class yt_dl_cli.utils.logger.ColorFormatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None)

Bases: Formatter

Custom logging formatter that adds ANSI color codes to log messages.

This formatter extends the standard logging.Formatter to provide colored output for different log levels when displaying messages in the console. Colors help users quickly identify the severity of log messages.

The formatter applies different colors based on the log level: - DEBUG: Cyan - INFO: Green - WARNING: Yellow - ERROR: Red - CRITICAL: Red background

Color codes are only applied to console output and are automatically reset after each message to prevent color bleeding.

Attributes:

Inherits all attributes from logging.Formatter

Example:
>>> formatter = ColorFormatter("%(levelname)s: %(message)s")
>>> handler = logging.StreamHandler()
>>> handler.setFormatter(formatter)
>>> logger.addHandler(handler)
>>> logger.info("This will appear in green")
>>> logger.error("This will appear in red")
format(record)

Format a log record with appropriate color coding.

This method overrides the parent format method to add ANSI color codes before the formatted message and reset codes after it. The color is determined by the log level of the record.

Args:
record (logging.LogRecord): The log record to be formatted.

Contains information about the log event including level, message, timestamp, and other metadata.

Returns:
str: The formatted log message with ANSI color codes applied.

Format: “{color_code}{formatted_message}{reset_code}”

Note:
  • Uses the parent class’s format method for the base formatting

  • Only adds color codes, doesn’t change the underlying format

  • Falls back to no color (RESET) if log level is not recognized

  • Color codes are compatible with most modern terminals

class yt_dl_cli.utils.logger.LoggerFactory

Bases: object

Factory class for creating and configuring logger instances.

This factory handles the setup of logging configuration including both console and file output, ensuring consistent logging behavior throughout the application. It implements a singleton-like pattern for the root logger configuration to prevent duplicate handlers and configuration conflicts.

The factory creates loggers with standardized formatting that includes timestamps, log levels, and message content. All log files are created with UTF-8 encoding to properly handle international characters in video titles and URLs.

Design Pattern:

This class follows the Factory Method pattern, providing a centralized way to create configured logger instances while encapsulating the complexity of logging setup.

Thread Safety:

The logging configuration is thread-safe as it relies on Python’s built-in logging module, which handles concurrent access internally.

Attributes:

None (all methods are static)

Example:
>>> # Create logger for downloads directory
>>> logger = LoggerFactory.get_logger(Path("downloads"))
>>> logger.info("Application started")
>>>
>>> # Logger can be reused across modules
>>> same_logger = LoggerFactory.get_logger(Path("downloads"))
>>> same_logger.warning("This uses the same configuration")
static get_logger(save_dir: Path) Logger

Create and configure a logger instance with both console and file handlers.

This method sets up a comprehensive logging system that outputs to both the console (for immediate feedback) and a log file (for persistent record keeping). The method ensures the target directory exists and configures the root logger only once to prevent duplicate log entries.

The logging configuration includes: - DEBUG level logging (captures all log levels) - Timestamped log entries with ISO format - Standardized message format with level indicators - UTF-8 encoded file output for international character support - Colored console output for better readability - Plain text file output without color codes

Args:
save_dir (Path): Directory path where the log file will be created.

The directory will be created automatically if it doesn’t exist, including any parent directories. Must be a valid pathlib.Path object.

Returns:
logging.Logger: Configured logger instance named “video_dl_cli”

ready for immediate use. The logger is set to DEBUG level and will output to both console and the specified log file.

Raises:
OSError: May be raised if the save directory cannot be created

due to permission issues or invalid path specifications.

PermissionError: Raised if the log file cannot be created or

written to due to insufficient permissions.

Side Effects:
  • Creates the specified directory and any missing parent directories

  • Creates or appends to “download.log” file in the save directory

  • Clears existing handlers to prevent duplication

  • Configures both console and file handlers with appropriate formatters

Example:
>>> from pathlib import Path
>>>
>>> # Basic usage
>>> logger = LoggerFactory.get_logger(Path("./logs"))
>>> logger.info("Starting download process")
>>> logger.error("Failed to connect to server")
>>>
>>> # With nested directory creation
>>> logger = LoggerFactory.get_logger(Path("./app/logs/downloads"))
>>> logger.warning("Using fallback quality setting")
>>>
>>> # Debug level logging
>>> logger.debug("Detailed debugging information")
Log File Format:

The log file entries follow this format:

2024-01-15 14:30:25,123 [INFO] Download started for video XYZ 2024-01-15 14:30:26,456 [ERROR] Network timeout occurred 2024-01-15 14:30:27,789 [WARNING] Retrying download attempt

Console Output:

Console output includes the same format but with color coding applied to help distinguish between different log levels.

Note:
  • Clears existing handlers on each call to prevent duplication

  • Creates new handlers for both console and file output

  • Console handler uses ColorFormatter for colored output

  • File handler uses standard Formatter without colors

  • Log file is created with UTF-8 encoding for international support

  • The save directory is created with parents=True and exist_ok=True

Command line interface argument parsing module for the YouTube downloader CLI.

This module provides comprehensive command line argument parsing functionality for the async video downloader application. It handles URL input from both files and direct command line arguments, validates user input, and creates properly configured application settings.

Key Features: - Multiple URL input methods (file-based or direct CLI arguments) - Configurable download directory and quality settings - Concurrent download worker configuration - Audio-only download option - Robust error handling for file operations - Comment and empty line filtering in URL files

The module integrates with the application’s configuration system and internationalization framework to provide a seamless user experience.

Example:

Basic usage from command line:

$ python -m yt_dl_cli -f urls.txt -d ./downloads -w 4 -q 720 $ python -m yt_dl_cli –urls “https://youtube.com/watch?v=xyz” -a $ python -m yt_dl_cli –file links.txt –workers 3 –quality best

Dependencies:
  • argparse: Standard library argument parsing

  • pathlib: Cross-platform path handling

  • sys: System-specific parameters and functions

  • typing: Type hints for better code documentation

yt_dl_cli.utils.parser.parse_arguments() Config

Parse command line arguments and create application configuration.

This function handles all command line argument parsing and validation, including reading URLs from files or command line arguments. It provides comprehensive error handling for file operations and processes URL lists by filtering out comments and empty lines.

The function creates an ArgumentParser instance, defines all supported command line options, parses the provided arguments, and then processes the URL input according to the specified method (file or direct URLs). Finally, it constructs and returns a fully populated Config object.

Returns:
Config: Fully populated configuration object containing all parsed

settings ready for use by the download application. The Config object includes validated paths, worker counts, quality settings, and a cleaned list of URLs.

Raises:
SystemExit: Raised by argparse when invalid arguments are provided

or when –help is requested. This is standard argparse behavior and should not be caught.

Command Line Arguments:
-f, –file (str): Path to file containing URLs, one per line.

Comments (lines starting with #) and empty lines are automatically ignored. Default: “links.txt”

-d, –dir (str): Target directory for downloaded files. Directory

will be created if it doesn’t exist. Can be relative or absolute path. Default: “downloads”

-w, –workers (int): Maximum number of concurrent download workers.

Higher values may improve download speed but consume more system resources. Default: 2

-q, –quality (str): Preferred video quality for downloads.

Options: “best”, “worst”, “720”, “480”, “360” Default: “best”

-a, –audio-only (flag): When present, downloads only the audio

track instead of video. Useful for music or podcast content.

–urls (List[str]): Direct list of URLs to download. When provided,

this option overrides the –file option completely. Multiple URLs can be specified separated by spaces.

File Format:

URL files should contain one URL per line. The following format is supported:

# This is a comment line (ignored) https://youtube.com/watch?v=video1 https://youtube.com/watch?v=video2

# Empty lines above are also ignored https://youtube.com/watch?v=video3

Error Handling:
  • FileNotFoundError: When the specified URL file doesn’t exist, an error message is printed to stderr but execution continues with an empty URL list

  • Other file reading errors: Generic file reading errors are caught and reported with the specific error details

  • Invalid arguments: Handled by argparse with automatic help message display and program termination

Example:
>>> # Parse arguments from command line
>>> config = parse_arguments()
>>> print(f"Will download {len(config.urls)} videos")
>>> print(f"Save directory: {config.save_dir}")
>>> print(f"Quality: {config.quality}")
>>> print(f"Workers: {config.max_workers}")
Note:
  • URLs starting with ‘#’ in files are treated as comments and ignored

  • Empty lines in URL files are automatically filtered out

  • Whitespace around URLs is automatically stripped

  • File reading errors are reported to stderr but don’t crash the program

  • The –urls option completely overrides file-based URL input

  • Path objects are used for cross-platform compatibility

Statistics Management Module

This module provides functionality for tracking and reporting download operation statistics. It includes the StatsManager class which maintains counters for various download outcomes and generates comprehensive reports with elapsed time information.

Classes:

StatsManager: Main statistics tracking and reporting class

Dependencies:
  • dataclasses: For creating the dataclass structure

  • typing: For type hints

  • yt_dl_cli.interfaces.interfaces: For logger interface

  • yt_dl_cli.i18n.messages: For internationalized messages

class yt_dl_cli.utils.stats_manager.StatsManager(success: int = 0, failed: int = 0, skipped: int = 0)

Bases: object

Statistics manager for tracking download operations and generating reports.

This class maintains counters for different types of download outcomes and provides methods for recording events and generating summary reports. It serves as a centralized point for collecting and reporting download session statistics including success rates, failures, and performance metrics.

Attributes:

success (int): Count of successful downloads. Defaults to 0. failed (int): Count of failed downloads. Defaults to 0. skipped (int): Count of skipped downloads (files already exist). Defaults to 0.

Example:
>>> stats = StatsManager()
>>> stats.record_success()
>>> stats.record_failure()
>>> summary = stats.get_summary()
>>> print(summary['total'])  # Output: 2
failed: int = 0
get_summary() Dict[str, int]

Calculate and return a summary of all statistics.

Computes the total count by summing all individual counters and returns a comprehensive dictionary with all statistics.

Returns:
Dict[str, int]: Dictionary containing the following keys:
  • ‘success’: Number of successful downloads

  • ‘failed’: Number of failed downloads

  • ‘skipped’: Number of skipped downloads

  • ‘total’: Total number of processed items

Example:
>>> stats = StatsManager()
>>> stats.success = 5
>>> stats.failed = 2
>>> stats.skipped = 1
>>> summary = stats.get_summary()
>>> summary
{'success': 5, 'failed': 2, 'skipped': 1, 'total': 8}
record_failure() None

Increment the failure counter by one.

This method should be called whenever a download operation fails due to any error condition.

record_skip() None

Increment the skip counter by one.

This method should be called whenever a download operation is skipped, typically because the target file already exists.

record_success() None

Increment the success counter by one.

This method should be called whenever a download operation completes successfully.

report(logger: ILogger, elapsed: float) None

Generate and log a formatted summary report of download statistics.

Creates a detailed report showing the breakdown of download results and total elapsed time, formatted with visual separators for easy reading. The report includes header/footer formatting and uses internationalized messages for consistent presentation.

Args:
logger (ILogger): Logger instance to output the report. Must implement

the ILogger interface with an info() method.

elapsed (float): Total elapsed time in seconds for the download session.

Should be a positive number representing the duration.

Raises:

AttributeError: If the logger doesn’t implement the required interface.

Example:
>>> import time
>>> from unittest.mock import Mock
>>>
>>> logger = Mock()
>>> stats = StatsManager()
>>> stats.success = 10
>>> stats.failed = 2
>>>
>>> start_time = time.time()
>>> # ... perform downloads ...
>>> elapsed_time = time.time() - start_time
>>>
>>> stats.report(logger, elapsed_time)
This will log a formatted report with all statistics
skipped: int = 0
success: int = 0

File system utilities module for safe filename handling and file operations.

This module provides utilities for checking file existence and sanitizing filenames to ensure compatibility across different operating systems. The module includes two main classes:

  • FileSystemChecker: Wrapper for file system operations

  • FilenameSanitizer: Utility for sanitizing strings into safe filenames

The module is designed with testability in mind, providing abstractions that allow for easy mocking and alternative implementations.

Example:

Basic usage of the file system utilities:

>>> from pathlib import Path
>>> checker = FileSystemChecker()
>>> sanitizer = FilenameSanitizer()
>>>
>>> # Check if a file exists
>>> file_path = Path("example.txt")
>>> if checker.exists(file_path):
...     print("File exists")
>>>
>>> # Sanitize a filename
>>> safe_name = sanitizer.sanitize("Video: Title with <special> chars!")
>>> print(safe_name)  # "Video_ Title with _special_ chars!"
class yt_dl_cli.utils.utils.FileSystemChecker

Bases: object

File system operations wrapper for checking file existence.

This class provides an abstraction layer over file system operations, making the code more testable and allowing for alternative implementations. It can be easily mocked or extended for different file system backends.

Attributes:

None

Example:
>>> checker = FileSystemChecker()
>>> file_path = Path("my_file.txt")
>>> if checker.exists(file_path):
...     print("File found!")
... else:
...     print("File not found.")
ensure_dir(path)

Create a directory and all necessary parent directories.

This method ensures that a directory exists at the specified path, creating it along with any missing parent directories if needed. If the directory already exists, the method completes successfully without raising an error.

This is equivalent to the Unix ‘mkdir -p’ command and is useful for preparing directory structures before file operations.

Args:
path (str or Path): Path where the directory should be created.

Can be either a string path or a pathlib.Path object. The path can be absolute or relative to the current working directory.

Returns:
None: This method doesn’t return a value. Success is indicated

by the absence of exceptions.

Raises:
OSError: Raised if directory creation fails due to:
  • Insufficient permissions

  • Path conflicts (e.g., a file exists with the same name)

  • Filesystem errors or limitations

FileExistsError: Raised if the path exists but is not a directory

(e.g., it’s a regular file)

TypeError: If path cannot be converted to a Path object

Example:
>>> checker = FileSystemChecker()
>>>
>>> # Create a simple directory
>>> checker.ensure_dir("new_folder")
>>>
>>> # Create nested directories
>>> checker.ensure_dir("path/to/deep/folder")
>>>
>>> # Works with Path objects
>>> from pathlib import Path
>>> output_dir = Path("./output/results/data")
>>> checker.ensure_dir(output_dir)
>>>
>>> # Safe to call multiple times
>>> checker.ensure_dir("existing_folder")  # Won't raise error
Note:
  • The method creates all missing parent directories automatically

  • If any part of the path already exists as a directory, it’s preserved

  • The method is idempotent: calling it multiple times is safe

  • File permissions for created directories follow system defaults

  • On Windows, this handles long path names appropriately

exists(filepath: Path) bool

Check if a file exists at the specified path.

This method wraps the pathlib Path.exists() method to provide a consistent interface that can be easily mocked for testing or replaced with alternative implementations.

Args:
filepath (Path): Path object representing the file location

to check for existence

Returns:
bool: True if the file exists at the specified path,

False if the file does not exist or if there’s an error accessing the path

Raises:
OSError: May be raised if there are permission issues

accessing the file system (though this is rare for existence checks)

Example:
>>> from pathlib import Path
>>> checker = FileSystemChecker()
>>> file_path = Path("/home/user/document.txt")
>>> if checker.exists(file_path):
...     print("File is available")
... else:
...     print("File not found")
is_dir(path)

Check if a path represents a directory (folder).

This method determines whether the specified path points to a directory rather than a regular file or other filesystem object. It provides a consistent interface that can be easily mocked for testing purposes.

The method handles both existing and non-existing paths gracefully: - For existing paths: returns True if it’s a directory, False otherwise - For non-existing paths: returns False

Args:
path (str or Path): Path to check. Can be either a string path

or a pathlib.Path object. The path can be absolute or relative to the current working directory.

Returns:
bool: True if the path exists and is a directory,

False if the path doesn’t exist, is a file, or is another type of filesystem object

Raises:
OSError: May be raised if there are permission issues

accessing the path or its parent directory

TypeError: If path cannot be converted to a Path object

Example:
>>> checker = FileSystemChecker()
>>>
>>> # Check existing directory
>>> if checker.is_dir("/home/user/documents"):
...     print("It's a directory")
>>>
>>> # Check file (should return False)
>>> if not checker.is_dir("/home/user/file.txt"):
...     print("It's not a directory")
>>>
>>> # Works with Path objects too
>>> from pathlib import Path
>>> dir_path = Path("./my_folder")
>>> if checker.is_dir(dir_path):
...     print("Directory exists")
class yt_dl_cli.utils.utils.FilenameSanitizer

Bases: object

Utility class for sanitizing filenames to ensure file system compatibility.

This class handles the conversion of video titles and other strings into safe filenames that work across different operating systems including Windows, macOS, and Linux. It removes invalid characters and enforces length limits to prevent file system errors.

The sanitizer handles common problematic characters found in user-generated content such as video titles, avoiding issues with file creation and manipulation across different platforms.

Attributes:

None (all methods are static)

Example:
>>> sanitizer = FilenameSanitizer()
>>> title = 'My Video: "The Best" <Part 1>'
>>> safe_title = sanitizer.sanitize(title)
>>> print(safe_title)  # 'My Video_ _The Best_ _Part 1_'
static sanitize(name: str, max_length: int = 100) str

Sanitize a string to make it safe for use as a filename.

Removes or replaces characters that are invalid in filenames on most operating systems, and truncates the result to a maximum length. This method handles the most common problematic characters that cause issues across Windows, macOS, and Linux file systems.

The following characters are replaced with underscores: - < > : “ / | ? *

Args:
name (str): Original string to sanitize. Can contain any

Unicode characters, though non-ASCII characters may cause issues on some older file systems.

max_length (int, optional): Maximum length of resulting filename.

Defaults to 100 characters. Should be less than the file system’s limit (typically 255 characters).

Returns:
str: Sanitized filename safe for file system use. The result

will contain only characters that are safe across all major operating systems, with a length not exceeding the specified maximum.

Raises:

TypeError: If name is not a string or max_length is not an integer ValueError: If max_length is less than 1

Example:
>>> # Basic sanitization
>>> FilenameSanitizer.sanitize('Video: "Title"')
'Video_ _Title_'
>>> # With custom length limit
>>> long_title = "Very long video title that exceeds normal limits"
>>> FilenameSanitizer.sanitize(long_title, max_length=20)
'Very long video titl'
>>> # Handling special characters
>>> problematic = 'File<name>with:bad/chars\and|more?stuff*'
>>> FilenameSanitizer.sanitize(problematic)
'File_name_with_bad_chars_and_more_stuff_'
Note:
  • Invalid characters are replaced with underscores, not removed

  • Leading and trailing whitespace is stripped from the result

  • The method preserves the original string’s case

  • Empty strings or strings with only invalid characters will result in a string of underscores

Indices and tables