Skip to main content

ytplay

A Python CLI tool to interact with the YouTube API and manage playlist information. Created to sort playlists by video time, but it has more stuff too.

Installation

uv tool install ytplay
ytplay playlist sort
# or
uvx ytplay playlist sort

Setup

Set Up Google API Credentials

  1. Create a Google Cloud Project:

  2. Enable YouTube Data API v3:

    • Go to APIs & Services > Library
    • Search for "YouTube Data API v3" and enable it
  3. Create OAuth 2.0 Credentials:

    • Go to APIs & Services > Credentials
    • Create OAuth client ID (Desktop application)
    • Download the JSON file and rename it to client_secrets.json
    • Use ytplay auth config add /path/to/client_secrets.json to copy it to the config directory
  4. Add Test User (Important):

    • Go to APIs & Services > OAuth consent screen
    • Add your Gmail address as a test user

Configuration

The tool supports flexible configuration through environment variables and command-line options:

File Locations

Default locations:

  • Config directory: Platform-specific application data directory:
    • Windows: %APPDATA%\ytplay\ (e.g., C:\Users\Username\AppData\Roaming\ytplay\)
    • Linux: ~/.config/ytplay/ (or $XDG_CONFIG_HOME/ytplay/ if set)
    • macOS: ~/.config/ytplay/ (or $XDG_CONFIG_HOME/ytplay/ if set)
  • Client secrets: <config_dir>/client_secrets.json
  • Token file: <config_dir>/youtube.dat

Environment Variables:

export YTPLAY_CONFIG_DIR="/path/to/config"              # Set config directory
export YTPLAY_CLIENT_SECRETS="/path/to/secrets.json"    # Set client secrets path
export YTPLAY_TOKEN_FILE="/path/to/token.dat"           # Set token file path

Command-line Options:

ytplay --config-dir /path/to/config playlist list           # Set config directory
ytplay --client-secrets /path/to/secrets.json auth login    # Set client secrets path
ytplay --token-file /path/to/token.dat auth status         # Set token file path

Check Current Configuration:

ytplay auth config show    # Show current file locations and status

Add Configuration Files:

ytplay auth config add /path/to/client_secrets.json    # Copy client secrets to config directory
ytplay auth config add /path/to/file.json --name custom.json  # Copy with custom name
ytplay auth config add /path/to/file.json --force      # Overwrite existing file

Configuration Priority:

  1. Command-line options (highest priority)
  2. Environment variables
  3. Default locations (lowest priority)

Troubleshooting

Error: "client_secrets.json not found"

  • Make sure you've downloaded and renamed the OAuth credentials file
  • Verify it's placed in the config/ folder: config/client_secrets.json

Error: "Access blocked: This app's request is invalid"

  • Make sure you've added your Gmail address as a test user in the OAuth consent screen
  • Verify you're using the same Google account that you added as a test user

Error: "The OAuth client was not found"

  • Double-check that you've enabled the YouTube Data API v3 in your Google Cloud project
  • Make sure you're using the correct Google Cloud project

Usage

Quick Start

# Authenticate with YouTube
ytplay auth login --force

# List all your playlists
ytplay playlist list

# Get detailed info about a playlist
ytplay playlist info PLAYLIST_ID_HERE

# List videos with durations 
ytplay playlist videos PLAYLIST_ID_HERE --durations

# Create a sorted playlist
ytplay playlist sort PLAYLIST_ID_HERE --sort-by duration --reverse

Command Reference

Authentication:

ytplay auth login                    # Authenticate with YouTube
ytplay auth login --force            # Force reauthentication  
ytplay auth status                   # Check authentication status
ytplay auth logout                   # Remove stored credentials
ytplay auth config show             # Show current configuration paths
ytplay auth config add <path>       # Copy configuration file to config directory
ytplay auth config remove --help     # Show help for removing configuration files

Playlist Management:

ytplay playlist list                 # List all your playlists
ytplay playlist info [PLAYLIST_ID]  # Get detailed playlist info
ytplay playlist videos [PLAYLIST_ID]         # List videos in playlist
ytplay playlist videos [PLAYLIST_ID] -d     # List videos with durations
ytplay playlist sort [PLAYLIST_ID]  # Create sorted playlist copy
ytplay playlist delete [PLAYLIST_ID]        # Delete a playlist

