qdp is a local Qobuz toolkit with an existing CLI/TUI downloader workflow and a local web player runtime.
Sprint 1 establishes the delivery baseline by documenting scope, backup rules, runnable commands, and packaging metadata.
- CLI entrypoint:
qdp/__main__.pyandqdp/cli.py - Interactive UI/TUI:
qdp/ui.py - Account management:
qdp/accounts.py - Local web player server:
qdp/web/server.py - Browser app assets:
qdp/web/app/ - Automated tests:
tests/ - Packaging files:
setup.py,qdp.spec,build_windows.*
- Python 3.9+
- pip
- Qobuz account credentials/config available locally
Cross-platform support: macOS / Linux / Windows / Android (Termux) / WSL
curl -fsSL https://raw.githubusercontent.com/lingion/qdp/main/install.sh | bashCustom install directory:
bash install.sh ~/my-qdpirm https://raw.githubusercontent.com/lingion/qdp/main/install.ps1 | iexOr with custom directory:
powershell -ExecutionPolicy Bypass -File install.ps1 -InstallDir C:\qdpgit clone https://github.com/lingion/qdp.git
cd qdp
bash install.sh # macOS / Linux / Termux / Git Bash
# or
powershell -File install.ps1 # Windows PowerShellThe installer automatically:
- 🔍 Detects your platform (macOS / Linux / Windows / Termux / WSL)
- 🐍 Finds Python 3.9+ (tries
python3,python,py...) - 📦 Clones or updates the repo from GitHub
- 📂 Creates a virtual environment (
.venv) - 📥 Installs all runtime dependencies
- ✅ Verifies the installation
| Platform | Installer | Venv activate | Notes |
|---|---|---|---|
| macOS | install.sh |
source .venv/bin/activate |
Needs Xcode CLI tools (xcode-select --install) |
| Linux | install.sh |
source .venv/bin/activate |
sudo apt install python3-venv if venv missing |
| Windows (Git Bash) | install.sh |
source .venv/Scripts/activate |
Install Git for Windows first |
| Windows (PowerShell) | install.ps1 |
.\.venv\Scripts\Activate.ps1 |
Run Set-ExecutionPolicy RemoteSigned if needed |
| Android (Termux) | install.sh |
source .venv/bin/activate |
pkg install python git first |
| WSL | install.sh |
source .venv/bin/activate |
Same as Linux |
Create a virtual environment and install runtime dependencies:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip setuptools wheel
python -m pip install -r requirements.txt
python -m pip install -e . --no-build-isolationExample variables are in .env.example.
The current application also reads account/config data from the local qdp config flow, especially for authenticated web-player actions.
qdpor
python -m qdpFirst-time setup:
qdp -rThe config wizard will guide you through login method, key selection (default Android key / auto-fetch web key / manual App ID & Secret), download directory, and quality preference.
qdp -s "query" # search all
qdp -sa "album name" # search albums
qdp -st "track name" # search tracks
qdp "https://www.qobuz.com/album/xxxxx" # download from URL
qdp --version # show version (114.0.1)
qdp --help # show help (works without config)python3 -m qdp.web.serverThe server prints a listening URL such as QDP web server listening on http://127.0.0.1:17890/ and keeps running until you stop it.
A reproducible local smoke sequence for the backend runtime is:
curl -i http://127.0.0.1:17890/
curl -i http://127.0.0.1:17890/app/
curl -i http://127.0.0.1:17890/nope
curl -i http://127.0.0.1:17890/stream
curl -i 'http://127.0.0.1:17890/api.json/0.2/test?x=1'
python3 scripts/webplayer_smoke.py --json
python3 -m pytest -q tests/test_web_server_runtime.py tests/test_web_player_frontend_contract.py tests/test_webplayer_smoke_cli.pywebplayer_smoke.py defaults to auto-starting a local Web Player, and also supports:
python3 scripts/webplayer_smoke.py --json— auto-start + machine-readable JSON outputpython3 scripts/webplayer_smoke.py --base-url http://127.0.0.1:17890 --no-start— reuse an existing server instancepython3 scripts/webplayer_smoke.py --base-url http://127.0.0.1:17890 --no-start --json— reuse an existing instance with stable JSON output
Expected results:
/redirects to/app//app/returns200/nopereturns404/streamwithouturlreturns400/api.json/0.2/test?x=1returns200and JSON describing the active proxy/runtime contractwebplayer_smoke.py --jsonreturns parseable JSON and validates runtime version consistency, core API routes, stream proxy behavior, and the frontend DOM contract
Add a proxies field in ~/.config/qobuz-dl/config.ini (or via the config wizard):
[DEFAULT]
proxies = https://proxy1.example.com,https://proxy2.example.comDownloads and API requests automatically rotate through proxies. Falls back to direct connection if all proxies fail.
The bundle.py module fetches Qobuz web keys. Default upstream is play.qobuz.com (official). Set QDP_BUNDLE_URL env var to use a custom mirror.
Supported runtime environment variables:
QDP_WEB_HOST— bind host for the local HTTP serverQDP_WEB_PORT— bind port for the local HTTP serverQDP_BUNDLE_URL— custom Qobuz mirror URL for web key fetchingQDP_APP_IDorQOBUZ_APP_ID— Qobuz application ID used by proxy routesQDP_AUTH_TOKEN,QOBUZ_AUTH_TOKEN, orQOBUZ_USER_AUTH_TOKEN— auth token forwarded to authenticated Qobuz API callsQDP_USER_AGENTorQOBUZ_USER_AGENT— user agent used for upstream API, asset, and stream requestsQDP_USE_TOKENorQOBUZ_USE_TOKEN— optional token-mode override
Run the existing automated test suite from the repository root:
pytest -qThe repository now ships pytest.ini so backup folders are not collected as tests.
Local-only build outputs and caches such as build/, dist/, __pycache__/, .pytest_cache/, and virtualenv directories should not be committed; they are safe to regenerate during local packaging or test runs.
If pytest is not installed yet:
python -m pip install -r requirements-build.txt
pytest -qInstall build dependencies:
python -m pip install -r requirements-build.txtBuild with PyInstaller:
python -m PyInstaller --clean --noconfirm qdp.specPreferred portable helper (works on Unix-like shells and auto-detects python3 when python is unavailable):
./build_windows.shThe helper now:
- creates an isolated
.venv-buildvirtual environment - installs runtime and build dependencies
- runs
python -m PyInstaller --clean --noconfirm qdp.spec - verifies that
dist/qdp/qdp,dist/qdp/qdp.exe, or legacy flatdist/qdp(.exe)exists - smoke-checks the artifact with
--helpbefore declaring success
Platform helpers:
build_windows.batbuild_windows.ps1build_windows.sh
- Product spec:
docs/PRD.md - Backup strategy:
docs/backup-and-restore.md - Definition of done:
docs/definition-of-done.md
The web-facing layer now has a dedicated maintenance note:
docs/webapp-maintenance.md
This area is mainly aligned with Kerry's contribution scope: web UI, browser interaction, and frontend-facing maintainability.
- Live demo: https://3d970eb7.qdp-webapp-demo.pages.dev/app/
- Deployment URL: https://3d970eb7.qdp-webapp-demo.pages.dev/app/
- Latest UI: v2.13.0 (refresh-safe app routes, mobile search chips, search history, artist-page multi-breakpoint cleanup)
- Last refreshed: 2026-06-15
- Demo mode: Static mock demo on Pages (UI/interaction showcase; not backed by a live qdp Python runtime)
Desktop search route with persistent URL and restored artist results:
Artist detail with back navigation, sticky paging info, and denser album grid:
Mobile search now has its own visible search box and focus-triggered type chips:
- Lingion: mainline integration, infrastructure, deployment, and repository quality
- Kerry1020: webapp, UI, browser-side behavior, and frontend-facing maintenance
Repository:
lingion/qdpis the canonical repository.Kerry1020/qdpis kept in lockstep as a mirror. Kerry1020 is a collaborator with write access.


