zach commited on
Commit
f076d8d
·
1 Parent(s): bdd90d1

Improve text length validation and make vote buttons flush with audio players

Browse files
Files changed (4) hide show
  1. pyproject.toml +1 -0
  2. src/app.py +33 -10
  3. src/constants.py +4 -1
  4. src/utils.py +32 -7
pyproject.toml CHANGED
@@ -45,6 +45,7 @@ ignore = [
45
  "PLR0913",
46
  "PLR2004",
47
  "RUF006",
 
48
  "TD002",
49
  "TD003",
50
  ]
 
45
  "PLR0913",
46
  "PLR2004",
47
  "RUF006",
48
+ "SIM117",
49
  "TD002",
50
  "TD003",
51
  ]
src/app.py CHANGED
@@ -35,6 +35,7 @@ from src.utils import (
35
  determine_selected_option,
36
  submit_voting_results,
37
  validate_character_description_length,
 
38
  )
39
 
40
 
@@ -116,9 +117,12 @@ class App:
116
  Raises:
117
  gr.Error: If any API or unexpected errors occur during the TTS synthesis process.
118
  """
119
- if not text:
120
- logger.warning("Skipping text-to-speech due to empty text.")
121
- raise gr.Error("Please generate or enter text to synthesize.")
 
 
 
122
 
123
  # Select 2 TTS providers based on whether the text has been modified.
124
  text_modified = text != generated_text_state
@@ -267,8 +271,8 @@ class App:
267
  return (
268
  gr.update(value=None),
269
  gr.update(value=None, autoplay=False),
270
- gr.update(value=constants.SELECT_OPTION_A, variant="secondary"),
271
- gr.update(value=constants.SELECT_OPTION_B, variant="secondary"),
272
  default_option_map, # Reset option_map_state as a default OptionMap
273
  False,
274
  )
@@ -314,12 +318,31 @@ class App:
314
  show_copy_button=True,
315
  )
316
  synthesize_speech_button = gr.Button("Synthesize Speech", variant="primary")
 
317
  with gr.Row(equal_height=True):
318
- option_a_audio_player = gr.Audio(label=constants.OPTION_A_LABEL, type="filepath", interactive=False)
319
- option_b_audio_player = gr.Audio(label=constants.OPTION_B_LABEL, type="filepath", interactive=False)
320
- with gr.Row(equal_height=True):
321
- vote_button_a = gr.Button(constants.SELECT_OPTION_A, interactive=False)
322
- vote_button_b = gr.Button(constants.SELECT_OPTION_B, interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  return (
324
  text_input,
325
  synthesize_speech_button,
 
35
  determine_selected_option,
36
  submit_voting_results,
37
  validate_character_description_length,
38
+ validate_text_length,
39
  )
40
 
41
 
 
117
  Raises:
118
  gr.Error: If any API or unexpected errors occur during the TTS synthesis process.
119
  """
120
+ try:
121
+ validate_character_description_length(character_description)
122
+ validate_text_length(text)
123
+ except ValueError as ve:
124
+ logger.warning(f"Validation error: {ve}")
125
+ raise gr.Error(str(ve))
126
 
127
  # Select 2 TTS providers based on whether the text has been modified.
128
  text_modified = text != generated_text_state
 
271
  return (
272
  gr.update(value=None),
273
  gr.update(value=None, autoplay=False),
274
+ gr.update(value=constants.SELECT_OPTION_A, variant="secondary", interactive=False),
275
+ gr.update(value=constants.SELECT_OPTION_B, variant="secondary", interactive=False),
276
  default_option_map, # Reset option_map_state as a default OptionMap
277
  False,
278
  )
 
318
  show_copy_button=True,
319
  )
320
  synthesize_speech_button = gr.Button("Synthesize Speech", variant="primary")
321
+
322
  with gr.Row(equal_height=True):
