mgbam commited on
Commit
2344b77
Β·
verified Β·
1 Parent(s): 219ad6e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -16
app.py CHANGED
@@ -17,7 +17,7 @@ import contextlib
17
  import asyncio
18
  import uuid # For unique identifiers
19
  import shutil # For directory operations
20
- import logging # For logging
21
 
22
  # Image handling
23
  from PIL import Image
@@ -36,7 +36,7 @@ import typing_extensions as typing
36
  import nest_asyncio
37
  nest_asyncio.apply()
38
 
39
- # Import Vertex AI SDK and service account credentials support
40
  import vertexai
41
  from vertexai.preview.vision_models import ImageGenerationModel
42
  from google.oauth2 import service_account
@@ -84,14 +84,13 @@ except KeyError:
84
  st.error("🚨 **Google API Key Not Found!** Please configure it.", icon="🚨")
85
  st.stop()
86
 
87
- # Vertex AI configuration: PROJECT_ID and LOCATION
88
  PROJECT_ID = st.secrets.get("PROJECT_ID") or os.environ.get("PROJECT_ID")
89
  LOCATION = st.secrets.get("LOCATION") or os.environ.get("LOCATION", "us-central1")
90
  if not PROJECT_ID:
91
  st.error("🚨 **PROJECT_ID not set!** Please add PROJECT_ID to your secrets.", icon="🚨")
92
  st.stop()
93
 
94
- # Load service account JSON from the secret
95
  try:
96
  service_account_info = json.loads(os.environ["SERVICE_ACCOUNT_JSON"])
97
  credentials = service_account.Credentials.from_service_account_info(service_account_info)
