zach commited on
Commit
a6d4367
·
1 Parent(s): 63ef86b

Improve Hume API error handling

Browse files
src/app.py CHANGED
@@ -30,9 +30,10 @@ from src.constants import (
30
  from src.integrations import (
31
  AnthropicError,
32
  ElevenLabsError,
33
- generate_text_with_claude,
34
- text_to_speech_with_hume,
35
- text_to_speech_with_elevenlabs
 
36
  )
37
  from src.theme import CustomTheme
38
  from src.utils import truncate_text, validate_prompt_length
@@ -148,7 +149,11 @@ def text_to_speech(prompt: str, generated_text: str) -> tuple[gr.update, gr.upda
148
  )
149
 
150
  except ElevenLabsError as ee:
151
- logger.error(f"ElevenLabsError while synthesizing speech: {str(ee)}")
 
 
 
 
152
  return gr.update(value=None), gr.update(value=None), {}, None
153
 
154
  except Exception as e:
 
30
  from src.integrations import (
31
  AnthropicError,
32
  ElevenLabsError,
33
+ generate_text_with_claude,
34
+ HumeError,
35
+ text_to_speech_with_elevenlabs,
36
+ text_to_speech_with_hume
37
  )
38
  from src.theme import CustomTheme
39
  from src.utils import truncate_text, validate_prompt_length
 
149
  )
150
 
151
  except ElevenLabsError as ee:
152
+ logger.error(f"ElevenLabsError while synthesizing speech from text: {str(ee)}")
153
+ return gr.update(value=None), gr.update(value=None), {}, None
154
+
155
+ except HumeError as he:
156
+ logger.error(f"HumeError while synthesizing speech from text: {str(he)}")
157
  return gr.update(value=None), gr.update(value=None), {}, None
158
 
159
  except Exception as e:
src/integrations/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
  from .anthropic_api import generate_text_with_claude, AnthropicError
2
  from .elevenlabs_api import text_to_speech_with_elevenlabs, ElevenLabsError
3
- from .hume_api import text_to_speech_with_hume
 
1
  from .anthropic_api import generate_text_with_claude, AnthropicError
2
  from .elevenlabs_api import text_to_speech_with_elevenlabs, ElevenLabsError
3
+ from .hume_api import text_to_speech_with_hume, HumeError
src/integrations/elevenlabs_api.py CHANGED
@@ -104,7 +104,7 @@ def text_to_speech_with_elevenlabs(text: str) -> bytes:
104
  Raises:
105
  ElevenLabsError: If there is an error communicating with the ElevenLabs API or processing the response.
106
  """
107
- logger.debug(f'Generating speech with ElevenLabs. Text length: {len(text)} characters.')
108
 
109
  try:
110
  # Generate audio using the ElevenLabs SDK
@@ -132,8 +132,8 @@ def text_to_speech_with_elevenlabs(text: str) -> bytes:
132
  return audio
133
 
134
  except Exception as e:
135
- logger.exception(f'Error generating speech: {e}')
136
  raise ElevenLabsError(
137
- message=f'Failed to generate audio with ElevenLabs: {e}',
138
  original_exception=e,
139
  )
 
104
  Raises:
105
  ElevenLabsError: If there is an error communicating with the ElevenLabs API or processing the response.
106
  """
107
+ logger.debug(f'Synthesizing speech from text with ElevenLabs. Text length: {len(text)} characters.')
108
 
109
  try:
110
  # Generate audio using the ElevenLabs SDK
 
132
  return audio
133
 
134
  except Exception as e:
135
+ logger.exception(f'Error synthesizing speech from text with Elevenlabs: {e}')
136
  raise ElevenLabsError(
137
+ message=f'Failed to synthesize speech from text with ElevenLabs: {e}',
138
  original_exception=e,
139
  )
src/integrations/hume_api.py CHANGED
@@ -12,7 +12,7 @@ Key Features:
12
 
13
  Classes:
14
  - HumeConfig: Immutable configuration for interacting with the TTS API.
15
- - HumeException: Custom exception for TTS API-related errors.
16
 
17
  Functions:
18
  - text_to_speech_with_hume: Converts text to speech using the Hume TTS API with input validation and retry logic.
@@ -66,7 +66,7 @@ class HumeConfig:
66
  return random.choice(self.voices)
67
 
68
 
69
- class HumeException(Exception):
70
  """Custom exception for errors related to the Hume TTS API."""
