abocha commited on
Commit
0b876d2
·
1 Parent(s): 7633d98

examples doc

Browse files
Files changed (2) hide show
  1. app.py +58 -46
  2. ui_layout.py +1 -73
app.py CHANGED
@@ -6,9 +6,10 @@ from openai import AsyncOpenAI
6
  from functools import partial
7
  import datetime
8
 
 
9
  from ui_layout import (
10
  create_main_input_components, create_speaker_config_components,
11
- create_action_and_output_components, create_examples_ui, # Keep this import
12
  TTS_MODELS_AVAILABLE, MODEL_DEFAULT_ENV, APP_AVAILABLE_VOICES,
13
  DEFAULT_GLOBAL_VOICE, VIBE_CHOICES, DEFAULT_VIBE, PREDEFINED_VIBES
14
  )
@@ -30,7 +31,7 @@ EFFECTIVE_MODEL_DEFAULT = MODEL_DEFAULT_FROM_ENV if MODEL_DEFAULT_FROM_ENV in TT
30
  async_openai_client = None
31
  if not OPENAI_API_KEY:
32
  # ... (secret loading logic) ...
33
- pass # Keep existing secret loading logic
34
  if OPENAI_API_KEY:
35
  async_openai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)
36
  else:
@@ -45,6 +46,7 @@ with gr.Blocks(theme=gr.themes.Soft(), elem_id="main_blocks_ui") as demo:
45
 
46
  speaker_configs_state = gr.State({})
47
 
 
48
  (script_input, tts_model_dropdown, pause_input,
49
  global_speed_input, global_instructions_input) = create_main_input_components(EFFECTIVE_MODEL_DEFAULT)
50
 
@@ -63,7 +65,7 @@ with gr.Blocks(theme=gr.themes.Soft(), elem_id="main_blocks_ui") as demo:
63
  triggers=[load_per_speaker_ui_button.click, tts_model_dropdown.change]
64
  )
65
  def render_dynamic_speaker_ui(current_script_text: str, current_speaker_configs: dict, current_tts_model: str):
66
- # --- @gr.render content (Full implementation from previous step) ---
67
  print(f"DEBUG: @gr.render CALLED. Model: {current_tts_model}. Script: '{current_script_text[:30]}...'. State Keys: {list(current_speaker_configs.keys()) if isinstance(current_speaker_configs,dict) else 'Not a dict'}")
68
  unique_speakers = get_speakers_from_script(current_script_text)
69
  if not unique_speakers:
@@ -93,58 +95,68 @@ with gr.Blocks(theme=gr.themes.Soft(), elem_id="main_blocks_ui") as demo:
93
  custom_instructions_textbox = gr.Textbox(label="Custom Instructions", value=default_custom_instructions, placeholder="e.g., Speak slightly hesitant.", lines=2, visible=(default_vibe == "Custom..."), elem_id=custom_instr_tb_elem_id)
94
  vibe_dropdown.change(fn=partial(handle_dynamic_accordion_input_change, speaker_name=speaker_name, config_key="vibe"), inputs=[vibe_dropdown, speaker_configs_state], outputs=[speaker_configs_state]).then(fn=lambda vibe_val: gr.update(visible=(vibe_val == "Custom...")), inputs=[vibe_dropdown], outputs=[custom_instructions_textbox])
95
  custom_instructions_textbox.change(fn=partial(handle_dynamic_accordion_input_change, speaker_name=speaker_name, config_key="custom_instructions"), inputs=[custom_instructions_textbox, speaker_configs_state], outputs=[speaker_configs_state])
96
- # --- End of @gr.render content ---
97
 
98
  # --- Event Listeners (Same as before) ---
99
- tts_model_dropdown.change(
100
- fn=handle_tts_model_change,
101
- inputs=[tts_model_dropdown, speaker_configs_state],
102
- outputs=[global_speed_input, global_instructions_input, speaker_configs_state]
103
- )
104
- speaker_config_method_dropdown.change(
105
- fn=handle_speaker_config_method_visibility_change,
106
- inputs=[speaker_config_method_dropdown],
107
- outputs=[single_voice_group, detailed_per_speaker_ui_group_container]
108
- )
109
- load_per_speaker_ui_button.click(
110
- fn=handle_load_refresh_per_speaker_ui_trigger,
111
- inputs=[script_input, speaker_configs_state, tts_model_dropdown],
112
- outputs=[speaker_configs_state]
113
- )
114
- calculate_cost_button.click(
115
- fn=handle_calculate_cost,
116
- inputs=[script_input, tts_model_dropdown],
117
- outputs=[cost_output]
118
- )
119
  generate_button_fn = partial(handle_script_processing, OPENAI_API_KEY, async_openai_client, NSFW_API_URL_TEMPLATE)
