Imported from GedeonNzemba/whisperx-api (
.github/skills/modal-deploy/SKILL.md). Install upstream withnpx skills add GedeonNzemba/whisperx-api --skill modal-deploy. Copyright stays with the author.
Modal deployment runbook (replaces the dead RunPod workflow)
Production URL: https://gedeonchrist2--api.modal.run
App: whisperx-api · workspace gedeonchrist2 · GPU L4 · scale-to-zero (10 min idle)
Deploy code changes (~7 seconds)
.venv/bin/modal deploy modal_app.py
Code (server.py, s2s/, streaming_asr.py, static/, omnivoice_tts/) is overlaid on the
registry image at deploy time — Docker rebuilds are needed ONLY when requirements or
the base image change (docker buildx build -f Dockerfile.omnivoice … --push, then
bump REGISTRY_IMAGE in modal_app.py).
Wake / warm the app
First request after idle cold-boots (~1–3 min to s2s_ready). Pre-warm before services:
curl -s https://gedeonchrist2--api.modal.run/health | python3 -m json.tool
Poll until "s2s_ready": true. IMPORTANT: continuous polling keeps the container
alive (billed) — stop polling when done.
Secrets (MT chain)
.venv/bin/modal secret create azure-translator AZURE_TRANSLATOR_KEY=… AZURE_TRANSLATOR_REGION=eastus
Attached in modal_app.py via modal.Secret.from_name. Gemini (gemini secret,
GEMINI_API_KEY) is dormant — user's Google account requires prepay.
Logs & state
.venv/bin/modal app logs whisperx-api # stream logs
.venv/bin/modal container list # running containers (empty = $0 idle)
.venv/bin/modal volume ls modal-examples # volumes; models live on models-vol at /vol/models
Validation battery
curl -s -X POST https://gedeonchrist2--api.modal.run/transcribe -F "file=@audioShort.m4a"
.venv/bin/python test_s2s.py --url https://gedeonchrist2--api.modal.run --audio audioShort.m4a --source fr --target ln --out /tmp/ln.wav
Cost guardrails
$30/mo free credits (recur monthly), usage limit $20, budget $19 → card can never be charged; apps stop instead. Dashboard: modal.com → Usage & Billing.