Files
x-space-downloader/docs/plans/2025-10-26-x-space-downloader-design.md
2026-08-24 03:36:49 +02:00

5.3 KiB

X Space Downloader - Design Document

Date: 2025-10-26 Status: Approved

Overview

A Python CLI tool that downloads X (Twitter) Space recordings and outputs them as MP3 files. Takes a Space URL as input and produces an audio file.

Requirements

  • Input: X Space recording URL (e.g., https://x.com/i/spaces/1ZkKzZWnVRRKv)
  • Output: MP3 audio file
  • Interface: Command-line tool
  • Authentication: Supports X account credentials via cookies
  • Scope: Recordings only (not live Spaces)
  • Error Handling: Clear error messages for invalid or non-recording URLs

Architecture Overview

Technology Choices

  • Language: Python
  • Core Engine: yt-dlp (handles X authentication and media extraction)
  • CLI Framework: Click (argument parsing and user interface)
  • Pattern: Thin wrapper around yt-dlp

Project Structure

x-space-downloader/
├── src/
│   ├── __init__.py
│   ├── main.py          # CLI entry point with argument parsing
│   ├── downloader.py    # Wraps yt-dlp functionality
│   └── validator.py     # URL validation and error handling
├── tests/
│   ├── test_validator.py
│   └── test_downloader.py
├── requirements.txt     # Dependencies: yt-dlp, click
├── setup.py            # Makes it installable
└── README.md

User Workflow

x-space-dl --cookies cookies.txt https://x.com/i/spaces/1ZkKzZWnVRRKv
# Output: space_1ZkKzZWnVRRKv.mp3

Component Design

validator.py

Responsibilities:

  • Validate URL format (must match X Spaces pattern: https://x.com/i/spaces/{SPACE_ID})
  • Check if URL points to a recording vs live Space
  • Return clear error messages for invalid inputs

Key Interface:

def validate_space_url(url: str) -> Tuple[bool, Optional[str], Optional[str]]:
    """
    Validates X Space URL.

    Returns:
        (is_valid, space_id, error_message)
    """

downloader.py

Responsibilities:

  • Configure yt-dlp options (format: mp3, quality, output template)
  • Pass cookie file to yt-dlp for authentication
  • Translate yt-dlp output/errors to user-friendly messages
  • Show download progress

Key Interface:

def download_space(
    space_url: str,
    output_dir: str,
    cookies_file: Optional[str]
) -> str:
    """
    Downloads Space recording using yt-dlp.

    Returns:
        Path to downloaded MP3 file
    """

yt-dlp Configuration:

  • Output format: mp3 (audio only)
  • Output template: space_{space_id}.mp3
  • Post-processing: convert to mp3 if needed
  • Progress hooks for user feedback

main.py

Responsibilities:

  • CLI argument parsing with Click
  • Orchestrate validation → download flow
  • Handle and display errors appropriately
  • Exit with appropriate status codes

CLI Arguments:

  • URL (required): X Space URL
  • --cookies (optional): Path to cookies file
  • --output (optional): Output directory (default: current directory)

Exit Codes:

  • 0: Success
  • 1: Invalid URL
  • 2: Download failed
  • 3: Authentication required

Data Flow

  1. User provides URL + optional cookies file
  2. Validator checks URL format → extracts space_id
  3. Downloader configures yt-dlp with:
    • Output format: mp3 (audio only)
    • Output template: space_{space_id}.mp3
    • Cookies file if provided
    • Post-processing: convert to mp3 if needed
  4. yt-dlp fetches metadata, downloads audio stream, converts to mp3
  5. Return file path to user

Error Handling

Error Scenario Detection User Message
Invalid URL format Validator regex check "Invalid URL format. Expected: https://x.com/i/spaces/{SPACE_ID}"
Space doesn't exist yt-dlp 404 error "Recording not found. Check URL or Space may be deleted."
Authentication required yt-dlp auth error "Authentication required. Please provide cookies file with --cookies"
Network errors yt-dlp timeout/connection "Network error. Check connection and try again."
Space is live Validator metadata check "Error: This is a live Space, not a recording."
Disk space/permissions File system errors "Cannot write to output directory. Check permissions and disk space."

Authentication

Cookie-based Authentication:

  • User exports cookies from logged-in X session
  • Provides cookie file path via --cookies flag
  • yt-dlp uses cookies for authenticated requests

Cookie Export Instructions:

  • Browser extensions: "Get cookies.txt", "cookies.txt"
  • Manual: Export via browser DevTools
  • Instructions included in README

Testing Strategy

Unit Tests:

  • Validator: Test various URL formats, valid/invalid patterns
  • Error message generation

Integration Tests:

  • Full download flow with yt-dlp
  • Use test Space URLs or mock yt-dlp calls
  • Cookie authentication flow

Error Scenario Tests:

  • Invalid URLs
  • Missing cookies
  • Network failures
  • Live Space detection

Dependencies

Core:

  • yt-dlp: Media downloading and extraction
  • click: CLI framework

Development:

  • pytest: Testing framework
  • pytest-mock: Mocking for tests

Future Considerations (Out of Scope)

  • Live Space recording
  • Batch downloading multiple Spaces
  • GUI interface
  • Format options beyond MP3
  • Metadata extraction (speakers, title, description)