120
- generate_button.click(
121
- fn=generate_button_fn,
122
- inputs=[
123
- script_input, tts_model_dropdown, pause_input,
124
- speaker_config_method_dropdown, global_voice_dropdown,
125
- speaker_configs_state,
126
- global_speed_input, global_instructions_input
127
- ],
128
- outputs=[individual_lines_zip_output, merged_dialogue_mp3_output, status_output]
129
- )
130
-
131
- # --- Examples Section Definition ---
132
- example_inputs_list = [
133
  script_input, tts_model_dropdown, pause_input,
134
  speaker_config_method_dropdown, global_voice_dropdown,
135
  speaker_configs_state,
136
  global_speed_input, global_instructions_input
137
  ]
138
- example_outputs_list = [individual_lines_zip_output, merged_dialogue_mp3_output, status_output]
139
- example_process_fn = partial(handle_script_processing, OPENAI_API_KEY, async_openai_client, NSFW_API_URL_TEMPLATE)
 
 
 
 
 
 
 
140
 
141
- # MODIFICATION: Wrap the call to create_examples_ui in a layout block
142
- with gr.Column(elem_id="examples_column"): # Explicitly place the examples in a Column
143
- create_examples_ui( # Call the function here
144
- inputs_for_examples=example_inputs_list,
145
- process_fn=example_process_fn if OPENAI_API_KEY else None,
146
- outputs_for_examples=example_outputs_list if OPENAI_API_KEY else None
147
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
  # --- Launch ---
150
  if __name__ == "__main__":
 
6
  from functools import partial
7
  import datetime
8
 
9
+ # Remove create_examples_ui from ui_layout imports if it's not used elsewhere
10
  from ui_layout import (
11
  create_main_input_components, create_speaker_config_components,
12
+ create_action_and_output_components, # Removed create_examples_ui
13
  TTS_MODELS_AVAILABLE, MODEL_DEFAULT_ENV, APP_AVAILABLE_VOICES,
14
  DEFAULT_GLOBAL_VOICE, VIBE_CHOICES, DEFAULT_VIBE, PREDEFINED_VIBES
15
  )
 
31
  async_openai_client = None
32
  if not OPENAI_API_KEY:
33
  # ... (secret loading logic) ...
34
+ pass
35
  if OPENAI_API_KEY:
36
  async_openai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)
37
  else:
 
46
 
47
  speaker_configs_state = gr.State({})
48
 
49
+ # --- Create Main UI Components ---
50
  (script_input, tts_model_dropdown, pause_input,
51
  global_speed_input, global_instructions_input) = create_main_input_components(EFFECTIVE_MODEL_DEFAULT)
52
 
 
65
  triggers=[load_per_speaker_ui_button.click, tts_model_dropdown.change]
66
  )
67
  def render_dynamic_speaker_ui(current_script_text: str, current_speaker_configs: dict, current_tts_model: str):
68
+ # ... (Full @gr.render implementation from previous correct step) ...
69
  print(f"DEBUG: @gr.render CALLED. Model: {current_tts_model}. Script: '{current_script_text[:30]}...'. State Keys: {list(current_speaker_configs.keys()) if isinstance(current_speaker_configs,dict) else 'Not a dict'}")
70
  unique_speakers = get_speakers_from_script(current_script_text)
71
  if not unique_speakers:
 
95
  custom_instructions_textbox = gr.Textbox(label="Custom Instructions", value=default_custom_instructions, placeholder="e.g., Speak slightly hesitant.", lines=2, visible=(default_vibe == "Custom..."), elem_id=custom_instr_tb_elem_id)
96
  vibe_dropdown.change(fn=partial(handle_dynamic_accordion_input_change, speaker_name=speaker_name, config_key="vibe"), inputs=[vibe_dropdown, speaker_configs_state], outputs=[speaker_configs_state]).then(fn=lambda vibe_val: gr.update(visible=(vibe_val == "Custom...")), inputs=[vibe_dropdown], outputs=[custom_instructions_textbox])
97
  custom_instructions_textbox.change(fn=partial(handle_dynamic_accordion_input_change, speaker_name=speaker_name, config_key="custom_instructions"), inputs=[custom_instructions_textbox, speaker_configs_state], outputs=[speaker_configs_state])
98
+
99
 
100
  # --- Event Listeners (Same as before) ---
