YouTube now gates downloadable formats behind JS challenges (nsig); yt-dlp needs a JavaScript runtime (Deno — its only default-enabled one) to solve them, and its STABLE channel can lag months behind a breaking YouTube change. Users hit "Requested format is not available" on every stream and music-video download with no hint why. Neither piece is fixable via requirements.txt: Deno isn't a Python package, and a version floor can only ever resolve stable. - Dockerfile: install Deno in the runtime image (official installer, auto-detects amd64/arm64, build fails early via `deno --version` if it breaks; unzip added for the installer) and build with the yt-dlp NIGHTLY channel (`pip install -U --pre "yt-dlp[default]"`) on top of requirements - core/youtube_client.py: one-time startup warning when deno isn't on PATH, naming the exact failure it causes and the install command — instead of letting users debug a cryptic yt-dlp format error - requirements.txt: annotate the yt-dlp line with the stable-lag caveat, the nightly upgrade command, and the Deno requirement - README: Deno + nightly notes in Prerequisites and the Python (No Docker) install section; Docker bundles both automatically
84 lines
3 KiB
Text
84 lines
3 KiB
Text
# SoulSync requirements
|
|
# Web application dependencies only
|
|
# All dependencies pinned for reproducible builds.
|
|
|
|
# Core web framework
|
|
Flask==3.1.3
|
|
Flask-Limiter==4.1.1
|
|
|
|
# Music service APIs
|
|
spotipy==2.26.0
|
|
PlexAPI==4.18.1
|
|
|
|
# HTTP and async support
|
|
requests==2.33.1
|
|
aiohttp==3.13.5
|
|
|
|
# Security and encryption
|
|
cryptography==48.0.0
|
|
|
|
# Media metadata handling
|
|
mutagen==1.47.0
|
|
Pillow==12.2.0
|
|
|
|
# Text processing
|
|
Unidecode==1.4.0
|
|
beautifulsoup4==4.14.3
|
|
|
|
# System monitoring
|
|
psutil==7.2.2
|
|
|
|
# IANA timezone data — required by ``zoneinfo`` on Windows hosts and
|
|
# minimal Docker base images that ship without the system tz database.
|
|
# Consumed by ``core/automation/schedule.py`` for daily / weekly /
|
|
# monthly schedule next-run computation in the user's local timezone.
|
|
# Loose-pinned because IANA tz data changes a few times a year for
|
|
# real-world DST policy updates; pinning to one snapshot would freeze
|
|
# the app's tz knowledge to the build date.
|
|
tzdata>=2024.1
|
|
|
|
# Cross-platform IANA timezone detection — returns the server's local
|
|
# tz as a string ('America/Los_Angeles', not 'PDT'). Consumed by the
|
|
# automation engine to preserve historic behaviour for daily / weekly
|
|
# trigger rows that don't carry an explicit ``tz`` field: the old
|
|
# engine computed delays from naive ``datetime.now()``, which is
|
|
# implicitly the server's local tz, so falling back to the same tz
|
|
# keeps existing schedules running at the same wall-clock time.
|
|
tzlocal>=5.0
|
|
|
|
# YouTube support -- unpinned; yt-dlp must track upstream releases to stay functional.
|
|
# NOTE: pip resolves this to the latest STABLE release, which can lag months
|
|
# behind a breaking YouTube change. If streams/music-video downloads fail with
|
|
# "Requested format is not available", switch to the nightly channel:
|
|
# pip install -U --pre "yt-dlp[default]"
|
|
# YouTube extraction ALSO requires a JavaScript runtime (Deno) on the system --
|
|
# it is NOT a Python package and cannot be listed here. Docker images bundle
|
|
# it; bare-metal installs need it on PATH: https://docs.deno.com/runtime/
|
|
yt-dlp>=2026.3.17
|
|
|
|
# Lyrics support
|
|
lrclibapi==0.3.1
|
|
|
|
# Audio fingerprinting for download verification
|
|
pyacoustid==1.3.1
|
|
|
|
# WebSocket client for Hydrabase connection
|
|
websocket-client==1.9.0
|
|
|
|
# Tidal download support
|
|
tidalapi==0.8.11
|
|
|
|
# WebSocket server for real-time UI updates
|
|
flask-socketio==5.6.1
|
|
gunicorn==26.0.0
|
|
simple-websocket==1.1.0
|
|
|
|
# Full public-playlist link imports (no Spotify credentials). The "Spotify link"
|
|
# tab scrapes Spotify's embed widget, which caps at ~100 tracks; SpotipyFree
|
|
# (the no-creds spotipy drop-in spotDL uses) pulls the full list. It is GPL-3.0,
|
|
# used here as a normal pip dependency — aggregation, exactly like spotDL (also
|
|
# MIT). It is NOT vendored into SoulSync's own code, so the project stays MIT.
|
|
# The code soft-imports it and falls back to the embed scraper (~100 tracks) if
|
|
# it's missing or fails, so this is never a hard runtime requirement.
|
|
spotipyFree>=1.1.2,<2
|
|
websockets>=12 # required by SpotipyFree/spotapi, not pulled in automatically
|