71
  def __init__(self, message: str, original_exception: Optional[Exception] = None):
72
  super().__init__(message)
@@ -78,10 +78,11 @@ hume_config = HumeConfig()
78
 
79
 
80
  @retry(
81
- stop=stop_after_attempt(3),
82
  wait=wait_fixed(2),
83
  before=before_log(logger, logging.DEBUG),
84
  after=after_log(logger, logging.DEBUG),
 
85
  )
86
  def text_to_speech_with_hume(prompt: str, text: str) -> bytes:
87
  """
@@ -95,7 +96,7 @@ def text_to_speech_with_hume(prompt: str, text: str) -> bytes:
95
  bytes: The raw binary audio data for playback.
96
 
97
  Raises:
98
- HumeException: If there is an error communicating with the Hume TTS API.
99
  """
100
  logger.debug(f'Processing TTS with Hume. Prompt length: {len(prompt)} characters. Text length: {len(text)} characters.')
101
 
@@ -114,7 +115,7 @@ def text_to_speech_with_hume(prompt: str, text: str) -> bytes:
114
  # Validate response
115
  if response.status_code != 200:
116
  logger.error(f'Hume TTS API Error: {response.status_code} - {response.text[:200]}... (truncated)')
117
- raise HumeException(f'Hume TTS API responded with status {response.status_code}: {response.text}')
118
 
119
  # Process audio response
120
  if response.headers.get('Content-Type', '').startswith('audio/'):
@@ -123,17 +124,11 @@ def text_to_speech_with_hume(prompt: str, text: str) -> bytes:
123
  return audio_data
124
 
125
  # Unexpected content type
126
- raise HumeException(f'Unexpected Content-Type: {response.headers.get("Content-Type", "Unknown")}')
127
 
128
- except requests.exceptions.RequestException as e:
129
- logger.exception('Request to Hume TTS API failed.')
130
- raise HumeException(
131
- message=f'Failed to communicate with Hume TTS API: {e}',
132
- original_exception=e,
133
- )
134
  except Exception as e:
135
- logger.exception('Request to Hume TTS API failed.')
136
- raise HumeException(
137
- message=f"Unexpected error while processing the Hume TTS response: {e}",
138
  original_exception=e,
139
  )
 
12
 
13
  Classes:
14
  - HumeConfig: Immutable configuration for interacting with the TTS API.
15
+ - HumeError: Custom exception for TTS API-related errors.
16
 
17
  Functions:
18
  - text_to_speech_with_hume: Converts text to speech using the Hume TTS API with input validation and retry logic.
 
66
  return random.choice(self.voices)
67
 
68
 
69
+ class HumeError(Exception):
70
  """Custom exception for errors related to the Hume TTS API."""
71
  def __init__(self, message: str, original_exception: Optional[Exception] = None):
72
  super().__init__(message)
 
78
 
79
 
80
  @retry(
81
+ stop=stop_after_attempt(1),
82
  wait=wait_fixed(2),
83
  before=before_log(logger, logging.DEBUG),
84
  after=after_log(logger, logging.DEBUG),
85
+ reraise=True
86
  )
87
  def text_to_speech_with_hume(prompt: str, text: str) -> bytes:
88
  """
 
96
  bytes: The raw binary audio data for playback.
97
 
98
  Raises:
99
+ HumeError: If there is an error communicating with the Hume TTS API.
100
  """
101
  logger.debug(f'Processing TTS with Hume. Prompt length: {len(prompt)} characters. Text length: {len(text)} characters.')
102
 
 
115
  # Validate response
116
  if response.status_code != 200:
117
  logger.error(f'Hume TTS API Error: {response.status_code} - {response.text[:200]}... (truncated)')
118
+ raise HumeError(f'Hume TTS API responded with status {response.status_code}: {response.text[:200]}')
119
 
120
  # Process audio response
121
  if response.headers.get('Content-Type', '').startswith('audio/'):
 
124
  return audio_data
125
 
126
  # Unexpected content type
127
+ raise HumeError(f'Unexpected Content-Type: {response.headers.get("Content-Type", "Unknown")}')
128
 
 
 
 
 
 
 
129
  except Exception as e:
130
+ logger.exception(f'Error synthesizing speech from text with Hume: {e}')
131
+ raise HumeError(
132
+ message=f'Failed to synthesize speech from text with Hume: {e}',
133
  original_exception=e,
134
  )