Spaces:
Running
Deployment Guide β YouTube Translator & Speaker (hardened v2)
Two supported ways to run this. Docker Space is recommended (bakes in a pinned
deno runtime β no cold-start download, no curl|sh supply-chain risk). The plain
Gradio SDK path still works as a fallback (app.py auto-installs deno on first boot).
Required Space Secrets (both deployment types)
Set these under Settings β Variables and secrets β New secret (they must be Secrets, not public Variables):
| Secret | Value |
|---|---|
WEBSHARE_PROXY_UN |
your Webshare proxy username |
WEBSHARE_PROXY_PW |
your Webshare proxy password |
ELEVENLABS_API_KEY |
your ElevenLabs API key |
Option A β Docker Space (recommended)
What you do, step by step
- In your Space, go to Settings. Under Space SDK, change it from
GradiotoDocker. (Equivalently, setsdk: dockerin theREADME.mdmetadata header β see the header block below.) - Upload these three files to the Space repo root:
Dockerfilerequirements.txtapp.py
- Add the three Secrets above.
- The Space rebuilds automatically. Docker builds take a few minutes (it builds a full image once); after that, startup is fast because deno is already baked in.
Space README.md metadata header (top of your Space's README.md)
---
title: YouTube Translator And Speaker
emoji: π§
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false
---
Why this is the cleaner option
- deno (pinned to 2.9.3) and yt-dlp (pinned to 2026.7.4) are installed at build time β no 30s runtime install, no dependence on deno.land at boot.
- No
curl | shexecuted on every restart β removes that supply-chain risk.
Option B β Gradio SDK Space (fallback)
What you do
- Keep the Space SDK as
Gradio. - Upload
requirements.txtandapp.py(no Dockerfile needed). - Add the three Secrets above.
Tradeoffs
app.pyinstalls deno into/tmpon first boot (~30s cold start, re-runs on each Space restart) and executes the deno.land install script at runtime.- Works, but is slower to start and less locked-down than the Docker option.
Maintenance β the one thing to watch
yt-dlp is pinned in requirements.txt. YouTube periodically changes its
extraction and breaks older yt-dlp versions. When transcripts start failing:
- Bump the
yt-dlp==pin to the latest release. - Redeploy and test one known video. Do not leave yt-dlp unpinned/floating in production β a surprise upstream change could silently break the Space.
Known dependency pins & why (do not unpin)
Every version in requirements.txt is pinned deliberately. Two pins in
particular exist to prevent silent dependency drift β cases where your own
code never changes but an unpinned upstream package updates and breaks the
Space on the next rebuild. If someone "cleans up" these pins, the Space will
break again.
| Pin | Why it's locked |
|---|---|
pydantic==2.10.6 |
Critical β do not unpin. gradio==4.44.1 only requires pydantic>=2.0 (open-ended) and ships gradio-client==1.3.0. pydantic 2.11.x emits JSON schemas with bare booleans (additionalProperties: true) that gradio-client 1.3.0 cannot parse. Result: TypeError: argument of type 'bool' is not iterable in get_api_info() at startup. 2.10.6 is the last known-good release for this gradio combo. Refs: Gradio #10649, Gradio #11722, HF Forums. |
fastapi==0.112.4 + starlette==0.38.6 |
Critical β do not unpin. gradio==4.44.1 only requires fastapi<1.0 (no lower bound). On rebuild pip pulled fastapi 1.x β starlette 1.x, which changed the TemplateResponse signature (first positional arg is now the request, not the template name). gradio 4.44.1 still calls the old TemplateResponse(name, context) form, so the context dict is passed as the template name β jinja2 tries to hash a dict β TypeError: unhashable type: 'dict', a 500 on every page (which also surfaces as the share=True / "localhost not accessible" ValueError at launch). These two are pinned as a consistent pre-1.0 pair (fastapi 0.112.4 requires starlette>=0.37.2,<0.39.0). Refs: FastAPI #15198, HF Space fix commit. |
yt-dlp==2026.7.4 |
YouTube periodically changes extraction and breaks older yt-dlp. This is the one pin you bump deliberately (see Maintenance above) β but always to a specific release, never floating. |
gradio==4.44.1 |
The app's gr.Interface uses allow_flagging="never", which is the 4.x parameter name. Upgrading to gradio 5.x renames it to flagging_mode="never" and can change Interface/Dropdown behavior. Stay on 4.44.1 unless you deliberately migrate and re-test. |
torch==2.4.1, transformers==4.44.2, sentencepiece, sacremoses, accelerate |
NLLB translation stack. Locked together as a tested set β bumping torch/transformers independently can pull incompatible CUDA/tokenizer combos. |
Rule of thumb: if transcripts break β bump yt-dlp only. If the Space
crashes at startup with a schema/bool/get_api_info traceback after a
rebuild β check pydantic first. If it 500s on every page with unhashable type: 'dict' (jinja2/TemplateResponse) β check fastapi/starlette. All
three are symptoms of the same root cause: gradio 4.44.1's open-ended pins on
pydantic, fastapi, and starlette let newer, incompatible versions slip in on
rebuild. Keep all three pinned.
What was verified before shipping (against video vd0fMpAIs1s)
- English transcript fetched through the SOCKS5 proxy: β (1,925 chars)
- French native caption fetched in the same single extraction: β (2,259 chars)
- Arabic auto-translated caption fetched: β (earlier run, 1,755 chars)
- Input validation (URL β ID, bad-ID rejection): β
- Proxy credentials scrubbed from logs/errors: β
- deno auto-install on a clean boot (Gradio fallback path): β