Skip to content

Latest commit

 

History

History
177 lines (132 loc) · 5.31 KB

File metadata and controls

177 lines (132 loc) · 5.31 KB

HTTP API

pip install -e ".[service]"
openspeech serve --host 0.0.0.0 --port 8000 --workers 2

Interactive docs are served at /docs, generated from the same route definitions.

Long edits take minutes, which is well past what an HTTP request should hold open. Work is submitted as a job, run on a worker thread, and polled or streamed. The model is loaded once for the process lifetime rather than per request.

Meta

GET /healthz

{
  "status": "ok",
  "version": "0.1.0",
  "engine": {"name": "auk+cache", "available": true, "sample_rate": 24000, "is_mock": false},
  "queued": 0
}

is_mock tells you whether real model output is being produced. Check it in deployment.

GET /v1/ops

The full catalogue, generated from the registry — names, categories, parameters and their legal values, duration and chunking policy, and the upstream reference for each. Use it to build a UI that cannot offer an invalid value.

Planning

POST /v1/plan

Turn a request into a plan without running anything. Instant and free.

curl -s localhost:8000/v1/plan -H 'content-type: application/json' \
  -d '{"request": "clean up the noise and normalise to -16 LUFS"}'
{
  "request": "clean up the noise and normalise to -16 LUFS",
  "language": "en",
  "source": "rules",
  "ops": [
    {
      "op": "enhance_speech",
      "subtype": null,
      "params": {"cleanup_mode": "denoise"},
      "adjustments": [],
      "instruction": "Remove only the background noise, preserve everything else, and output audio of the same length."
    },
    {
      "op": "loudness_normalize",
      "params": {"target_lufs": -16.0, "true_peak_db": -1.0},
      "instruction": null
    }
  ],
  "warnings": [],
  "notes": []
}

instruction is null for operations that run in local DSP. adjustments records any parameter snapping; warnings records intents that matched nothing.

Field Type Notes
request string Required
language "en" | "zh" Optional; detected otherwise
use_llm bool Requires the llm extra and credentials

Returns 422 with an explanatory detail when nothing can be planned.

Jobs

POST /v1/jobs

multipart/form-data. Returns 202 immediately.

curl -s -X POST localhost:8000/v1/jobs \
  -F 'request=remove the noise and master to -16 LUFS' \
  -F 'audio=@interview.wav'
{"id": "9f2c4a1b7e3d5086", "status": "queued", "created_at": 1789..., "has_output": false}
Field Notes
request Required
audio Optional — omit for text-to-speech
language, use_llm, seed Optional

GET /v1/jobs/{id}

queued → running → succeeded | failed | cancelled.

Add ?progress=true for the recorded event list. A finished job carries the full run report under result: per-step verdicts, chunk counts, engine calls, repairs and quality checks.

{
  "id": "9f2c4a1b7e3d5086",
  "status": "succeeded",
  "duration": 41.2,
  "result": {
    "engine": "auk",
    "verdict": "pass",
    "duration": 2412.5,
    "steps": [
      {"op": "enhance_speech(...)", "chunks": 173, "engine_calls": 174,
       "verdict": "pass", "repairs": ["chunk 12: removed a DC offset of +0.0021"]}
    ]
  }
}

GET /v1/jobs/{id}/events

Server-sent events, one JSON object per line, from submission until the job finishes.

data: {"event": "step_start", "index": 0, "total": 2, "op": "enhance_speech(...)"}
data: {"event": "chunked", "chunks": 173, "budget_seconds": 13.95}
data: {"event": "chunk_start", "index": 0, "total": 173, "seconds": 13.4}
data: {"event": "retry", "attempt": 2, "reason": ["not_silent"]}
data: {"event": "step_end", "index": 0, "verdict": "pass"}
data: {"event": "done", "status": "succeeded"}

GET /v1/jobs/{id}/result

The finished WAV. 409 if the job has not succeeded, with the reason in detail.

DELETE /v1/jobs/{id}

Cancels a queued job. Running jobs are not interrupted; 409 says so.

GET /v1/jobs?limit=50

Recent jobs, newest first. History is bounded, so a long-lived server does not grow without limit.

Analysis

POST /v1/measure

Objective metrics for an uploaded file — the same numbers the quality gates use.

curl -s -X POST localhost:8000/v1/measure -F 'audio=@episode.wav'
{"duration": 2412.5, "sample_rate": 24000, "lufs": -16.02,
 "true_peak_dbfs": -1.00, "speech_ratio": 0.83, "f0_median_hz": 118.4, ...}

Deployment notes

  • One process, one model. AuK occupies GPU memory; --workers raises job concurrency against a single loaded model. Scale across GPUs with separate processes behind a load balancer, not with more workers.
  • Results are files on disk. They go to a temp directory by default; pass storage to create_app() for somewhere durable.
  • There is no authentication. Run it behind something that has some. It is an internal service, not an edge service.
  • Cache the engine. create_app() wraps the backend in CachedEngine by default; a shared cache directory means repeated work is paid for once.
from openspeech.service import create_app
from openspeech.engine import CachedEngine, create_engine

app = create_app(
    engine=CachedEngine(create_engine("auk"), "/var/cache/openspeech"),
    workers=2,
    storage="/var/lib/openspeech/jobs",
)