Hug0endob commited on
Commit
41a3d0e
·
verified ·
1 Parent(s): 6952c54

Update streamlit_app.py

Browse files
Files changed (1) hide show
  1. streamlit_app.py +59 -42
streamlit_app.py CHANGED
@@ -250,6 +250,19 @@ def _strip_prompt_echo(prompt: str, text: str, threshold: float = 0.68) -> str:
250
  # ----------------------------------------------------------------------
251
  # Streamlit UI
252
  # ----------------------------------------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  def main() -> None:
254
  st.set_page_config(page_title="Video Analysis", layout="wide")
255
 
@@ -257,59 +270,30 @@ def main() -> None:
257
  st.sidebar.header("Video Input")
258
  st.sidebar.text_input("Video URL", key="url", placeholder="https://")
259
 
260
- # **Load Video button – now directly under the URL field**
261
  if st.sidebar.button("Load Video"):
262
  try:
263
  with st.spinner("Downloading video…"):
264
  raw_path = download_video(
265
  st.session_state["url"], DATA_DIR, st.session_state["video_password"]
266
  )
267
- # ALWAYS convert to MP4 before storing
268
- mp4_path = _convert_to_mp4(Path(raw_path))
269
  st.session_state["video_path"] = str(mp4_path) # guaranteed MP4
270
  st.session_state["last_error"] = ""
271
  st.success("Video loaded successfully.")
 
 
272
  except Exception as e:
273
  st.session_state["last_error"] = f"Download failed: {e}"
274
  st.sidebar.error(st.session_state["last_error"])
275
 
276
- # ---------- Preview & clear ----------
277
- if st.session_state.get("video_path"):
278
- try:
279
- mp4 = _convert_to_mp4(Path(st.session_state["video_path"]))
280
- st.sidebar.video(str(mp4))
281
- except Exception:
282
- st.sidebar.write("Preview unavailable")
283
-
284
- if st.sidebar.button("Clear Video"):
285
- # delete every file in DATA_DIR (both raw and converted)
286
- for f in DATA_DIR.iterdir():
287
- try:
288
- f.unlink()
289
- except Exception:
290
- pass
291
- # reset session state, including the URL field
292
- st.session_state.update(
293
- {
294
- "url": "",
295
- "video_path": "",
296
- "analysis_out": "",
297
- "last_error": "",
298
- "busy": False,
299
- "show_raw_on_error": False,
300
- }
301
- )
302
- st.success("Session cleared.")
303
-
304
  # ---------- Settings ----------
305
  with st.sidebar.expander("Settings", expanded=False):
306
  model = st.selectbox(
307
  "Model", MODEL_OPTIONS, index=MODEL_OPTIONS.index(DEFAULT_MODEL)
308
  )
309
  if model == "custom":
310
- model = st.text_input(
311
- "Custom model ID", value=DEFAULT_MODEL, key="custom_model"
312
- )
313
  st.session_state["model_input"] = model
314
 
315
  # API key handling
@@ -318,11 +302,8 @@ def main() -> None:
318
  st.session_state["api_key"] = secret_key
319
  st.text_input("Google API Key", key="api_key", type="password")
320
 
321
- st.text_area(
322
- "Analysis prompt", value=DEFAULT_PROMPT, key="prompt", height=140
323
- )
324
  st.text_input("Video password (if needed)", key="video_password", type="password")
325
-
326
  st.number_input(
327
  "Compress if > (MB)",
328
  min_value=10,
@@ -332,12 +313,43 @@ def main() -> None:
332
  key="compress_mb",
333
  )
334
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  # ---------- Generation ----------
336
  col1, col2 = st.columns([1, 3])
337
 
338
  with col1:
339
  generate_now = st.button(
340
- "Generate analysis", type="primary", disabled=st.session_state.get("busy", False)
 
 
341
  )
342
 
343
  with col2:
@@ -400,10 +412,15 @@ def main() -> None:
400
  st.subheader("📝 Analysis")
401
  st.markdown(st.session_state["analysis_out"])
402
 
403
- # Show raw Gemini output only when it exists
404
  if st.session_state.get("raw_output"):
405
- st.subheader("🔎 Full Gemini output")
406
- st.code(st.session_state["raw_output"], language="text")
 
 
 
 
 
407
 
408
  # ---------- Errors ----------
409
  if st.session_state.get("last_error"):
 
250
  # ----------------------------------------------------------------------
251
  # Streamlit UI
252
  # ----------------------------------------------------------------------
