Update app.py
Browse files
app.py
CHANGED
|
@@ -11,6 +11,7 @@ import gc
|
|
| 11 |
import math
|
| 12 |
import uuid
|
| 13 |
import re
|
|
|
|
| 14 |
from urllib.parse import quote
|
| 15 |
from datetime import timedelta
|
| 16 |
|
|
@@ -257,7 +258,7 @@ def call_gemini_for_edl(transcript_data, story_prompt, api_key):
|
|
| 257 |
st.error("Gemini API Key is missing.")
|
| 258 |
return None
|
| 259 |
|
| 260 |
-
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-
|
| 261 |
|
| 262 |
system_prompt = (
|
| 263 |
"You are an expert Documentary Senior Editor. Use the provided transcript JSON "
|
|
@@ -274,22 +275,69 @@ def call_gemini_for_edl(transcript_data, story_prompt, api_key):
|
|
| 274 |
|
| 275 |
prompt_text = f"Creative Brief: {story_prompt}\n\nTranscript Data:\n{json.dumps(transcript_data)}"
|
| 276 |
|
|
|
|
| 277 |
payload = {
|
| 278 |
-
"contents": [
|
| 279 |
-
|
| 280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 281 |
}
|
| 282 |
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 293 |
|
| 294 |
# --- Streamlit UI ---
|
| 295 |
st.set_page_config(page_title="Junior Editor", layout="wide")
|
|
|
|
| 11 |
import math
|
| 12 |
import uuid
|
| 13 |
import re
|
| 14 |
+
import time
|
| 15 |
from urllib.parse import quote
|
| 16 |
from datetime import timedelta
|
| 17 |
|
|
|
|
| 258 |
st.error("Gemini API Key is missing.")
|
| 259 |
return None
|
| 260 |
|
| 261 |
+
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-3.0-flash:generateContent?key={api_key}"
|
| 262 |
|
| 263 |
system_prompt = (
|
| 264 |
"You are an expert Documentary Senior Editor. Use the provided transcript JSON "
|
|
|
|
| 275 |
|
| 276 |
prompt_text = f"Creative Brief: {story_prompt}\n\nTranscript Data:\n{json.dumps(transcript_data)}"
|
| 277 |
|
| 278 |
+
# Stricter payload formatting according to Gemini REST API specs
|
| 279 |
payload = {
|
| 280 |
+
"contents": [
|
| 281 |
+
{
|
| 282 |
+
"role": "user",
|
| 283 |
+
"parts": [{"text": prompt_text}]
|
| 284 |
+
}
|
| 285 |
+
],
|
| 286 |
+
"systemInstruction": {
|
| 287 |
+
"parts": [{"text": system_prompt}]
|
| 288 |
+
},
|
| 289 |
+
"generationConfig": {
|
| 290 |
+
"responseMimeType": "application/json"
|
| 291 |
+
}
|
| 292 |
}
|
| 293 |
|
| 294 |
+
headers = {
|
| 295 |
+
"Content-Type": "application/json"
|
| 296 |
+
}
|
| 297 |
+
|
| 298 |
+
max_retries = 3
|
| 299 |
+
for attempt in range(max_retries):
|
| 300 |
+
try:
|
| 301 |
+
res = requests.post(url, json=payload, headers=headers)
|
| 302 |
+
|
| 303 |
+
# Handle Rate Limiting (429) specifically
|
| 304 |
+
if res.status_code == 429:
|
| 305 |
+
if attempt < max_retries - 1:
|
| 306 |
+
wait_time = 10 * (attempt + 1)
|
| 307 |
+
st.warning(f"Rate limit hit. Retrying in {wait_time} seconds...")
|
| 308 |
+
time.sleep(wait_time)
|
| 309 |
+
continue
|
| 310 |
+
else:
|
| 311 |
+
st.error("Google API Rate Limit Exceeded (429). Please wait a few minutes before trying again, or upgrade your API tier.")
|
| 312 |
+
return None
|
| 313 |
+
|
| 314 |
+
# Instead of generic failure, show the EXACT error message from Google
|
| 315 |
+
if not res.ok:
|
| 316 |
+
error_details = res.text
|
| 317 |
+
try:
|
| 318 |
+
error_details = res.json().get('error', {}).get('message', res.text)
|
| 319 |
+
except Exception:
|
| 320 |
+
pass
|
| 321 |
+
st.error(f"Google API Rejected Request ({res.status_code}): {error_details}")
|
| 322 |
+
return None
|
| 323 |
+
|
| 324 |
+
result_json = res.json()
|
| 325 |
+
raw_text = result_json['candidates'][0]['content']['parts'][0]['text']
|
| 326 |
+
cleaned_text = clean_json_response(raw_text)
|
| 327 |
+
return json.loads(cleaned_text)
|
| 328 |
+
|
| 329 |
+
except json.JSONDecodeError as e:
|
| 330 |
+
st.error(f"Failed to parse Gemini's output as JSON: {e}")
|
| 331 |
+
return None
|
| 332 |
+
except requests.exceptions.RequestException as e:
|
| 333 |
+
if attempt < max_retries - 1:
|
| 334 |
+
time.sleep(5)
|
| 335 |
+
continue
|
| 336 |
+
st.error(f"Network Error connecting to Gemini API: {e}")
|
| 337 |
+
return None
|
| 338 |
+
except Exception as e:
|
| 339 |
+
st.error(f"Senior Editor AI Error: {e}")
|
| 340 |
+
return None
|
| 341 |
|
| 342 |
# --- Streamlit UI ---
|
| 343 |
st.set_page_config(page_title="Junior Editor", layout="wide")
|