101
+ tts_model_dropdown.change(fn=handle_tts_model_change, inputs=[tts_model_dropdown, speaker_configs_state], outputs=[global_speed_input, global_instructions_input, speaker_configs_state])
102
+ speaker_config_method_dropdown.change(fn=handle_speaker_config_method_visibility_change, inputs=[speaker_config_method_dropdown], outputs=[single_voice_group, detailed_per_speaker_ui_group_container])
103
+ load_per_speaker_ui_button.click(fn=handle_load_refresh_per_speaker_ui_trigger, inputs=[script_input, speaker_configs_state, tts_model_dropdown], outputs=[speaker_configs_state])
104
+ calculate_cost_button.click(fn=handle_calculate_cost, inputs=[script_input, tts_model_dropdown], outputs=[cost_output])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  generate_button_fn = partial(handle_script_processing, OPENAI_API_KEY, async_openai_client, NSFW_API_URL_TEMPLATE)
106
+ generate_button.click(fn=generate_button_fn, inputs=[script_input, tts_model_dropdown, pause_input, speaker_config_method_dropdown, global_voice_dropdown, speaker_configs_state, global_speed_input, global_instructions_input], outputs=[individual_lines_zip_output, merged_dialogue_mp3_output, status_output])
107
+
108
+ # --- Examples Section Definition (Moved here) ---
109
+ gr.Markdown("## Example Scripts") # Keep the header if desired
110
+
111
+ # Define the lists needed for Examples right here
112
+ example_inputs_list_comps = [
 
 
 
 
 
 
113
  script_input, tts_model_dropdown, pause_input,
114
  speaker_config_method_dropdown, global_voice_dropdown,
115
  speaker_configs_state,
116
  global_speed_input, global_instructions_input
117
  ]
118
+ example_outputs_list_comps = [individual_lines_zip_output, merged_dialogue_mp3_output, status_output]
119
+ example_process_fn_actual = partial(handle_script_processing, OPENAI_API_KEY, async_openai_client, NSFW_API_URL_TEMPLATE) if OPENAI_API_KEY else None
120
+
121
+ # Define the example data directly
122
+ examples_data = [
123
+ ["[Alice] Hello Bob, this is a test using the detailed configuration method.\\n[Bob] Hi Alice! I'm Bob, and I'll have my own voice settings.\\n[Alice] Let's see how this sounds.", "tts-1-hd", 300, "Detailed Configuration (Per Speaker UI)", DEFAULT_GLOBAL_VOICE, {}, 1.0, ""],
124
+ ["[Narrator] This is a short story.\\n[CharacterA] Once upon a time...\\n[Narrator] ...there was a Gradio app.\\n[CharacterB] And it could talk!", "gpt-4o-mini-tts", 200, "Random per Speaker", DEFAULT_GLOBAL_VOICE, {}, 1.0, "Speak with a gentle, storytelling voice for the narrator."],
125
+ ["[Solo] Just one line, using global voice and speed.", "tts-1", 0, "Single Voice (Global)", "fable", {}, 1.2, ""],
126
+ ]
127
 
128
+ # Validate example data length against input components length
129
+ num_inputs_expected = len(example_inputs_list_comps)
130
+ valid_examples_data_inline = []
131
+ for ex_data in examples_data:
132
+ if len(ex_data) == num_inputs_expected:
133
+ valid_examples_data_inline.append(ex_data)
134
+ else:
135
+ print(f"Warning (Inline Examples): Example data mismatch. Expected {num_inputs_expected}, got {len(ex_data)}. Skipping.")
136
+
137
+ # Directly instantiate gr.Examples if valid data exists
138
+ if valid_examples_data_inline:
139
+ if example_process_fn_actual:
140
+ gr.Examples(
141
+ examples=valid_examples_data_inline,
142
+ inputs=example_inputs_list_comps,
143
+ outputs=example_outputs_list_comps,
144
+ fn=example_process_fn_actual,
145
+ cache_examples=False,
146
+ examples_per_page=5,
147
+ label="Example Scripts (Click to Load & Run)", # Label is optional if header exists
148
+ run_on_click=True
149
+ )
150
+ else:
151
+ gr.Examples(
152
+ examples=valid_examples_data_inline,
153
+ inputs=example_inputs_list_comps,
154
+ examples_per_page=5,
155
+ label="Example Scripts (Click to Load Inputs)", # Label is optional if header exists
156
+ )
157
+ else:
158
+ gr.Markdown("<p style='color: orange;'>No valid examples could be loaded due to configuration mismatch.</p>")
159
+
160
 
161
  # --- Launch ---
162
  if __name__ == "__main__":
ui_layout.py CHANGED
@@ -126,76 +126,4 @@ def create_action_and_output_components():
126
  individual_lines_zip_output = gr.File(label="Download Individual Lines (ZIP)", elem_id="individual_lines_zip_output")
127
  merged_dialogue_mp3_output = gr.Audio(label="Play/Download Merged Dialogue (MP3)", type="filepath", elem_id="merged_dialogue_mp3_output")
128
  status_output = gr.Textbox(label="Status", interactive=False, lines=2, max_lines=5, elem_id="status_output")
