NickVerri commited on
Commit
7b1e992
·
verified ·
1 Parent(s): 218eb2f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -42
app.py CHANGED
@@ -268,8 +268,6 @@ def call_gemini_for_edl(transcript_data, story_prompt, api_key):
268
  st.error("Gemini API Key is missing.")
269
  return None
270
 
271
- url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={api_key}"
272
-
273
  system_prompt = (
274
  "You are an expert Documentary Senior Editor. Use the provided transcript JSON "
275
  "(which includes Speaker IDs and word-level timestamps) to create a condensed story. "
@@ -305,49 +303,64 @@ def call_gemini_for_edl(transcript_data, story_prompt, api_key):
305
  "Content-Type": "application/json"
306
  }
307
 
308
- max_retries = 3
309
- for attempt in range(max_retries):
310
- try:
311
- res = requests.post(url, json=payload, headers=headers)
312
-
313
- # Handle Rate Limiting (429) specifically
314
- if res.status_code == 429:
315
- if attempt < max_retries - 1:
316
- wait_time = 10 * (attempt + 1)
317
- st.warning(f"Rate limit hit. Retrying in {wait_time} seconds...")
318
- time.sleep(wait_time)
319
- continue
320
- else:
321
- st.error("Google API Rate Limit Exceeded (429). Please wait a few minutes before trying again, or upgrade your API tier.")
322
- return None
323
 
324
- # Instead of generic failure, show the EXACT error message from Google
325
- if not res.ok:
326
- error_details = res.text
327
- try:
328
- error_details = res.json().get('error', {}).get('message', res.text)
329
- except Exception:
330
- pass
331
- st.error(f"Google API Rejected Request ({res.status_code}): {error_details}")
332
- return None
333
 
334
- result_json = res.json()
335
- raw_text = result_json['candidates'][0]['content']['parts'][0]['text']
336
- cleaned_text = clean_json_response(raw_text)
337
- return json.loads(cleaned_text)
338
-
339
- except json.JSONDecodeError as e:
340
- st.error(f"Failed to parse Gemini's output as JSON: {e}")
341
- return None
342
- except requests.exceptions.RequestException as e:
343
- if attempt < max_retries - 1:
344
- time.sleep(5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  continue
346
- st.error(f"Network Error connecting to Gemini API: {e}")
347
- return None
348
- except Exception as e:
349
- st.error(f"Senior Editor AI Error: {e}")
350
- return None
351
 
352
  # --- Streamlit UI ---
353
  st.set_page_config(page_title="Junior Editor", layout="wide")
@@ -527,3 +540,6 @@ if uploaded_file:
527
 
528
  st.download_button(f"Download .{ext.upper()}", data=final_output, file_name=f"junior_editor_cut.{ext}")
529
 
 
 
 
 
268
  st.error("Gemini API Key is missing.")
269
  return None
270
 
 
 
271
  system_prompt = (
272
  "You are an expert Documentary Senior Editor. Use the provided transcript JSON "
273
  "(which includes Speaker IDs and word-level timestamps) to create a condensed story. "
 
303
  "Content-Type": "application/json"
304
  }
305
 
306
+ # Cascading Fallback List - If one fails, it instantly tries the next.
307
+ models_to_try = [
308
+ "gemini-2.5-flash",
309
+ "gemini-3.1-flash",
310
+ "gemini-1.5-flash",
311
+ "gemini-2.5-pro"
312
+ ]
313
+
314
+ # Try the final/stable endpoint first, fallback to beta if features aren't promoted yet
315
+ endpoints_to_try = ["v1", "v1beta"]
316
+ last_error = ""
317
+
318
+ for model_name in models_to_try:
319
+ for api_version in endpoints_to_try:
320
+ url = f"https://generativelanguage.googleapis.com/{api_version}/models/{model_name}:generateContent?key={api_key}"
321
 
322
+ try:
323
+ res = requests.post(url, json=payload, headers=headers)
 
 
 
 
 
 
 
324
 
325
+ # Success
326
+ if res.status_code == 200:
327
+ result_json = res.json()
328
+ raw_text = result_json['candidates'][0]['content']['parts'][0]['text']
329
+ cleaned_text = clean_json_response(raw_text)
330
+ return json.loads(cleaned_text)
331
+
332
+ # Handle High Demand (503) or Rate Limits (429)
333
+ elif res.status_code in [503, 429]:
334
+ last_error = f"Model {model_name} busy ({res.status_code}) on {api_version}."
335
+ st.warning(f"Debug: {last_error} Skipping to next model...")
336
+ break # Break inner loop: No point trying v1beta if v1 is rate limited. Move to next model.
337
+
338
+ # Handle endpoints that don't exist (404) or API rejections (400)
339
+ else:
340
+ try:
341
+ error_details = res.json().get('error', {}).get('message', res.text)
342
+ except Exception:
343
+ error_details = res.text
344
+ last_error = f"Model {model_name} rejected request ({res.status_code}) on {api_version}: {error_details}"
345
+ st.warning(f"Debug: {last_error} Trying fallback endpoint/model...")
346
+ continue # Try v1beta, or the next model
347
+
348
+ except json.JSONDecodeError:
349
+ last_error = f"Model {model_name} returned invalid JSON on {api_version}."
350
+ st.warning(f"Debug: {last_error} Trying fallback endpoint/model...")
351
+ continue
352
+ except requests.exceptions.RequestException as e:
353
+ last_error = f"Network error connecting to {model_name} on {api_version}: {e}"
354
+ st.warning(f"Debug: {last_error} Trying fallback endpoint/model...")
355
+ continue
356
+ except Exception as e:
357
+ last_error = f"Error with {model_name} on {api_version}: {e}"
358
+ st.warning(f"Debug: {last_error} Trying fallback endpoint/model...")
359
  continue
360
+
361
+ # If the loop finishes without returning, all models failed
362
+ st.error(f"All Gemini models failed or are currently experiencing high demand. Last error: {last_error}")
363
+ return None
 
364
 
365
  # --- Streamlit UI ---
366
  st.set_page_config(page_title="Junior Editor", layout="wide")
 
540
 
541
  st.download_button(f"Download .{ext.upper()}", data=final_output, file_name=f"junior_editor_cut.{ext}")
542
 
543
+
544
+
545
+