Spaces:
Sleeping
Sleeping
Commit Β·
439e009
1
Parent(s): 842fed4
Add YouTube-access health check; confirm stale length-cap UI is gone
Browse files- New "Check YouTube access" button reports YT_PROXY/YT_COOKIES/YOUTUBE_API_KEY status,
the Space's egress IP (via proxy if set), and live YouTube reachability with a
green/red verdict pointing at tools/ when blocked
- run status notes when YT_PROXY is active
- (Re-architecture already removed the self-contradictory "Max video length (min)" slider,
the per-user "Proxy URL" field, and the "Whisper timing" label β verified absent)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
app.py
CHANGED
|
@@ -88,6 +88,35 @@ def _resolve_api_key(ui_key: str | None) -> str | None:
|
|
| 88 |
return key or None
|
| 89 |
|
| 90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
# ----------------------------------------------------------------------------- helpers
|
| 92 |
def _ranking_rows(scored: list[dict]) -> list[list]:
|
| 93 |
rows = []
|
|
@@ -140,6 +169,8 @@ def run_pipeline(topic, hf_token, yt_api_key, llm_model, vlm_model,
|
|
| 140 |
api_key = _resolve_api_key(yt_api_key)
|
| 141 |
cookiefile = _cookiefile(workdir)
|
| 142 |
proxy = _resolve_proxy()
|
|
|
|
|
|
|
| 143 |
|
| 144 |
# 1. Search ------------------------------------------------------------------
|
| 145 |
progress(0.03, desc="Searching")
|
|
@@ -266,6 +297,10 @@ def build_ui():
|
|
| 266 |
lead = gr.Slider(0.0, 5.0, value=1.0, step=0.5, label="Lead offset (s)")
|
| 267 |
max_shots = gr.Slider(1, 15, value=8, step=1, label="Max screenshots")
|
| 268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 269 |
run_btn = gr.Button("Generate tutorial", variant="primary")
|
| 270 |
|
| 271 |
status_md = gr.Markdown(label="Status")
|
|
@@ -276,6 +311,7 @@ def build_ui():
|
|
| 276 |
transcript_box = gr.Textbox(label="Transcript preview", lines=10, max_lines=20)
|
| 277 |
docx_file = gr.File(label="Download tutorial (.docx)")
|
| 278 |
|
|
|
|
| 279 |
run_btn.click(
|
| 280 |
run_pipeline,
|
| 281 |
inputs=[topic, hf_token, yt_api_key, llm_model, vlm_model,
|
|
|
|
| 88 |
return key or None
|
| 89 |
|
| 90 |
|
| 91 |
+
def check_access():
|
| 92 |
+
"""Health check: which secrets are set, the egress IP, and YouTube reachability."""
|
| 93 |
+
import requests
|
| 94 |
+
|
| 95 |
+
proxy = _resolve_proxy()
|
| 96 |
+
proxies = {"http": proxy, "https": proxy} if proxy else None
|
| 97 |
+
lines = [
|
| 98 |
+
f"- **Proxy** (`YT_PROXY`): {'set β
' if proxy else 'not set βͺ'}",
|
| 99 |
+
f"- **Cookies** (`YT_COOKIES`): {'set β
' if os.environ.get('YT_COOKIES') else 'not set βͺ'}",
|
| 100 |
+
f"- **Data API key** (`YOUTUBE_API_KEY`): {'set β
' if os.environ.get('YOUTUBE_API_KEY') else 'not set βͺ'}",
|
| 101 |
+
]
|
| 102 |
+
try:
|
| 103 |
+
ip = requests.get("https://api.ipify.org", proxies=proxies, timeout=20).text.strip()
|
| 104 |
+
lines.append(f"- **Egress IP** {'(via proxy)' if proxy else '(Space direct)'}: `{ip}`")
|
| 105 |
+
except Exception as exc:
|
| 106 |
+
lines.append(f"- **Egress IP**: β {type(exc).__name__}")
|
| 107 |
+
try:
|
| 108 |
+
r = requests.get("https://www.youtube.com/robots.txt", proxies=proxies, timeout=20)
|
| 109 |
+
lines.append(f"- **YouTube reachable**: β
HTTP {r.status_code}")
|
| 110 |
+
verdict = "### π’ YouTube is reachable β transcript + screenshots should work."
|
| 111 |
+
except Exception as exc:
|
| 112 |
+
lines.append(f"- **YouTube reachable**: β {type(exc).__name__} (datacenter IP likely blocked)")
|
| 113 |
+
verdict = ("### π΄ YouTube is NOT reachable from the Space.\n"
|
| 114 |
+
"Set a residential **`YT_PROXY`** (e.g. the home-tunnel panel in "
|
| 115 |
+
"[`tools/`](tools/README.md)). Comments still work via the Data API; "
|
| 116 |
+
"transcript + screenshots need the proxy.")
|
| 117 |
+
return verdict + "\n\n" + "\n".join(lines)
|
| 118 |
+
|
| 119 |
+
|
| 120 |
# ----------------------------------------------------------------------------- helpers
|
| 121 |
def _ranking_rows(scored: list[dict]) -> list[list]:
|
| 122 |
rows = []
|
|
|
|
| 169 |
api_key = _resolve_api_key(yt_api_key)
|
| 170 |
cookiefile = _cookiefile(workdir)
|
| 171 |
proxy = _resolve_proxy()
|
| 172 |
+
if proxy:
|
| 173 |
+
log.append("π `YT_PROXY` is set β transcript + stream requests route through it.")
|
| 174 |
|
| 175 |
# 1. Search ------------------------------------------------------------------
|
| 176 |
progress(0.03, desc="Searching")
|
|
|
|
| 297 |
lead = gr.Slider(0.0, 5.0, value=1.0, step=0.5, label="Lead offset (s)")
|
| 298 |
max_shots = gr.Slider(1, 15, value=8, step=1, label="Max screenshots")
|
| 299 |
|
| 300 |
+
with gr.Row():
|
| 301 |
+
health_btn = gr.Button("π©Ί Check YouTube access (proxy + reachability)")
|
| 302 |
+
health_md = gr.Markdown()
|
| 303 |
+
|
| 304 |
run_btn = gr.Button("Generate tutorial", variant="primary")
|
| 305 |
|
| 306 |
status_md = gr.Markdown(label="Status")
|
|
|
|
| 311 |
transcript_box = gr.Textbox(label="Transcript preview", lines=10, max_lines=20)
|
| 312 |
docx_file = gr.File(label="Download tutorial (.docx)")
|
| 313 |
|
| 314 |
+
health_btn.click(check_access, outputs=health_md)
|
| 315 |
run_btn.click(
|
| 316 |
run_pipeline,
|
| 317 |
inputs=[topic, hf_token, yt_api_key, llm_model, vlm_model,
|