9.1 KiB
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):
# Install Python 3 (includes pip)
brew install python
# Install git
brew install git
Ubuntu/Debian (using apt):
# 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):
# 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)
# Install Python packages system-wide
pip3 install --user yt-dlp rich requests flask==2.3.3
Option 2: Virtual environment (recommended for development)
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)
docker-compose up --build
Installing yt-dlp
Using pip (recommended):
pip3 install --user yt-dlp
Using Homebrew (macOS):
brew install yt-dlp
Using apt (Ubuntu/Debian):
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)
git clone <repository>
cd youtube-cli
pip3 install --user -e .
Running the CLI Application
# 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
python app.py
The API server runs on port 4096 by default.
Docker Deployment
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:
# 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
# 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
# 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:
# 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
# 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
YouTubeCLIclass 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
- User input (CLI or API)
- Request processing in
YouTubeCLImethods - yt-dlp integration for YouTube operations
- Configuration and archive management
- Result delivery to user
Configuration
Configuration file location: ~/.config/youtube_cli/config.json
Key configuration options:
download_dir: Default download directorydefault_locations: List of category folders for downloadsmax_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 downloadsdefault_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
- Follow existing code structure and patterns
- Use Rich for all terminal output
- Implement proper error handling with user-friendly messages
- Update documentation and README as needed
- Test both CLI and API interfaces
Common Patterns
- Use
Pathobjects 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