# YouTube CLI Agent Guidelines ## Project Overview This is a Python command-line interface (CLI) application for browsing and downloading YouTube videos using yt-dlp. The application provides both CLI and REST API interfaces, with support for search, pagination, playlist downloads, and network share integration. ## System Requirements ### Prerequisites (Install via system package manager) **macOS (using Homebrew):** ```bash # Install Python 3 (includes pip) brew install python # Install git brew install git ``` **Ubuntu/Debian (using apt):** ```bash # Install Python 3 and pip sudo apt update sudo apt install python3 python3-pip git # Optional: Install yt-dlp system-wide sudo apt install yt-dlp ``` **Fedora/RHEL (using dnf/yum):** ```bash # Install Python 3 and pip sudo dnf install python3 python3-pip git # or on older systems: sudo yum install python3 python3-pip git # Optional: Install yt-dlp system-wide sudo dnf install yt-dlp ``` ### Python Dependencies (Install system-wide or in virtual environment) **Option 1: System-wide installation (no virtual environment needed)** ```bash # Install Python packages system-wide pip3 install --user yt-dlp rich requests flask==2.3.3 ``` **Option 2: Virtual environment (recommended for development)** ```bash python3 -m venv venv source venv/bin/activate pip install -e . # For API development: pip install -r requirements-api.txt ``` **Option 3: Docker (isolation guaranteed)** ```bash docker-compose up --build ``` ### Installing yt-dlp **Using pip (recommended):** ```bash pip3 install --user yt-dlp ``` **Using Homebrew (macOS):** ```bash brew install yt-dlp ``` **Using apt (Ubuntu/Debian):** ```bash sudo apt install yt-dlp ``` **Note:** The application requires yt-dlp version 2023.12.0 or later for full functionality. ## Build & Deployment ### Installation from Source (After installing prerequisites) ```bash git clone cd youtube-cli pip3 install --user -e . ``` ### Running the CLI Application ```bash # Direct execution youtube-cli "search query" # Using module syntax python -m youtube_cli "search query" # Using run script ./run.sh "search query" ``` ### Running the API Server ```bash python app.py ``` The API server runs on port 4096 by default. ### Docker Deployment ```bash docker-compose up --build ``` **Persistent volumes:** - `youtube-config` → `/app/.config/youtube_cli/` (queue.json, archive.db, config.json) - `youtube-logs` → `/app/logs/` (youtube-cli.log) - `/mnt/mediaserver/Youtube` → `/mnt/mediaserver/Youtube` (downloaded videos) **Viewing logs:** ```bash # Live logs docker logs -f youtube-web # Persistent log file (survives container restart) docker exec youtube-web cat /app/logs/youtube-cli.log ``` ## Dependencies **Core dependencies (requirements.txt):** - yt-dlp - YouTube video downloading - rich - Terminal formatting and UI - requests - HTTP requests for API calls **API dependencies (requirements-api.txt):** - Flask==2.3.3 - REST API framework - All core dependencies ## Testing ### Running Tests ```bash # Run the API test script python test_api.py # Run web server tests (inside container) docker exec youtube-web python3 /app/web/server/tests/test_queue_store.py docker exec youtube-web python3 /app/web/server/tests/test_queue_api.py docker exec youtube-web python3 /app/web/server/tests/test_download_recovery.py # Run all tests with pytest (if configured) pytest ``` ### Running a Single Test ```bash # Execute specific test file python test_api.py # For pytest-based tests pytest test_api.py::test_function_name ``` ### CRITICAL: Run tests before deploying **Always run the web server tests before rebuilding and restarting the container:** ```bash # Copy test files to container docker cp web/server/tests/test_queue_store.py youtube-web:/app/web/server/tests/ docker cp web/server/tests/test_queue_api.py youtube-web:/app/web/server/tests/ docker cp web/server/tests/test_download_recovery.py youtube-web:/app/web/server/tests/ # Run tests docker exec youtube-web python3 /app/web/server/tests/test_queue_store.py docker exec youtube-web python3 /app/web/server/tests/test_queue_api.py docker exec youtube-web python3 /app/web/server/tests/test_download_recovery.py ``` If any test fails, fix the issue before deploying. ## Code Style Guidelines ### Python Conventions - **Python version:** 3.6+ - **Style:** PEP 8 compliant - **Line length:** 80 characters (strict) - **Imports:** Grouped as: standard library, third-party, local - **Type hints:** Optional but recommended for public APIs ### Import Organization ```python # 1. Standard library imports (alphabetical) import argparse import json import os import subprocess # 2. Third-party imports (alphabetical) from rich.console import Console from rich.table import Table # 3. Local imports from youtube_cli.main import YouTubeCLI ``` ### Naming Conventions - **Classes:** PascalCase (e.g., `YouTubeCLI`, `VideoHandler`) - **Functions/Variables:** snake_case (e.g., `search_videos`, `download_dir`) - **Constants:** UPPERCASE (e.g., `MAX_VIDEOS_PER_PAGE`) - **Private members:** Leading underscore (e.g., `_private_method`) ### Error Handling - Use try/except blocks for predictable error conditions - Provide user-friendly error messages using Rich color tags - Log detailed errors internally while showing simplified messages to users - Use `console.print()` with colored output for all user-facing messages: - `[red]` for errors - `[green]` for success - `[yellow]` for warnings - `[blue]` for info ### String Formatting - Use f-strings for dynamic content - Use Rich's inline markup for terminal colors: `[blue]text[/blue]` - Escape special characters in user input to prevent injection ## Architecture ### Core Components **youtube_cli/main.py** - Contains `YouTubeCLI` class with all main functionality - Handles search, download, and archive operations - Manages configuration and user interaction **youtube_cli/__main__.py** - Entry point for CLI execution - Calls `main()` from main.py **youtube_cli/__init__.py** - Package initialization - Version information **app.py** - Flask-based REST API - Provides JSON endpoints for search and download - Implements MCP (Model Context Protocol) compliance ### Data Flow 1. User input (CLI or API) 2. Request processing in `YouTubeCLI` methods 3. yt-dlp integration for YouTube operations 4. Configuration and archive management 5. Result delivery to user ## Configuration **Configuration file location:** `~/.config/youtube_cli/config.json` **Key configuration options:** - `download_dir`: Default download directory - `default_locations`: List of category folders for downloads - `max_videos_per_page`: Number of videos to display per page (default: 15) - `yt_dlp_args`: Custom yt-dlp arguments (format, thumbnail, extractor args) - `network_share_path`: Network share path for copying downloads - `default_network_subfolder`: Default subfolder on network share ### Archive System - Stores downloaded videos in `~/.config/youtube_cli/downloaded_videos.json` - Tracks videos by YouTube video ID - Prevents duplicate downloads - Supports pre-filling from existing downloads ## API Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/search` | GET | Search YouTube videos (requires `q` parameter) | | `/download` | POST | Download video by URL (requires `url` field) | | `/health` | GET | Health check endpoint | | `/version` | GET | API version info | | `/capabilities` | GET | MCP capabilities | | `/openapi.json` | GET | OpenAPI specification | **API Port:** 4096 ## Special Features ### Short Video Detection Videos with `/shorts/` in the URL are automatically detected and marked with "(short)" prefix in display. ### Pagination Search results display 15 videos per page. Users can navigate with 'n' for next page or 's' for new search. ### Category Selection Downloads require category selection from configured locations. Users can select from predefined categories or create custom folder names. ### Network Share Integration After download, videos can be automatically copied to configured network shares. ### yt-dlp Integration - Uses yt-dlp for all YouTube operations - Supports custom format selection (default: 1080p) - Handles JavaScript challenges with remote components - Automatically checks for updates ## Git Conventions - **Branch naming:** feature/branch-name or fix/branch-name - **Commit messages:** Use present tense, imperative mood - **Pull requests:** Include description of changes and testing steps ## Development Notes ### Adding New Features 1. Follow existing code structure and patterns 2. Use Rich for all terminal output 3. Implement proper error handling with user-friendly messages 4. Update documentation and README as needed 5. Test both CLI and API interfaces ### Common Patterns - Use `Path` objects for file operations - Always validate user input - Provide clear feedback during long operations - Handle timeouts for external commands (yt-dlp, API calls) - Use subprocess with proper timeout values (60s for search, 600s for download, 1200s for playlists) ### Known Constraints - Search results limited to 15 videos per page - Download timeout: 10 minutes (600 seconds) - Playlist download timeout: 20 minutes (1200 seconds) - Network share path must exist and be writable