Update app.py
Browse files
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 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
|
| 323 |
|
| 324 |
-
|
| 325 |
-
|
| 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 |
-
|
| 335 |
-
|
| 336 |
-
|
| 337 |
-
|
| 338 |
-
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 345 |
continue
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
|
| 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 |
+
|