253
+ import os
254
+ import traceback
255
+ from pathlib import Path
256
+
257
+ import streamlit as st
258
+ import genai # your Gemini wrapper
259
+
260
+ # import your helpers:
261
+ # download_video, _convert_to_mp4, _maybe_compress,
262
+ # generate_report, _strip_prompt_echo, MODEL_OPTIONS,
263
+ # DEFAULT_MODEL, DEFAULT_PROMPT, DATA_DIR
264
+
265
+
266
  def main() -> None:
267
  st.set_page_config(page_title="Video Analysis", layout="wide")
268
 
 
270
  st.sidebar.header("Video Input")
271
  st.sidebar.text_input("Video URL", key="url", placeholder="https://")
272
 
273
+ # ---- Load Video button (directly under the URL) ----
274
  if st.sidebar.button("Load Video"):
275
  try:
276
  with st.spinner("Downloading video…"):
277
  raw_path = download_video(
278
  st.session_state["url"], DATA_DIR, st.session_state["video_password"]
279
  )
280
+ mp4_path = _convert_to_mp4(Path(raw_path)) # always MP4
 
281
  st.session_state["video_path"] = str(mp4_path) # guaranteed MP4
282
  st.session_state["last_error"] = ""
283
  st.success("Video loaded successfully.")
284
+ # Force Streamlit to rerun so the preview appears immediately
285
+ st.experimental_rerun()
286
  except Exception as e:
287
  st.session_state["last_error"] = f"Download failed: {e}"
288
  st.sidebar.error(st.session_state["last_error"])
289
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
  # ---------- Settings ----------
291
  with st.sidebar.expander("Settings", expanded=False):
292
  model = st.selectbox(
293
  "Model", MODEL_OPTIONS, index=MODEL_OPTIONS.index(DEFAULT_MODEL)
294
  )
295
  if model == "custom":
296
+ model = st.text_input("Custom model ID", value=DEFAULT_MODEL, key="custom_model")
 
 
297
  st.session_state["model_input"] = model
298
 
299
  # API key handling
 
302
  st.session_state["api_key"] = secret_key
303
  st.text_input("Google API Key", key="api_key", type="password")
304
 
305
+ st.text_area("Analysis prompt", value=DEFAULT_PROMPT, key="prompt", height=140)
 
 
306
  st.text_input("Video password (if needed)", key="video_password", type="password")
 
307
  st.number_input(
308
  "Compress if > (MB)",
309
  min_value=10,
 
313
  key="compress_mb",
314
  )
315
 
316
+ # ---------- Preview & clear (shown only when a video is loaded) ----------
317
+ if st.session_state.get("video_path"):
318
+ try:
319
+ mp4 = _convert_to_mp4(Path(st.session_state["video_path"]))
320
+ st.sidebar.video(str(mp4))
321
+ except Exception:
322
+ st.sidebar.write("Preview unavailable")
323
+
324
+ if st.sidebar.button("Clear Video"):
325
+ # delete every file in DATA_DIR (both raw and converted)
326
+ for f in DATA_DIR.iterdir():
327
+ try:
328
+ f.unlink()
329
+ except Exception:
330
+ pass
331
+ # reset session state (including the URL field)
332
+ st.session_state.update(
333
+ {
334
+ "url": "",
335
+ "video_path": "",
336
+ "analysis_out": "",
337
+ "last_error": "",
338
+ "busy": False,
339
+ "show_raw_on_error": False,
340
+ }
341
+ )
342
+ st.success("Session cleared.")
343
+ st.experimental_rerun()
344
+
345
  # ---------- Generation ----------
346
  col1, col2 = st.columns([1, 3])
347
 
348
  with col1:
349
  generate_now = st.button(
350
+ "Generate analysis",
351
+ type="primary",
352
+ disabled=st.session_state.get("busy", False),
353
  )
354
 
355
  with col2:
 
412
  st.subheader("📝 Analysis")
413
  st.markdown(st.session_state["analysis_out"])
414
 
415
+ # Full Gemini output collapsed by default, expanded only on error
416
  if st.session_state.get("raw_output"):
417
+ if st.session_state.get("show_raw_on_error"):
418
+ st.subheader("🔎 Full Gemini output")
419
+ st.code(st.session_state["raw_output"], language="text")
420
+ else:
421
+ # collapsed expander, starts closed
422
+ with st.expander("🔎 Full Gemini output (collapsed)"):
423
+ st.code(st.session_state["raw_output"], language="text")
424
 
425
  # ---------- Errors ----------
426
  if st.session_state.get("last_error"):