129
- return calculate_cost_button, generate_button, cost_output, individual_lines_zip_output, merged_dialogue_mp3_output, status_output
130
-
131
- def create_examples_ui(inputs_for_examples, process_fn, outputs_for_examples=None):
132
- """Creates the examples section."""
133
- print("--- DEBUG: Entering create_examples_ui ---") # DEBUG ENTRY PRINT
134
- gr.Markdown("## Example Scripts")
135
- example_script_1 = "[Alice] Hello Bob, this is a test using the detailed configuration method.\\n[Bob] Hi Alice! I'm Bob, and I'll have my own voice settings.\\n[Alice] Let's see how this sounds."
136
- example_script_2 = "[Narrator] This is a short story.\\n[CharacterA] Once upon a time...\\n[Narrator] ...there was a Gradio app.\\n[CharacterB] And it could talk!"
137
-
138
- examples_data = [
139
- [example_script_1, "tts-1-hd", 300, "Detailed Configuration (Per Speaker UI)", DEFAULT_GLOBAL_VOICE, {}, 1.0, ""],
140
- [example_script_2, "gpt-4o-mini-tts", 200, "Random per Speaker", DEFAULT_GLOBAL_VOICE, {}, 1.0, "Speak with a gentle, storytelling voice for the narrator."],
141
- ["[Solo] Just one line, using global voice and speed.", "tts-1", 0, "Single Voice (Global)", "fable", {}, 1.2, ""],
142
- ]
143
-
144
- # It's crucial that inputs_for_examples is correctly passed from app.py
145
- if not inputs_for_examples:
146
- print("ERROR (Examples): inputs_for_examples list is None or empty!")
147
- return None # Cannot create examples without knowing the input components
148
-
149
- num_inputs = len(inputs_for_examples)
150
- valid_examples_data = []
151
- print(f"DEBUG (Examples): Expected number of inputs based on inputs_for_examples: {num_inputs}")
152
-
153
- for i, ex_data in enumerate(examples_data):
154
- print(f"DEBUG (Examples): Checking example {i+1}, data length: {len(ex_data)}")
155
- if len(ex_data) == num_inputs:
156
- valid_examples_data.append(ex_data)
157
- print(f"DEBUG (Examples): Example {i+1} length matches. Added to valid_examples_data.")
158
- else:
159
- print(f"Warning (Examples): Example data {i+1} mismatch. Expected {num_inputs} items, got {len(ex_data)}. Skipping example: {ex_data[0][:30]}...")
160
-
161
- if not valid_examples_data:
162
- print("DEBUG (Examples): valid_examples_data list is empty after checking all examples. Returning None.")
163
- gr.Markdown("<p style='color: orange;'>No valid examples could be loaded due to configuration mismatch.</p>")
164
- return None
165
-
166
- print(f"DEBUG (Examples): Found {len(valid_examples_data)} valid examples. API Key Present: {bool(process_fn)}. Creating Examples component.")
167
-
168
- if process_fn and outputs_for_examples:
169
- print("DEBUG (Examples): Creating Examples component with run capability.")
170
- try:
171
- examples_component = gr.Examples(
172
- examples=valid_examples_data,
173
- inputs=inputs_for_examples,
174
- outputs=outputs_for_examples,
175
- fn=process_fn,
176
- cache_examples=False,
177
- examples_per_page=5,
178
- label="Example Scripts (Click to Load & Run)",
179
- run_on_click=True
180
- )
181
- print("DEBUG (Examples): Runnable Examples component created successfully.")
182
- return examples_component
183
- except Exception as e:
184
- print(f"ERROR (Examples): Failed to create runnable Examples component: {e}")
185
- gr.Markdown(f"<p style='color: red;'>Error creating runnable examples: {e}</p>")
186
- return None # Return None if creation fails
187
- else:
188
- print("DEBUG (Examples): Creating Examples component as input loaders only (no API key or outputs).")
189
- try:
190
- examples_component = gr.Examples(
191
- examples=valid_examples_data,
192
- inputs=inputs_for_examples,
193
- examples_per_page=5,
194
- label="Example Scripts (Click to Load Inputs)",
195
- )
196
- print("DEBUG (Examples): Input-only Examples component created successfully.")
197
- return examples_component
198
- except Exception as e:
199
- print(f"ERROR (Examples): Failed to create input-only Examples component: {e}")
200
- gr.Markdown(f"<p style='color: red;'>Error creating input-only examples: {e}</p>")
201
- return None # Return None if creation fails
 
126
  individual_lines_zip_output = gr.File(label="Download Individual Lines (ZIP)", elem_id="individual_lines_zip_output")
127
  merged_dialogue_mp3_output = gr.Audio(label="Play/Download Merged Dialogue (MP3)", type="filepath", elem_id="merged_dialogue_mp3_output")
128
  status_output = gr.Textbox(label="Status", interactive=False, lines=2, max_lines=5, elem_id="status_output")
129
+ return calculate_cost_button, generate_button, cost_output, individual_lines_zip_output, merged_dialogue_mp3_output, status_output