- Python 86.2%
- HTML 8.4%
- Shell 3%
- Dockerfile 2.4%
Discogs Music Library Manager
A collection of Python scripts and a web UI for managing a local FLAC music library using Discogs metadata.
Core philosophy: tags are set by the user via a dedicated tagger (e.g. Yate on macOS). Scripts enrich and organise — they never overwrite user-set tags arbitrarily. The DISCOGS_RELEASE_ID tag anchors every album to an exact Discogs release, eliminating the ambiguity that automated taggers introduce.
Why?
If you have multiple versions of the same album (original, remaster, SACD, Qobuz 24/96), automated music tools will happily collapse them into one. I've tried many; they've all mangled my collection at some point. Assigning a Discogs release ID to every album means I always know exactly which version I'm listening to, and can recover from any accidental tag overwrite as long as the release ID survives.
Features
- Web UI — FastAPI + HTMX interface: browse your library, trigger scans, fetch lyrics, organise files, sync to remote
- Configurable link buttons — up to 5 toolbar buttons linking to any URL (favicons auto-cached)
- Tag enrichment — pulls release date, original release date, and format info from the Discogs API
- File organisation — moves FLACs into
Artist/Album/track_title.flac, creates MP3 mirrors via ffmpeg - Dynamic Range scoring — per-track and per-album DR values written as FLAC tags; DR column links to loudness-war.info
- Lyrics — parallel fetching (32 workers) from lrclib.net; LRC upgrade and invalid-LRC detection
- AcoustID fingerprinting — generates and stores acoustic fingerprints
- rclone sync — mirrors the FLAC library to a remote destination
- Syslog forwarding — optional structured log forwarding to a Synology log server
- Docker support — runs on Docker Desktop (Mac) or Synology NAS
Quick Start
Local (macOS)
brew install taglib --HEAD ffmpeg rsgain rclone
cp config_demo.py config/config.py # fill in your paths and API key
uv run webui.py
Docker (local)
Create docker-compose.yml (gitignored — may contain credentials):
services:discogs:build:.ports:- "8000:8000"volumes:- ./config:/config- /path/to/flac:/flacenvironment:- CONFIG_DIR=/config- PORT=8000- RCLONE_CONFIG=/config/rclone.confdocker compose up --build
Synology NAS
./build_synology.sh # builds discogs-synology-amd64.tar
# Upload via Container Manager → Image → Add → Import from file
Then use docker-compose-synology.yml as a reference for container settings.
Configuration
Copy config_demo.py to config/config.py and set:
| Key | Description |
|---|---|
discogs_api_key |
From https://www.discogs.com/settings/developers |
flacroot |
Root of your organised FLAC library (container-internal path) |
mp3root |
MP3 mirror root |
nzbdir |
Staging directory for newly tagged FLACs |
flacroot_local |
Path as seen by the browser (for tagger deep links) |
flacroot_remote |
rclone destination remote (e.g. ROCK:/mnt/flac) |
rclone_source |
rclone source remote (e.g. FLAC:/flac) |
syslog_host / syslog_port |
Optional Synology log server |
log_file |
Log filename (written to config_dir) |
All config values are also editable via the Settings modal in the web UI.
config.py is gitignored — it contains credentials.
Tagging Suggestions
- Assign a Discogs release ID and a MusicBrainz ID for every album
- Add decent cover art
- Put source info (vendor, medium) in
DESCRIPTION(e.g."Qobuz 24/96") - For ambiguous titles or deluxe editions, put the disambiguation in
ORIGINAL_FILENAME - Use
SUBTITLEfor format variants (e.g."SACD","5.1")
Typical Workflow
- Tag FLAC files with a Discogs Release ID using Yate or similar
- Drop files into
nzbdir(staging) - Run
nzbfix.py(or click Refresh in the web UI) to enrich tags, calculate DR, generate fingerprints, fetch lyrics, and organise files into the library - Use the web UI to browse, search, and manage the library
Scripts
| Script | Purpose |
|---|---|
webui.py |
Web interface (FastAPI + HTMX) |
nzbfix.py |
Pipeline orchestrator |
fixtags.py |
Discogs API tag enrichment |
bliss.py |
File organisation + MP3 sync |
album_list.py |
Album inventory scan → CSV + DR chart |
update_lyrics.py |
Parallel lyrics fetch from lrclib.net (32 workers) |
calculate_dr.py |
Dynamic Range calculation |
calculate_fp.py |
AcoustID fingerprint generation |
convert_opus.py |
FLAC → Opus transcoding |
build_synology.sh |
Build Docker image tar for Synology upload |
All scripts use uv and declare their own dependencies via PEP 723 headers — no manual pip install needed:
uv run fixtags.py /path/to/album
Requirements
- Python ≥ 3.14 (managed automatically by uv)
- TagLib 2.x — built from source in Docker;
brew install taglib --HEADon macOS - ffmpeg, rsgain, rclone — included in the Docker image; install separately for local use
Logging
Structured logging via structlog:
- Pretty coloured output when running in a terminal
- JSON to stdout when running as a subprocess (captured and re-logged cleanly by the web UI)
- JSON log file at
config_dir/log_file - Optional syslog forwarding: set
syslog_hostandsyslog_portin config.py - Set
LOG_LEVELenv var to control verbosity (default:INFO)
Libraries and Tools
- discogs_client — Discogs API
- pytaglib — FLAC tag read/write via TagLib
- drmeter — Dynamic Range calculation
- pyacoustid — AcoustID fingerprinting
- lrclib.net — synced lyrics API
- rsgain — ReplayGain tag calculation
- FastAPI + HTMX — web UI
- structlog — structured logging