Cache Management:

ytplay cache info                    # Show cache statistics
ytplay cache clear                   # Clear all cached data
ytplay cache clear --type videos    # Clear specific cache type

Command Options

Common Options:

  • --output/-o FILE: Save output to file
  • --format/-f FORMAT: Choose output format (text/json)
  • --no-progress: Disable progress bars
  • --no-cache: Skip cache and fetch fresh data

Sort Options:

  • --sort-by/-s CRITERIA: Sort by upload_date, duration, title, channel, or position
  • --reverse/-r: Sort in descending order
  • --title/-t TITLE: Custom title for sorted playlist
  • --privacy/-p LEVEL: Set privacy (private/public/unlisted)

Examples:

# Interactive playlist selection (if PLAYLIST_ID omitted)
ytplay playlist videos

# Save playlist info as JSON
ytplay playlist info PLxxx --output playlist.json --format json

# Create reverse-sorted playlist by duration
ytplay playlist sort PLxxx --sort-by duration --reverse --title "My Sorted Playlist"

# List videos with durations, skip cache
ytplay playlist videos PLxxx --durations --no-cache

Project Structure

The project is organized into a clean, modular structure:

sort-wl/
├── main.py                    # Entry point for the CLI application
├── pyproject.toml             # Project configuration and dependencies
├── uv.lock                    # Dependency lock file (uv sync --dev)
├── .pre-commit-config.yaml    # Pre-commit hooks configuration (uv run pre-commit install)
├── ruff.toml                  # Ruff linter/formatter configuration (uv run ruff format/check --fix)
├── src/                       # Main source code
│   ├── cli/                   # CLI interface and commands
│   │   ├── __init__.py
│   │   ├── auth_commands.py   # Authentication CLI commands
│   │   ├── cache_commands.py  # Cache management CLI commands
│   │   ├── playlist_commands.py # Playlist management CLI commands
│   │   └── common.py          # Common CLI utilities
│   ├── core/                  # Core business logic
│   │   ├── __init__.py
│   │   ├── auth.py           # YouTube API authentication
│   │   ├── cache.py          # Cache management system
│   │   ├── youtube_api.py    # YouTube API functions
│   │   └── sorting.py        # Video sorting utilities
│   ├── types/                 # Type definitions
│   │   ├── __init__.py
│   │   └── youtube.py        # YouTube API type definitions
│   ├── output/                # Output formatting
│   │   ├── __init__.py
│   │   └── formatters.py     # Display and file output functions
│   ├── config.py             # Configuration and paths
│   └── __init__.py
└── README.md

Overengineered for sure but whtv thats what happens with vibe coding.

TODO

  • Make sorting resumable
  • Make login cancelable

Metadata

Release files for ytplay 2.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ytplay 2.1.1
File Size Uploaded Provenance Actions
ytplay-2.1.1.tar.gz 58.1 kB Without provenance Details for ytplay-2.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for ytplay 2.1.1
File Interpreter ABI Platform Actions
ytplay-2.1.1-py3-none-any.whl Python 3 none any Details for ytplay-2.1.1-py3-none-any.whl

Total release size: 90.9 kB

Release files / ytplay-2.1.1.tar.gz

Download URL ytplay-2.1.1.tar.gz
Size 58.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f49fe21ba6f0d407556e5d72cd5c7084f59b66e502c01d5f431e2ef6cc110bd6
BLAKE2b-256 checksum
How to use checksums
c0d021599da643a096ad59afa0e04355e9ce5c527537b3290934403951fcaa2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.20

Release files / ytplay-2.1.1-py3-none-any.whl

Download URL ytplay-2.1.1-py3-none-any.whl
Size 32.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a22ba7ca554827fec693d9cde3d55cc02fb344ddc2c7086c67ad6ccf9ff102ce
BLAKE2b-256 checksum
How to use checksums
428323f58851c4ecd01a35ea6f1ac404d63ba15e08c78d68bc8352b653699726
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.20

Security for ytplay 2.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page