@@ -175,7 +174,6 @@ def wave_file_writer(filename: str, channels: int = 1, rate: int = AUDIO_SAMPLIN
175
  logger.error(f"Error closing wave file {filename}: {e_close}")
176
 
177
  # --- Audio Generation using gTTS ---
178
- # We replace the previous failing method with gTTS.
179
  async def generate_audio_live_async(api_text: str, output_filename: str, voice: Optional[str] = None) -> Optional[str]:
180
  """
181
  Generates audio using gTTS (Google Text-to-Speech).
@@ -184,16 +182,18 @@ async def generate_audio_live_async(api_text: str, output_filename: str, voice:
184
  task_id = os.path.basename(output_filename).split('.')[0]
185
  logger.info(f"πŸŽ™οΈ [{task_id}] Generating audio via gTTS for text: '{api_text[:60]}...'")
186
  try:
187
- # Generate audio using gTTS
188
  tts = gTTS(text=api_text, lang="en")
189
- # Replace .wav with .mp3
190
  mp3_filename = output_filename.replace(".wav", ".mp3")
191
  tts.save(mp3_filename)
192
  logger.info(f"βœ… [{task_id}] Audio saved: {os.path.basename(mp3_filename)}")
193
  return mp3_filename
194
  except Exception as e:
 
 
 
 
 
195
  logger.exception(f"❌ [{task_id}] Audio generation error: {e}")
196
- st.error(f"Audio generation failed for {task_id}: {e}", icon="πŸ”Š")
197
  return None
198
 
199
  def generate_story_sequence_chrono(theme: str, num_scenes: int, num_timelines: int, divergence_prompt: str = "") -> Optional[ChronoWeaveResponse]:
@@ -258,8 +258,8 @@ def generate_image_imagen(prompt: str, aspect_ratio: str = "1:1", task_id: str =
258
  """
259
  Generates an image using Vertex AI's Imagen model via the Vertex AI preview API.
260
 
261
- This function loads the pretrained Imagen model "imagen-3.0-generate-002" and generates an image.
262
- If authentication fails, it provides guidance on how to resolve the issue.
263
  """
264
  logger.info(f"πŸ–ΌοΈ [{task_id}] Requesting image: '{prompt[:70]}...' (Aspect: {aspect_ratio})")
265
  try:
@@ -278,12 +278,10 @@ def generate_image_imagen(prompt: str, aspect_ratio: str = "1:1", task_id: str =
278
  return image
279
  except Exception as e:
280
  error_str = str(e)
281
- if "Unable to authenticate" in error_str:
282
  error_msg = (
283
- "Authentication error: Unable to authenticate your request. "
284
- "Ensure your service account JSON is loaded correctly. "
285
- "For example, on Hugging Face Spaces, set SERVICE_ACCOUNT_JSON in your repository secrets. "
286
- "If running locally, run `!gcloud auth login`."
287
  )
288
  else:
289
  error_msg = f"Image generation for {task_id} failed: {e}"
@@ -382,7 +380,6 @@ if generate_button:
382
  generated_audio_path: Optional[str] = None
383
  if not scene_has_error:
384
  with st.spinner(f"[{task_id}] Generating audio... πŸ”Š"):
385
- # Change output extension to .wav for consistency, but gTTS returns MP3
386
  audio_path_temp = os.path.join(temp_dir, f"{task_id}_audio.wav")
387
  try:
388
  generated_audio_path = asyncio.run(generate_audio_live_async(segment.audio_text, audio_path_temp, audio_voice))
 
17
  import asyncio
18
  import uuid # For unique identifiers
19
  import shutil # For directory operations
20
+ import logging
21
 
22
  # Image handling
23
  from PIL import Image
 
36
  import nest_asyncio
37
  nest_asyncio.apply()
38
 
39
+ # Import Vertex AI SDK and Google service account credentials support
40
  import vertexai
41
  from vertexai.preview.vision_models import ImageGenerationModel
42
  from google.oauth2 import service_account
 
84
  st.error("🚨 **Google API Key Not Found!** Please configure it.", icon="🚨")
85
  st.stop()
86
 
 
87
  PROJECT_ID = st.secrets.get("PROJECT_ID") or os.environ.get("PROJECT_ID")
88
  LOCATION = st.secrets.get("LOCATION") or os.environ.get("LOCATION", "us-central1")
89
  if not PROJECT_ID:
90
  st.error("🚨 **PROJECT_ID not set!** Please add PROJECT_ID to your secrets.", icon="🚨")
91
  st.stop()
92
 
93
+ # Load service account JSON from secret and create credentials
94
  try:
95
  service_account_info = json.loads(os.environ["SERVICE_ACCOUNT_JSON"])
96
  credentials = service_account.Credentials.from_service_account_info(service_account_info)
 
174
  logger.error(f"Error closing wave file {filename}: {e_close}")
175
 
176
  # --- Audio Generation using gTTS ---
 
177
  async def generate_audio_live_async(api_text: str, output_filename: str, voice: Optional[str] = None) -> Optional[str]:
178
  """
179
  Generates audio using gTTS (Google Text-to-Speech).
 
182
  task_id = os.path.basename(output_filename).split('.')[0]
183
  logger.info(f"πŸŽ™οΈ [{task_id}] Generating audio via gTTS for text: '{api_text[:60]}...'")
184
  try:
 
185
  tts = gTTS(text=api_text, lang="en")
 
186
  mp3_filename = output_filename.replace(".wav", ".mp3")
187
  tts.save(mp3_filename)
188
  logger.info(f"βœ… [{task_id}] Audio saved: {os.path.basename(mp3_filename)}")
189
  return mp3_filename
190
  except Exception as e:
191
+ error_str = str(e)
192
+ if "429" in error_str:
193
+ st.error(f"Audio generation for {task_id} failed: 429 Too Many Requests from TTS API. Please try again later.", icon="πŸ”Š")
194
+ else:
195
+ st.error(f"Audio generation for {task_id} failed: {e}", icon="πŸ”Š")
196
  logger.exception(f"❌ [{task_id}] Audio generation error: {e}")
 
197
  return None
198
 
199
  def generate_story_sequence_chrono(theme: str, num_scenes: int, num_timelines: int, divergence_prompt: str = "") -> Optional[ChronoWeaveResponse]:
 
258
  """
259
  Generates an image using Vertex AI's Imagen model via the Vertex AI preview API.
260
 
261
+ Loads the pretrained Imagen model and attempts to generate an image.
262
+ If a quota exceeded error occurs, it informs you to request a quota increase.
263
  """
264
  logger.info(f"πŸ–ΌοΈ [{task_id}] Requesting image: '{prompt[:70]}...' (Aspect: {aspect_ratio})")
265
  try:
 
278
  return image
279
  except Exception as e:
280
  error_str = str(e)
281
+ if "Quota exceeded" in error_str:
282
  error_msg = (
283
+ "Quota exceeded for image generation requests. "
284
+ "Please submit a quota increase request via the Vertex AI console: https://cloud.google.com/vertex-ai/docs/generative-ai/quotas-genai"
 
 
285
  )
286
  else:
287
  error_msg = f"Image generation for {task_id} failed: {e}"
 
380
  generated_audio_path: Optional[str] = None
381
  if not scene_has_error:
382
  with st.spinner(f"[{task_id}] Generating audio... πŸ”Š"):
 
383
  audio_path_temp = os.path.join(temp_dir, f"{task_id}_audio.wav")
384
  try:
385
  generated_audio_path = asyncio.run(generate_audio_live_async(segment.audio_text, audio_path_temp, audio_voice))