vivekchakraverty Claude Opus 4.8 commited on
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>

Files changed (1) hide show
  1. app.py +36 -0
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,