CB commited on
Commit
1c6309c
·
verified ·
1 Parent(s): 5bb659f

Update streamlit_app.py

Browse files
Files changed (1) hide show
  1. streamlit_app.py +36 -33
streamlit_app.py CHANGED
@@ -17,7 +17,6 @@ st.set_page_config(page_title="Generate the story of videos", layout="wide")
17
  DATA_DIR = Path("./data")
18
  DATA_DIR.mkdir(exist_ok=True)
19
 
20
- # session defaults
21
  for k, v in {
22
  "videos": "",
23
  "loop_video": False,
@@ -147,7 +146,6 @@ def file_name_or_id(file_obj):
147
  return s[idx:] if s[idx:].startswith("files/") else f"files/{s[idx+6:]}"
148
  return None
149
 
150
- # optional Google SDK
151
  HAS_GENAI = False
152
  genai = None
153
  upload_file = None
@@ -157,8 +155,8 @@ if os.getenv("GOOGLE_API_KEY"):
157
  try:
158
  import google.generativeai as genai_mod
159
  genai = genai_mod
160
- upload_file = genai_mod.upload_file
161
- get_file = genai_mod.get_file
162
  delete_file = getattr(genai_mod, "delete_file", None)
163
  HAS_GENAI = True
164
  except Exception:
@@ -168,8 +166,8 @@ def upload_video_sdk(filepath: str):
168
  key = get_runtime_api_key()
169
  if not key:
170
  raise RuntimeError("No API key")
171
- if not HAS_GENAI:
172
- raise RuntimeError("google.generativeai SDK not available")
173
  genai.configure(api_key=key)
174
  return upload_file(filepath)
175
 
@@ -213,7 +211,6 @@ def remove_prompt_echo(prompt: str, text: str):
213
  return t[len(ph):].lstrip(" \n:-")
214
  return text
215
 
216
- # UI: sidebar
217
  st.sidebar.header("Video Input")
218
  st.sidebar.text_input("Video URL", key="url", placeholder="https://")
219
  settings = st.sidebar.expander("Settings", expanded=False)
@@ -241,7 +238,6 @@ settings.number_input("Max output tokens", key="max_output_tokens", value=1024,
241
  if not API_KEY_INPUT and not env_key:
242
  settings.info("No Google API key provided; upload/generation disabled. Use local-only demos or provide key for real analysis.", icon="ℹ️")
243
 
244
- # load video
245
  if st.sidebar.button("Load Video", use_container_width=True):
246
  try:
247
  vpw = st.session_state.get("video-password", "")
@@ -302,7 +298,35 @@ def get_runtime_api_key():
302
  return key
303
  return os.getenv("GOOGLE_API_KEY", "").strip() or None
304
 
305
- # generation flow
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
  if (st.session_state.get("busy") is False) and ('generate_now' in locals() and generate_now):
307
  if not st.session_state.get("videos"):
308
  st.error("No video loaded. Use 'Load Video' in the sidebar.")
@@ -328,7 +352,6 @@ if (st.session_state.get("busy") is False) and ('generate_now' in locals() and g
328
 
329
  upload_path = current_path
330
  uploaded = st.session_state.get("uploaded_file")
331
- # If we need to (re)upload
332
  if reupload_needed:
333
  local_path = current_path
334
  fast_mode = st.session_state.get("fast_mode", False)
@@ -354,8 +377,6 @@ if (st.session_state.get("busy") is False) and ('generate_now' in locals() and g
354
  st.session_state["processed_file"] = processed
355
  st.session_state["last_loaded_path"] = current_path
356
  st.session_state["file_hash"] = current_hash
357
-
358
- # Do not delete original local file until entire generation succeeds.
359
  else:
360
  uploaded = st.session_state.get("uploaded_file")
361
  processed = st.session_state.get("processed_file")
@@ -372,24 +393,11 @@ if (st.session_state.get("busy") is False) and ('generate_now' in locals() and g
372
  user_msg = {"role": "user", "content": prompt_text}
373
 
374
  def call_responses_once(model_used, system_msg, user_msg, fname, max_tokens):
375
- genai.configure(api_key=runtime_key)
376
  for attempt in range(2):
377
  try:
378
- try:
379
- response = genai.responses.generate(
380
- model=model_used,
381
- messages=[system_msg, user_msg],
382
- files=[{"name": fname}],
383
- max_output_tokens=max_tokens,
384
- )
385
- except TypeError:
386
- response = genai.responses.generate(
387
- model=model_used,
388
- input=[{"text": user_msg["content"], "files": [{"name": fname}]}],
389
- max_output_tokens=max_tokens,
390
- )
391
- return response
392
- except Exception as e:
393
  if attempt == 0:
394
  time.sleep(1.0)
395
  continue
@@ -470,12 +478,10 @@ if (st.session_state.get("busy") is False) and ('generate_now' in locals() and g
470
  st.subheader("Analysis Result")
471
  st.markdown(out or "_(no text returned)_")
472
 
473
- # delete local copies now that generation succeeded (if upload created temporary compressed file)
474
  try:
475
  if reupload_needed:
476
  if upload_path and Path(upload_path).exists() and Path(upload_path) != Path(current_path):
477
  Path(upload_path).unlink(missing_ok=True)
478
- # optionally remove original local file to avoid persistence
479
  Path(current_path).unlink(missing_ok=True)
480
  st.session_state["videos"] = ""
481
  except Exception:
@@ -490,7 +496,6 @@ if (st.session_state.get("busy") is False) and ('generate_now' in locals() and g
490
  "processed_state": getattr(st.session_state.get("processed_file"), "state", None) if st.session_state.get("processed_file") else None,
491
  }
492
  st.write(info)
493
- # truncated response keys for debugging
494
  try:
495
  if isinstance(response, dict):
496
  keys = list(response.keys())[:20]
@@ -508,7 +513,6 @@ if (st.session_state.get("busy") is False) and ('generate_now' in locals() and g
508
  finally:
509
  st.session_state["busy"] = False
510
 
511
- # persistent UI: show cached analysis without paths/ids
512
  if st.session_state.get("analysis_out"):
513
  st.subheader("Analysis Result")
514
  st.markdown(st.session_state.get("analysis_out"))
@@ -517,7 +521,6 @@ if st.session_state.get("last_error"):
517
  with st.expander("Last Error", expanded=False):
518
  st.write(st.session_state.get("last_error"))
519
 
520
- # delete uploaded files (local + cloud if possible)
521
  with st.sidebar.expander("Manage uploads", expanded=False):
522
  if st.button("Delete uploaded files (local + cloud)"):
523
  for f in glob(str(DATA_DIR / "*")):
 
17
  DATA_DIR = Path("./data")
18
  DATA_DIR.mkdir(exist_ok=True)
19
 
 
20
  for k, v in {
21
  "videos": "",
22
  "loop_video": False,
 
146
  return s[idx:] if s[idx:].startswith("files/") else f"files/{s[idx+6:]}"
147
  return None
148
 
 
149
  HAS_GENAI = False
150
  genai = None
151
  upload_file = None
 
155
  try:
156
  import google.generativeai as genai_mod
157
  genai = genai_mod
158
+ upload_file = getattr(genai_mod, "upload_file", None)
159
+ get_file = getattr(genai_mod, "get_file", None)
160
  delete_file = getattr(genai_mod, "delete_file", None)
161
  HAS_GENAI = True
162
  except Exception:
 
166
  key = get_runtime_api_key()
167
  if not key:
168
  raise RuntimeError("No API key")
169
+ if not HAS_GENAI or upload_file is None:
170
+ raise RuntimeError("google.generativeai SDK upload not available")
171
  genai.configure(api_key=key)
172
  return upload_file(filepath)
173
 
 
211
  return t[len(ph):].lstrip(" \n:-")
212
  return text
213
 
 
214
  st.sidebar.header("Video Input")
215
  st.sidebar.text_input("Video URL", key="url", placeholder="https://")
216
  settings = st.sidebar.expander("Settings", expanded=False)
 
238
  if not API_KEY_INPUT and not env_key:
239
  settings.info("No Google API key provided; upload/generation disabled. Use local-only demos or provide key for real analysis.", icon="ℹ️")
240
 
 
241
  if st.sidebar.button("Load Video", use_container_width=True):
242
  try:
243
  vpw = st.session_state.get("video-password", "")
 
298
  return key
299
  return os.getenv("GOOGLE_API_KEY", "").strip() or None
300
 
301
+ # Responses caller supporting SDK variants and HTTP fallback
302
+ def responses_generate(model, messages, files, max_output_tokens, api_key):
303
+ genai.configure(api_key=api_key)
304
+ # preferred SDK style
305
+ if hasattr(genai, "responses") and getattr(genai, "responses") is not None:
306
+ try:
307
+ return genai.responses.generate(model=model, messages=messages, files=files, max_output_tokens=max_output_tokens)
308
+ except Exception:
309
+ # let higher level handle retries/errors
310
+ raise
311
+ # older/newer SDKs might expose different helpers; attempt generic client POST
312
+ # fallback: directly call the REST endpoint via genai.client/_client if available
313
+ client_attr = getattr(genai, "client", None) or getattr(genai, "_client", None) or getattr(genai, "transport", None)
314
+ if client_attr:
315
+ try:
316
+ # construct payload similar to Responses API
317
+ payload = {"model": model, "messages": messages, "max_output_tokens": max_output_tokens}
318
+ headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
319
+ # try to find a requests-like post method
320
+ post = getattr(client_attr, "post", None) or getattr(client_attr, "request", None)
321
+ if post:
322
+ # endpoint path used by Google Generative API
323
+ url = "/v1/responses"
324
+ resp = post(url, json=payload, headers=headers)
325
+ return resp
326
+ except Exception:
327
+ pass
328
+ raise RuntimeError("genai.responses not available and HTTP fallback failed")
329
+
330
  if (st.session_state.get("busy") is False) and ('generate_now' in locals() and generate_now):
331
  if not st.session_state.get("videos"):
332
  st.error("No video loaded. Use 'Load Video' in the sidebar.")
 
352
 
353
  upload_path = current_path
354
  uploaded = st.session_state.get("uploaded_file")
 
355
  if reupload_needed:
356
  local_path = current_path
357
  fast_mode = st.session_state.get("fast_mode", False)
 
377
  st.session_state["processed_file"] = processed
378
  st.session_state["last_loaded_path"] = current_path
379
  st.session_state["file_hash"] = current_hash
 
 
380
  else:
381
  uploaded = st.session_state.get("uploaded_file")
382
  processed = st.session_state.get("processed_file")
 
393
  user_msg = {"role": "user", "content": prompt_text}
394
 
395
  def call_responses_once(model_used, system_msg, user_msg, fname, max_tokens):
 
396
  for attempt in range(2):
397
  try:
398
+ resp = responses_generate(model_used, [system_msg, user_msg], [{"name": fname}], max_tokens, api_key=runtime_key)
399
+ return resp
400
+ except Exception:
 
 
 
 
 
 
 
 
 
 
 
 
401
  if attempt == 0:
402
  time.sleep(1.0)
403
  continue
 
478
  st.subheader("Analysis Result")
479
  st.markdown(out or "_(no text returned)_")
480
 
 
481
  try:
482
  if reupload_needed:
483
  if upload_path and Path(upload_path).exists() and Path(upload_path) != Path(current_path):
484
  Path(upload_path).unlink(missing_ok=True)
 
485
  Path(current_path).unlink(missing_ok=True)
486
  st.session_state["videos"] = ""
487
  except Exception:
 
496
  "processed_state": getattr(st.session_state.get("processed_file"), "state", None) if st.session_state.get("processed_file") else None,
497
  }
498
  st.write(info)
 
499
  try:
500
  if isinstance(response, dict):
501
  keys = list(response.keys())[:20]
 
513
  finally:
514
  st.session_state["busy"] = False
515
 
 
516
  if st.session_state.get("analysis_out"):
517
  st.subheader("Analysis Result")
518
  st.markdown(st.session_state.get("analysis_out"))
 
521
  with st.expander("Last Error", expanded=False):
522
  st.write(st.session_state.get("last_error"))
523
 
 
524
  with st.sidebar.expander("Manage uploads", expanded=False):
525
  if st.button("Delete uploaded files (local + cloud)"):
526
  for f in glob(str(DATA_DIR / "*")):