diff --git a/Dockerfile b/Dockerfile index 2341478..ea6eef5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,13 +36,28 @@ RUN --mount=type=cache,target=/root/.cache/pip \ # Additional voices can be downloaded at runtime into /data/voices via the # admin UI (see services/tts.py for the voice-discovery logic). # Voice catalog: https://huggingface.co/rhasspy/piper-voices -RUN mkdir -p /opt/piper-voices && cd /opt/piper-voices && \ - for VOICE in en_US-amy-medium en_US-ryan-medium; do \ - DATASET="${VOICE#en_US-}"; DATASET="${DATASET%-medium}"; \ - BASE="https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/${DATASET}/medium"; \ - curl -fsSL -o "${VOICE}.onnx" "${BASE}/${VOICE}.onnx"; \ - curl -fsSL -o "${VOICE}.onnx.json" "${BASE}/${VOICE}.onnx.json"; \ - done +# +# Using Python's urllib instead of curl/wget because python:3.14-slim +# ships neither; python is obviously available. The heredoc requires +# the BuildKit Dockerfile 1.3+ frontend, which the `# syntax=...:1` +# directive at the top of this file already pulls in. +RUN <<'PYEOF' python3 +import os, urllib.request + +VOICES = ["en_US-amy-medium", "en_US-ryan-medium"] +BASE = "https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US" +TARGET = "/opt/piper-voices" +os.makedirs(TARGET, exist_ok=True) +for v in VOICES: + dataset = v.split("-")[1] + for ext in ("onnx", "onnx.json"): + url = f"{BASE}/{dataset}/medium/{v}.{ext}" + path = os.path.join(TARGET, f"{v}.{ext}") + print(f"Downloading {url}", flush=True) + urllib.request.urlretrieve(url, path) + size = os.path.getsize(path) + print(f" -> {path} ({size:,} bytes)", flush=True) +PYEOF # Build the fable-mcp wheel so it can be served for download COPY fable-mcp/ fable-mcp/