323
+ with gr.Column():
324
+ with gr.Group():
325
+ option_a_audio_player = gr.Audio(
326
+ label=constants.OPTION_A_LABEL,
327
+ type="filepath",
328
+ interactive=False,
329
+ )
330
+ vote_button_a = gr.Button(
331
+ constants.SELECT_OPTION_A,
332
+ interactive=False,
333
+ )
334
+ with gr.Column():
335
+ with gr.Group():
336
+ option_b_audio_player = gr.Audio(
337
+ label=constants.OPTION_B_LABEL,
338
+ type="filepath",
339
+ interactive=False,
340
+ )
341
+ vote_button_b = gr.Button(
342
+ constants.SELECT_OPTION_B,
343
+ interactive=False,
344
+ )
345
+
346
  return (
347
  text_input,
348
  synthesize_speech_button,
src/constants.py CHANGED
@@ -23,7 +23,10 @@ HUME_TO_HUME: ComparisonType = "Hume AI - Hume AI"
23
  HUME_TO_ELEVENLABS: ComparisonType = "Hume AI - ElevenLabs"
24
 
25
  CHARACTER_DESCRIPTION_MIN_LENGTH: int = 20
26
- CHARACTER_DESCRIPTION_MAX_LENGTH: int = 800
 
 
 
27
 
28
  OPTION_A_KEY: OptionKey = "option_a"
29
  OPTION_B_KEY: OptionKey = "option_b"
 
23
  HUME_TO_ELEVENLABS: ComparisonType = "Hume AI - ElevenLabs"
24
 
25
  CHARACTER_DESCRIPTION_MIN_LENGTH: int = 20
26
+ CHARACTER_DESCRIPTION_MAX_LENGTH: int = 1000
27
+
28
+ TEXT_MIN_LENGTH: int = 100
29
+ TEXT_MAX_LENGTH: int = 1000
30
 
31
  OPTION_A_KEY: OptionKey = "option_a"
32
  OPTION_B_KEY: OptionKey = "option_b"
src/utils.py CHANGED
@@ -71,13 +71,6 @@ def validate_character_description_length(character_description: str) -> None:
71
 
72
  Raises:
73
  ValueError: If the character description is empty, too short, or exceeds max length.
74
-
75
- Example:
76
- >>> validate_character_description_length("This is a character description.")
77
- # Passes validation
78
-
79
- >>> validate_character_description_length("")
80
- # Raises ValueError: "Voice Description must be at least 20 characters long."
81
  """
82
  stripped_character_description = character_description.strip()
83
  character_description_length = len(stripped_character_description)
@@ -101,6 +94,38 @@ def validate_character_description_length(character_description: str) -> None:
101
  logger.debug(f"Character description length validation passed for character_description: {truncated_description}")
102
 
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  def _delete_files_older_than(directory: Path, minutes: int = 30) -> None:
105
  """
106
  Delete all files in the specified directory that are older than a given number of minutes.
 
71
 
72
  Raises:
73
  ValueError: If the character description is empty, too short, or exceeds max length.
 
 
 
 
 
 
 
74
  """
75
  stripped_character_description = character_description.strip()
76
  character_description_length = len(stripped_character_description)
 
94
  logger.debug(f"Character description length validation passed for character_description: {truncated_description}")
95
 
96
 
97
+ def validate_text_length(text: str) -> None:
98
+ """
99
+ Validates that a text input is within specified minimum and maximum length limits.
100
+
101
+ Args:
102
+ text (str): The input text to validate.
103
+
104
+ Raises:
105
+ ValueError: If the text is empty, too short, or exceeds max length.
106
+ """
107
+ stripped_text = text.strip()
108
+ text_length = len(stripped_text)
109
+
110
+ logger.debug(f"Voice description length being validated: {text_length} characters")
111
+
112
+ if text_length < constants.TEXT_MIN_LENGTH:
113
+ raise ValueError(
114
+ f"Your text is too short. Please enter at least "
115
+ f"{constants.TEXT_MIN_LENGTH} characters. "
116
+ f"(Current length: {text_length})"
117
+ )
118
+ if text_length > constants.TEXT_MAX_LENGTH:
119
+ raise ValueError(
120
+ f"Your text is too long. Please limit it to "
121
+ f"{constants.TEXT_MAX_LENGTH} characters. "
122
+ f"(Current length: {text_length})"
123
+ )
124
+
125
+ truncated_text = truncate_text(stripped_text)
126
+ logger.debug(f"Character description length validation passed for text: {truncated_text}")
127
+
128
+
129
  def _delete_files_older_than(directory: Path, minutes: int = 30) -> None:
130
  """
131
  Delete all files in the specified directory that are older than a given number of minutes.