Skip to content

Commit 116abdd

Browse files
authored
Merge pull request #10 from ronibhakta1/refactor/#9
docs: update README and API documentation for clarity and accuracy
2 parents 928e4ad + dcaa343 commit 116abdd

2 files changed

Lines changed: 187 additions & 413 deletions

File tree

README.md

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Designed to pair with [Readium Speech](https://github.com/readium/speech) and an
1414
| **Providers** | PocketTTS (v1) · Kokoro, ElevenLabs, Azure (planned) |
1515
| **Languages** | English · French · Italian · German · Spanish · Portuguese |
1616
| **Formats** | MP3 · WAV · Opus |
17-
| **Word boundaries** | Schema ready; supported when provider supplies timing data |
17+
| **Word boundaries** | Schema ready, not yet populated by any provider |
1818
| **Deployment** | Docker · CPU-only · single named volume for model weights |
1919

2020
---
@@ -45,11 +45,17 @@ curl -s -X POST http://localhost:8000/v1/synthesize \
4545
### Production
4646

4747
```bash
48-
make start # detached, restarts automatically on crash or reboot
48+
make start # detached — docker compose --profile nginx up -d
4949
make stop # stop all containers
50-
make logs # tail container logs
50+
make logs # tail app logs (nginx logs: docker compose logs -f nginx)
5151
```
5252

53+
Reachable at `http://<DOMAIN>:8080` — nginx publishes host port `8080`, plain HTTP only, no TLS termination. Put a TLS-terminating load balancer in front for a real deployment.
54+
55+
`restart: unless-stopped` is set on the **app** container only; the nginx sidecar has no restart policy (`docker-compose.yml`), so it won't come back on its own after a crash or host reboot.
56+
57+
nginx also rate-limits `/v1/synthesize` (2 req/s, burst 4) and caps connections per IP — a `503` from behind nginx under load is a plain nginx error page, not the app's Problem Details JSON.
58+
5359
---
5460

5561
## Setup wizard
@@ -200,7 +206,7 @@ Binary audio with `Content-Type: audio/mpeg` (or `audio/wav`, `audio/ogg`).
200206
}
201207
```
202208

203-
`boundaries` is `null` when the provider does not support word timing. Check `voice.boundary` before requesting — if `false`, the response will always return `null`.
209+
`boundaries` is always `null` today — no provider populates timing marks yet. Every voice reports `boundary: false`; check it before setting `boundary: true` to skip a wasted round trip.
204210

205211
Word boundary fields mirror the [Web Speech API `boundary` event](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance/boundary_event): `charIndex` and `charLength` index into the original `text`; `elapsedTime` is seconds from audio start.
206212

@@ -214,20 +220,24 @@ Word boundary fields mirror the [Web Speech API `boundary` event](https://develo
214220

215221
**Errors:**
216222

217-
All errors return a consistent shape:
223+
All errors are [RFC 9457 Problem Details](https://www.rfc-editor.org/rfc/rfc9457) (`Content-Type: application/problem+json`):
218224

219225
```json
220-
{ "error": { "code": "voice_not_found", "message": "...", "detail": null } }
226+
{ "type": "https://readium.org/speech-server/error#voice_not_found", "title": "Voice Not Found", "status": 404, "detail": "Voice 'urn:unknown' not found." }
221227
```
222228

223-
| Status | Code | Cause |
229+
| Status | Type suffix | Cause |
224230
|---|---|---|
225231
| 400 | `validation_failed` | Empty or whitespace text |
226232
| 404 | `voice_not_found` | Voice URI not registered |
227233
| 413 | `payload_too_large` | Text exceeds `MAX_TEXT_LENGTH` (default 2000 chars) |
228-
| 415 | `unsupported_format` | `format` value not in `mp3`, `wav`, `opus` |
229-
| 422 || Request schema invalid (Pydantic detail) |
230-
| 503 || Models not yet loaded |
234+
| 422 | `validation_failed` | Request schema invalid (Pydantic detail) |
235+
| 502 | `provider_error` | Provider or ffmpeg failed |
236+
| 503 | `service_not_ready` | `/readyz` only — models not loaded, ffmpeg missing, or a provider unhealthy |
237+
238+
Behind production nginx, a `503`/`429` can also come from nginx's own rate/connection limits — those are plain nginx error pages, not `application/problem+json`.
239+
240+
Full field-by-field reference, including every request/response field and what's not implemented yet: [`docs/API.md`](docs/API.md).
231241

232242
---
233243

@@ -241,13 +251,16 @@ Run `make configure` to generate `.env`, or run `bash scripts/configure.sh` dire
241251
| `HF_TOKEN` | _(empty)_ | HuggingFace token. Optional — prevents rate-limiting on first-run model downloads |
242252
| `WORKERS` | `1` | Uvicorn worker processes. Each loads a full copy of every active language model |
243253
| `MAX_CONCURRENT_SYNTHESES` | `2` | Max parallel CPU inference jobs per worker |
244-
| `API_KEY_ENABLED` | `false` | Require `X-API-Key` header on all routes |
245-
| `API_KEY` | _(empty)_ | Key value when `API_KEY_ENABLED=true` |
254+
| `API_KEY_ENABLED` | `false` | Reserved — validated at startup but **not yet enforced** on any route |
255+
| `API_KEY` | _(empty)_ | Reserved, same caveat |
246256
| `LOG_LEVEL` | `INFO` | `DEBUG` · `INFO` · `WARNING` · `ERROR` |
247257
| `PORT` | `8000` | Listen port |
248258
| `MAX_TEXT_LENGTH` | `2000` | Maximum characters per synthesis request |
249259
| `FFMPEG_BIN` | `ffmpeg` | Path to ffmpeg binary (bundled in the Docker image) |
250260
| `POCKET_DEFAULT_VOICE` | `alba` | Default voice when none is specified |
261+
| `ENABLED_PROVIDERS` | `pocket` | Comma-separated provider ids to register at startup. Only `pocket` exists today |
262+
| `DEFAULT_PROVIDER` | `pocket` | Must be one of `ENABLED_PROVIDERS` — validated at startup |
263+
| `DOMAIN` | _(empty)_ | Required when `APP_ENV=production` — used for `TrustedHostMiddleware` and nginx `server_name` |
251264

252265
**RAM estimate:** `WORKERS × active languages × ~240 MB`
253266

@@ -323,9 +336,9 @@ Client
323336
| Provider | Status | Notes |
324337
|---|---|---|
325338
| PocketTTS | Current| CPU · 6 languages · 156 voices (26 identities × 6 languages) |
326-
| Kokoro | 📆 Comming soon | Referenced, not vendored (IP cleanliness) |
327-
| ElevenLabs | 📆 Comming soon | Proxied · word boundaries supported |
328-
| Azure Speech | 📆 Comming soon | Proxied · word boundaries supported |
339+
| Kokoro | Planned | Referenced, not vendored (IP cleanliness) |
340+
| ElevenLabs | Planned | Proxied · word boundaries supported |
341+
| Azure Speech | Planned | Proxied · word boundaries supported |
329342

330343
---
331344

0 commit comments

Comments
 (0)