speaker-helper 0.7.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. speaker_helper-0.7.4/LICENSE +29 -0
  2. speaker_helper-0.7.4/PKG-INFO +365 -0
  3. speaker_helper-0.7.4/README.md +312 -0
  4. speaker_helper-0.7.4/pyproject.toml +136 -0
  5. speaker_helper-0.7.4/setup.cfg +4 -0
  6. speaker_helper-0.7.4/speaker_helper/__init__.py +98 -0
  7. speaker_helper-0.7.4/speaker_helper/api.py +294 -0
  8. speaker_helper-0.7.4/speaker_helper/cli.py +561 -0
  9. speaker_helper-0.7.4/speaker_helper/client.py +597 -0
  10. speaker_helper-0.7.4/speaker_helper/cloning.py +213 -0
  11. speaker_helper-0.7.4/speaker_helper/config.py +246 -0
  12. speaker_helper-0.7.4/speaker_helper/engine.py +330 -0
  13. speaker_helper-0.7.4/speaker_helper/eval/__init__.py +90 -0
  14. speaker_helper-0.7.4/speaker_helper/eval/data/en_reference.jsonl +10 -0
  15. speaker_helper-0.7.4/speaker_helper/eval/data/es_reference.jsonl +10 -0
  16. speaker_helper-0.7.4/speaker_helper/eval/data/fr_reference.jsonl +12 -0
  17. speaker_helper-0.7.4/speaker_helper/eval/dataset.py +146 -0
  18. speaker_helper-0.7.4/speaker_helper/eval/deepeval_metrics.py +141 -0
  19. speaker_helper-0.7.4/speaker_helper/eval/metrics.py +313 -0
  20. speaker_helper-0.7.4/speaker_helper/eval/multilang.py +127 -0
  21. speaker_helper-0.7.4/speaker_helper/eval/priors.py +119 -0
  22. speaker_helper-0.7.4/speaker_helper/eval/runner.py +344 -0
  23. speaker_helper-0.7.4/speaker_helper/eval/thresholds.py +92 -0
  24. speaker_helper-0.7.4/speaker_helper/eval/thresholds.yaml +17 -0
  25. speaker_helper-0.7.4/speaker_helper/profiles.py +189 -0
  26. speaker_helper-0.7.4/speaker_helper/sources.py +306 -0
  27. speaker_helper-0.7.4/speaker_helper/speaker.py +410 -0
  28. speaker_helper-0.7.4/speaker_helper/text.py +106 -0
  29. speaker_helper-0.7.4/speaker_helper/transcription.py +189 -0
  30. speaker_helper-0.7.4/speaker_helper/types.py +189 -0
  31. speaker_helper-0.7.4/speaker_helper.egg-info/PKG-INFO +365 -0
  32. speaker_helper-0.7.4/speaker_helper.egg-info/SOURCES.txt +45 -0
  33. speaker_helper-0.7.4/speaker_helper.egg-info/dependency_links.txt +1 -0
  34. speaker_helper-0.7.4/speaker_helper.egg-info/entry_points.txt +2 -0
  35. speaker_helper-0.7.4/speaker_helper.egg-info/requires.txt +35 -0
  36. speaker_helper-0.7.4/speaker_helper.egg-info/top_level.txt +1 -0
  37. speaker_helper-0.7.4/tests/test_api.py +107 -0
  38. speaker_helper-0.7.4/tests/test_cli.py +48 -0
  39. speaker_helper-0.7.4/tests/test_client.py +102 -0
  40. speaker_helper-0.7.4/tests/test_cloning.py +166 -0
  41. speaker_helper-0.7.4/tests/test_config.py +52 -0
  42. speaker_helper-0.7.4/tests/test_engine.py +100 -0
  43. speaker_helper-0.7.4/tests/test_eval.py +321 -0
  44. speaker_helper-0.7.4/tests/test_eval_deepeval.py +85 -0
  45. speaker_helper-0.7.4/tests/test_profiles.py +97 -0
  46. speaker_helper-0.7.4/tests/test_sources.py +121 -0
  47. speaker_helper-0.7.4/tests/test_text.py +48 -0
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Warith HARCHAOUI
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,365 @@
1
+ Metadata-Version: 2.4
2
+ Name: speaker-helper
3
+ Version: 0.7.4
4
+ Summary: Speaker Helper — professional Speech Synthesis (offline + streaming) over a local engine (Voicebox by default). The inverse of vocal-helper: text in, speech out. Library + CLI + REST API, with voice cloning and a built-in AI evaluation gate; runnable locally (conda + pip) or as a Docker server.
5
+ Author-email: Warith HARCHAOUI <warith@deraison.ai>
6
+ License: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/warith-harchaoui/speaker-helper
8
+ Project-URL: Issues, https://github.com/warith-harchaoui/speaker-helper/issues
9
+ Keywords: tts,text-to-speech,speech,voicebox,kokoro,streaming,offline,asyncio,real-time,french,multilingual
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
20
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Requires-Python: <3.14,>=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: os-helper>=1.5.0
25
+ Requires-Dist: audio-helper>=1.5.5
26
+ Requires-Dist: httpx>=0.27
27
+ Requires-Dist: pyyaml>=6.0
28
+ Requires-Dist: numpy>=1.24
29
+ Requires-Dist: soundfile>=0.12
30
+ Provides-Extra: server
31
+ Requires-Dist: fastapi>=0.110; extra == "server"
32
+ Requires-Dist: uvicorn>=0.29; extra == "server"
33
+ Requires-Dist: pydantic>=2.6; extra == "server"
34
+ Requires-Dist: python-multipart>=0.0.9; extra == "server"
35
+ Requires-Dist: fastapi-mcp>=0.4; extra == "server"
36
+ Provides-Extra: stt
37
+ Requires-Dist: vocal-helper>=0.3.7; extra == "stt"
38
+ Provides-Extra: youtube
39
+ Requires-Dist: youtube-helper>=1.3.3; extra == "youtube"
40
+ Provides-Extra: podcast
41
+ Requires-Dist: podcast-helper>=0.3.3; extra == "podcast"
42
+ Provides-Extra: mic
43
+ Requires-Dist: capture-helper>=0.2.2; extra == "mic"
44
+ Provides-Extra: eval
45
+ Requires-Dist: deepeval>=3; extra == "eval"
46
+ Provides-Extra: dev
47
+ Requires-Dist: pytest>=8; extra == "dev"
48
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
49
+ Requires-Dist: pytest-cov>=5; extra == "dev"
50
+ Requires-Dist: ruff>=0.6; extra == "dev"
51
+ Requires-Dist: mypy>=1.11; extra == "dev"
52
+ Dynamic: license-file
53
+
54
+ # Speaker Helper
55
+
56
+ [🇫🇷](https://github.com/warith-harchaoui/speaker-helper/blob/main/LISEZMOI.md) · [🇬🇧](https://github.com/warith-harchaoui/speaker-helper/blob/main/README.md)
57
+
58
+ [![CI](https://github.com/warith-harchaoui/speaker-helper/actions/workflows/ci.yml/badge.svg)](https://github.com/warith-harchaoui/speaker-helper/actions/workflows/ci.yml) [![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](LICENSE) [![Python](https://img.shields.io/badge/python-3.10%E2%80%933.13-blue.svg)](#)
59
+
60
+ `Speaker Helper` belongs to a collection of libraries called `AI Helpers` developed for building Artificial Intelligence.
61
+
62
+ [🌍 AI Helpers](https://harchaoui.org/warith/ai-helpers)
63
+
64
+ [![logo](https://raw.githubusercontent.com/warith-harchaoui/speaker-helper/main/assets/logo.png)](https://harchaoui.org/warith/ai-helpers)
65
+
66
+
67
+ **Professional text-to-speech — offline and streaming, with voice cloning and a
68
+ built-in evaluation gate — over a local Speech Synthesis engine
69
+ ([Voicebox](https://github.com/jamiepine/voicebox) by default).**
70
+
71
+ speaker-helper is the counterpart of
72
+ [`vocal-helper`](https://github.com/warith-harchaoui): where vocal-helper turns
73
+ *speech into text*, speaker-helper turns **text into speech**. It gives you a
74
+ small, typed Python API, a CLI, and a REST API — runnable locally (conda + pip)
75
+ or as a Docker server.
76
+
77
+ - **Two modes.** *Offline* (whole text → one audio) and *streaming*
78
+ (sentence-split, low time-to-first-audio).
79
+ - **Real-time on CPU.** The default `kokoro` engine synthesises faster than
80
+ real time (real-time factor well below 1.0) — no GPU required.
81
+ - **Backend-agnostic.** The engine is an implementation detail behind a
82
+ `TTSEngine` protocol. Voicebox is the default; a deterministic `mock` backend
83
+ ships for tests and CI, and new backends are a small, local change.
84
+ - **Voice cloning, everywhere.** Point at a recording and speaker-helper clones
85
+ the voice — in the library, CLI, and REST API. Missing transcripts are
86
+ derived automatically with [`vocal-helper`](https://github.com/warith-harchaoui).
87
+ - **Built-in AI evaluation.** A committed dataset, versioned thresholds, and
88
+ speed/anomaly/fidelity metrics gate quality in CI — no vibe checks.
89
+ - **Batteries included.** Library, CLI, REST API, Docker.
90
+
91
+ See [`EXAMPLES.md`](https://github.com/warith-harchaoui/speaker-helper/blob/main/EXAMPLES.md) for a runnable cookbook,
92
+ [`docs/tech-report.en.md`](https://github.com/warith-harchaoui/speaker-helper/blob/main/docs/tech-report.en.md) for the technical report
93
+ ([FR](https://github.com/warith-harchaoui/speaker-helper/blob/main/docs/tech-report.fr.md)), and [`LISEZMOI.md`](https://github.com/warith-harchaoui/speaker-helper/blob/main/LISEZMOI.md) for the French
94
+ readme.
95
+
96
+ ## Documentation
97
+
98
+ [💻 Documentation](https://harchaoui.org/warith/ai-helpers/docs/speaker-helper-doc/)
99
+
100
+ [📋 Examples](https://github.com/warith-harchaoui/speaker-helper/blob/main/EXAMPLES.md)
101
+
102
+ ## How it fits together
103
+
104
+ ```mermaid
105
+ flowchart LR
106
+ text["your text"]:::input
107
+ subgraph SH["speaker-helper (library · CLI · REST API)"]
108
+ speaker["Speaker<br/>offline · streaming · clone"]:::core
109
+ eval["evaluation<br/>RTF · anomalies · WER/chrF"]:::eval
110
+ end
111
+ engine["Speech Synthesis engine<br/>voicebox · mock · …"]:::engine
112
+ audio["WAV audio"]:::output
113
+
114
+ text --> speaker
115
+ speaker -- "TTSEngine protocol" --> engine
116
+ engine --> audio
117
+ speaker -.->|measured by| eval
118
+
119
+ classDef input fill:#FFF5CC,stroke:#FFCC00,color:#000000
120
+ classDef core fill:#CCE4FF,stroke:#007AFF,color:#000000
121
+ classDef eval fill:#D4F5D9,stroke:#28CD41,color:#000000
122
+ classDef engine fill:#EFDCF8,stroke:#AF52DE,color:#000000
123
+ classDef output fill:#FFEACC,stroke:#FF9500,color:#000000
124
+ ```
125
+
126
+ speaker-helper talks only to the `TTSEngine` protocol, so the concrete engine
127
+ (Voicebox by default) is swappable. Start an engine once, then point
128
+ speaker-helper at it.
129
+
130
+ ---
131
+
132
+ ## Installation
133
+
134
+ **Prerequisites** — **Python 3.10–3.13** and **git**, **libsndfile**, **ffmpeg**, cross-platform. `soundfile` needs the native `libsndfile` library, and `audio-helper` (voice-clone trimming / concatenation) uses `ffmpeg`:
135
+
136
+ - 🍎 **macOS** ([Homebrew](https://brew.sh)): `brew install python git libsndfile ffmpeg`
137
+ - 🐧 **Ubuntu/Debian**: `sudo apt update && sudo apt install -y python3 python3-pip git libsndfile1 ffmpeg`
138
+ - 🪟 **Windows** (PowerShell): `winget install Python.Python.3.12 Git.Git ffmpeg` (`libsndfile` is bundled with the `soundfile` wheel — no separate install).
139
+
140
+ We recommend using Python environments. Check this link if you're unfamiliar with setting one up: [🥸 Tech tips](https://harchaoui.org/warith/4ml/#install).
141
+
142
+ ### From source
143
+
144
+ speaker-helper is **not on PyPI yet** (PyPI release coming soon). Like the other
145
+ `*-helper` projects, it installs from git, pinned to a release tag:
146
+
147
+ ```bash
148
+ # core
149
+ pip install "git+https://github.com/warith-harchaoui/speaker-helper.git@v0.7.4"
150
+ # with extras (server + MCP, and STT for cloning/eval round-trip):
151
+ pip install "speaker-helper[server,stt] @ git+https://github.com/warith-harchaoui/speaker-helper.git@v0.7.4"
152
+ ```
153
+
154
+ Available extras: `server` (REST API + MCP), `stt` (vocal-helper), `youtube`,
155
+ `podcast`, `mic` (speech-to-speech sources), `eval` (DeepEval), `dev`.
156
+
157
+ Or, for local development (conda + pip):
158
+
159
+ ```bash
160
+ conda create -n speaker-helper python=3.11 -y
161
+ conda activate speaker-helper
162
+ pip install -e ".[server]" # add ",dev" for the test/lint toolchain
163
+ pip install -e ".[server,stt]" # add ",stt" to auto-transcribe clone references
164
+ ```
165
+
166
+ speaker-helper is part of the **AI Helpers** ecosystem: it installs
167
+ [`os-helper`](https://github.com/warith-harchaoui/os-helper) (logging) and
168
+ [`audio-helper`](https://github.com/warith-harchaoui/audio-helper) (audio
169
+ slicing/concatenation) automatically. The optional `stt` extra adds
170
+ [`vocal-helper`](https://github.com/warith-harchaoui/vocal-helper) for
171
+ transcribing voice-clone references and the evaluation round-trip.
172
+
173
+ ### A Voicebox engine
174
+
175
+ speaker-helper needs a running Voicebox.
176
+
177
+ - **Apple Silicon (recommended): native MLX Voicebox on `:17493`.** It uses the
178
+ Apple **GPU** and is markedly faster (well under real time). This is
179
+ speaker-helper's default port, so no override is needed. Note: Docker on macOS
180
+ has **no GPU/Metal passthrough**, so only the native build gets the GPU.
181
+ - **CPU / Docker on `:17600`** (portable, no GPU): fine for functionality;
182
+ real-time factor is borderline and load-sensitive on CPU (see
183
+ [`BENCHMARKS.md`](https://github.com/warith-harchaoui/speaker-helper/blob/main/BENCHMARKS.md)).
184
+
185
+ ```bash
186
+ git clone https://github.com/jamiepine/voicebox && cd voicebox
187
+ docker compose up --build # serves on 127.0.0.1:17600
188
+ ```
189
+
190
+ Then tell speaker-helper where it is (`--port`, `settings.yaml`, or
191
+ `SPEAKER_HELPER_VOICEBOX_PORT`).
192
+
193
+ ---
194
+
195
+ ## Quickstart
196
+
197
+ ### Python
198
+
199
+ ```python
200
+ from speaker_helper import Speaker, Settings
201
+
202
+ spk = Speaker(Settings.from_mapping({
203
+ "engine": "kokoro", "language": "fr", "voicebox": {"port": 17600},
204
+ }))
205
+ result = spk.save("Bonjour le monde.", "hello.wav")
206
+ print(f"{result.duration_s:.2f}s audio, RTF {result.rtf:.2f}")
207
+ # 2.80s audio, RTF 0.43
208
+ ```
209
+
210
+ ### CLI
211
+
212
+ ```bash
213
+ speaker-helper --port 17600 voices --engine kokoro
214
+ speaker-helper --port 17600 synth "Bonjour le monde." -o hello.wav
215
+ speaker-helper --port 17600 synth "Une. Deux. Trois." -o out.wav --stream
216
+ speaker-helper --backend mock eval # gate quality (no engine needed)
217
+ speaker-helper --port 17600 --clone synth "Bonjour." -o cloned.wav
218
+ ```
219
+
220
+ ### REST API server
221
+
222
+ ```bash
223
+ speaker-helper --port 17600 serve --host 0.0.0.0 --port 8080
224
+ curl -s -X POST localhost:8080/synth -H 'content-type: application/json' \
225
+ -d '{"text": "Bonjour."}' -o out.wav
226
+ # streaming (Server-Sent Events, one JSON chunk per sentence):
227
+ curl -N -X POST localhost:8080/synth/stream -H 'content-type: application/json' \
228
+ -d '{"text": "Une. Deux. Trois."}'
229
+ ```
230
+
231
+ The server also mounts a **Model Context Protocol** endpoint at `/mcp` (via
232
+ [`fastapi-mcp`](https://github.com/tadata-org/fastapi-mcp), bundled with the
233
+ `server` extra), exposing `synth`, `synth_stream`, `clone_voice`, `list_voices`,
234
+ and `health` as MCP tools an assistant can call directly.
235
+
236
+ Or with Docker (server points at a Voicebox on the host):
237
+
238
+ ```bash
239
+ docker compose up --build # speaker-helper API on :8080
240
+ ```
241
+
242
+ ---
243
+
244
+ ## Voice cloning
245
+
246
+ Point at a recording and speaker-helper clones the voice — in the library, CLI,
247
+ and REST API. If you do not supply a transcript of the reference, it is derived
248
+ automatically with [`vocal-helper`](https://github.com/warith-harchaoui) (install
249
+ the `stt` extra). A ready-to-use reference (`assets/ref-malo.wav`) ships as the
250
+ default.
251
+
252
+ ```python
253
+ from speaker_helper import Speaker, Settings, VoiceSample
254
+
255
+ spk = Speaker(Settings.from_mapping({"engine": "chatterbox", "voicebox": {"port": 17600}}))
256
+ # give only the audio — the transcript is transcribed and aligned for you:
257
+ await spk.clone_voice("malo", [VoiceSample("my_voice.wav", "")])
258
+ result = await spk.say("Maintenant je parle avec la voix clonée.")
259
+ ```
260
+
261
+ ```bash
262
+ speaker-helper --port 17600 clone # clone the bundled ref-malo, print id
263
+ speaker-helper --port 17600 --clone-audio my_voice.wav synth "Bonjour." -o out.wav
264
+ ```
265
+
266
+ Reference audio longer than the engine's limit (Voicebox: 30 s) is trimmed
267
+ automatically (via [`audio-helper`](https://github.com/warith-harchaoui)) and
268
+ re-transcribed so audio and text stay aligned.
269
+
270
+ ---
271
+
272
+ ## Speech-to-speech (re-voicing)
273
+
274
+ Bring audio in from the AI Helpers source packages and re-voice it — transcribed
275
+ with [`vocal-helper`](https://github.com/warith-harchaoui) and spoken back
276
+ (optionally in a cloned voice or another language):
277
+
278
+ ```python
279
+ import asyncio
280
+ from speaker_helper import Speaker, Settings
281
+ from speaker_helper.sources import from_youtube, revoice
282
+
283
+ async def main() -> None:
284
+ src = from_youtube("https://youtu.be/…") # extra: youtube
285
+ async with Speaker(Settings.from_mapping({"voicebox": {"port": 17600}})) as spk:
286
+ out = await revoice(src, spk) # transcribe + re-speak
287
+ open("revoiced.wav", "wb").write(out.wav_bytes)
288
+
289
+ asyncio.run(main())
290
+ ```
291
+
292
+ ```bash
293
+ speaker-helper --port 17600 speak-from --source youtube --url https://youtu.be/… -o out.wav
294
+ speaker-helper --port 17600 speak-from --source podcast --url https://feed/rss -o out.wav
295
+ speaker-helper --port 17600 --clone speak-from --source mic --seconds 5 -o out.wav
296
+ ```
297
+
298
+ Sources are optional extras: `youtube` (`youtube-helper`), `podcast`
299
+ (`podcast-helper`), `mic` (`capture-helper`).
300
+
301
+ ---
302
+
303
+ ## Evaluation (no vibe checks)
304
+
305
+ Quality is gated, not guessed. `speaker-helper eval` runs the engine over a
306
+ committed dataset and checks versioned thresholds — **synthesis faster than real
307
+ time**, **zero audio anomalies** (empty / clipped / aberrant duration), and,
308
+ with an STT transcriber wired in, a WER/chrF **round-trip**. It exits non-zero
309
+ when the bar is missed, so it gates CI.
310
+
311
+ ```bash
312
+ speaker-helper --backend mock eval # deterministic, no engine
313
+ speaker-helper --port 17600 --engine kokoro eval --json report.json
314
+ # backend=voicebox engine=kokoro cases=12
315
+ # mean_rtf=0.3534 p95_rtf=0.3989 anomaly_rate=0.0 quality=0.75 (prior)
316
+ # PASS
317
+ ```
318
+
319
+ The evaluation targets the engine-agnostic `Speaker`, so the same gate grades
320
+ the `mock` backend in CI or a real engine locally — only `--backend` differs.
321
+
322
+ For teams standardising on a framework, the `eval` extra adds a
323
+ [DeepEval](https://github.com/confident-ai/deepeval) binding
324
+ (`RealTimeFactorMetric`, `AudioIntegrityMetric`) that reports the same
325
+ measurements as DeepEval custom metrics — deterministic and offline.
326
+
327
+ ---
328
+
329
+ ## Configuration
330
+
331
+ Copy [`settings.yaml.example`](https://github.com/warith-harchaoui/speaker-helper/blob/main/settings.yaml.example) to `settings.yaml` (it is
332
+ gitignored) or use [`speaker_config.json.example`](https://github.com/warith-harchaoui/speaker-helper/blob/main/speaker_config.json.example)
333
+ as a reference. Every key can be overridden by a `SPEAKER_HELPER_*` environment
334
+ variable; `${VAR}` references inside the YAML are expanded from the environment.
335
+
336
+ ---
337
+
338
+ ## Development
339
+
340
+ ```bash
341
+ pip install -e ".[dev,server]"
342
+ pytest -q -m "not slow" # fast, deterministic suite (no engine needed)
343
+ pytest -q # also runs @slow live tests (needs Voicebox)
344
+ ruff check speaker_helper tests
345
+ speaker-helper --backend mock eval # run the evaluation gate locally
346
+ ```
347
+
348
+ CI runs ruff + the fast suite on Python 3.10–3.13; a failing test blocks merges.
349
+ The fast suite drives the deterministic `mock` backend, so it needs no engine.
350
+
351
+ ---
352
+
353
+ ## Author
354
+
355
+ - [Warith HARCHAOUI](https://linkedin.com/in/warith-harchaoui)
356
+
357
+ ## Acknowledgements
358
+
359
+ Special thanks to the contributors, reviewers, and users who helped improve
360
+ this project — and to the [Voicebox](https://github.com/jamiepine/voicebox)
361
+ authors for the engine speaker-helper builds on.
362
+
363
+ ## License
364
+
365
+ BSD-3-Clause © Warith HARCHAOUI.