Update app.py
Browse files
app.py
CHANGED
@@ -12,6 +12,8 @@ import logging
|
|
12 |
from dash.exceptions import PreventUpdate
|
13 |
import pandas as pd
|
14 |
import time
|
|
|
|
|
15 |
|
16 |
# Set up logging
|
17 |
logging.basicConfig(level=logging.INFO)
|
@@ -20,11 +22,10 @@ logger = logging.getLogger(__name__)
|
|
20 |
# Initialize Dash app
|
21 |
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
|
22 |
|
23 |
-
# Initialize Gemini AI
|
24 |
-
genai.configure(api_key='
|
25 |
|
26 |
-
def generate_podcast_script(
|
27 |
-
genai.configure(api_key=api_key)
|
28 |
model = genai.GenerativeModel('gemini-2.5-pro-preview-03-25')
|
29 |
|
30 |
if num_hosts == 1:
|
@@ -70,7 +71,7 @@ async def text_to_speech(text, voice):
|
|
70 |
audio.seek(0)
|
71 |
return audio.read()
|
72 |
|
73 |
-
async def render_podcast(
|
74 |
lines = [line for line in script.split('\n') if line.strip()]
|
75 |
audio_segments = []
|
76 |
|
@@ -155,7 +156,6 @@ app.layout = dbc.Container([
|
|
155 |
|
156 |
dbc.Card([
|
157 |
dbc.CardBody([
|
158 |
-
dbc.Input(id="api-key-input", type="password", placeholder="Enter your Gemini API Key"),
|
159 |
dbc.Textarea(id="content-input", placeholder="Paste your content or upload a document", rows=5, className="my-3"),
|
160 |
dcc.Upload(
|
161 |
id='document-upload',
|
@@ -192,10 +192,28 @@ app.layout = dbc.Container([
|
|
192 |
inline=True,
|
193 |
className="my-3"
|
194 |
),
|
195 |
-
dbc.Select(
|
196 |
-
|
197 |
-
|
198 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
dbc.Button("Generate Script", id="generate-btn", color="primary", className="mt-3"),
|
200 |
dcc.Loading(
|
201 |
id="loading-script",
|
@@ -219,7 +237,7 @@ app.layout = dbc.Container([
|
|
219 |
])
|
220 |
], fluid=True)
|
221 |
|
222 |
-
# Callbacks
|
223 |
@app.callback(
|
224 |
Output("voice1-select", "options"),
|
225 |
Input("lang1-select", "value")
|
@@ -246,13 +264,12 @@ def update_voice2_options(lang):
|
|
246 |
[Output("script-output", "value"),
|
247 |
Output("script-progress", "value")],
|
248 |
Input("generate-btn", "n_clicks"),
|
249 |
-
[State("
|
250 |
-
State("content-input", "value"),
|
251 |
State("duration", "value"),
|
252 |
State("num-hosts", "value")],
|
253 |
prevent_initial_call=True
|
254 |
)
|
255 |
-
def generate_script(n_clicks,
|
256 |
if n_clicks is None:
|
257 |
raise PreventUpdate
|
258 |
try:
|
@@ -260,7 +277,7 @@ def generate_script(n_clicks, api_key, content, duration, num_hosts):
|
|
260 |
time.sleep(0.5) # Simulate progress
|
261 |
# Instead of yielding, we'll just pass and update at the end
|
262 |
pass
|
263 |
-
script = generate_podcast_script(
|
264 |
return script, 100
|
265 |
except Exception as e:
|
266 |
logger.error(f"Error generating script: {str(e)}")
|
@@ -271,19 +288,18 @@ def generate_script(n_clicks, api_key, content, duration, num_hosts):
|
|
271 |
Output("download-audio", "data"),
|
272 |
Output("podcast-progress", "value")],
|
273 |
Input("generate-podcast-btn", "n_clicks"),
|
274 |
-
[State("
|
275 |
-
State("script-output", "value"),
|
276 |
State("voice1-select", "value"),
|
277 |
State("voice2-select", "value"),
|
278 |
State("num-hosts", "value")],
|
279 |
prevent_initial_call=True
|
280 |
)
|
281 |
-
def render_and_download_podcast(n_clicks,
|
282 |
if n_clicks is None:
|
283 |
raise PreventUpdate
|
284 |
try:
|
285 |
# Run the async function in a synchronous context
|
286 |
-
sample_rate, audio_data = asyncio.run(render_podcast(
|
287 |
|
288 |
# Convert numpy array to WAV
|
289 |
wav_audio = AudioSegment(
|
@@ -351,4 +367,4 @@ def update_content(contents, filename):
|
|
351 |
if __name__ == '__main__':
|
352 |
print("Starting the Dash application...")
|
353 |
app.run(debug=True, host='0.0.0.0', port=7860)
|
354 |
-
print("Dash application has finished running.")
|
|
|
12 |
from dash.exceptions import PreventUpdate
|
13 |
import pandas as pd
|
14 |
import time
|
15 |
+
import os
|
16 |
+
from pydub import AudioSegment
|
17 |
|
18 |
# Set up logging
|
19 |
logging.basicConfig(level=logging.INFO)
|
|
|
22 |
# Initialize Dash app
|
23 |
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
|
24 |
|
25 |
+
# Initialize Gemini AI with environment variable
|
26 |
+
genai.configure(api_key=os.environ.get('GEMINI_API_KEY'))
|
27 |
|
28 |
+
def generate_podcast_script(content, duration, num_hosts):
|
|
|
29 |
model = genai.GenerativeModel('gemini-2.5-pro-preview-03-25')
|
30 |
|
31 |
if num_hosts == 1:
|
|
|
71 |
audio.seek(0)
|
72 |
return audio.read()
|
73 |
|
74 |
+
async def render_podcast(script, voice1, voice2, num_hosts):
|
75 |
lines = [line for line in script.split('\n') if line.strip()]
|
76 |
audio_segments = []
|
77 |
|
|
|
156 |
|
157 |
dbc.Card([
|
158 |
dbc.CardBody([
|
|
|
159 |
dbc.Textarea(id="content-input", placeholder="Paste your content or upload a document", rows=5, className="my-3"),
|
160 |
dcc.Upload(
|
161 |
id='document-upload',
|
|
|
192 |
inline=True,
|
193 |
className="my-3"
|
194 |
),
|
195 |
+
dbc.Select(
|
196 |
+
id="lang1-select",
|
197 |
+
options=[{"label": lang, "value": lang} for lang in language_names.values()],
|
198 |
+
value="English (United States)",
|
199 |
+
className="my-2"
|
200 |
+
),
|
201 |
+
dbc.Select(
|
202 |
+
id="voice1-select",
|
203 |
+
value="en-US-AriaNeural",
|
204 |
+
className="my-2"
|
205 |
+
),
|
206 |
+
dbc.Select(
|
207 |
+
id="lang2-select",
|
208 |
+
options=[{"label": lang, "value": lang} for lang in language_names.values()],
|
209 |
+
value="English (United States)",
|
210 |
+
className="my-2"
|
211 |
+
),
|
212 |
+
dbc.Select(
|
213 |
+
id="voice2-select",
|
214 |
+
value="en-US-BrianNeural",
|
215 |
+
className="my-2"
|
216 |
+
),
|
217 |
dbc.Button("Generate Script", id="generate-btn", color="primary", className="mt-3"),
|
218 |
dcc.Loading(
|
219 |
id="loading-script",
|
|
|
237 |
])
|
238 |
], fluid=True)
|
239 |
|
240 |
+
# Callbacks (continued)
|
241 |
@app.callback(
|
242 |
Output("voice1-select", "options"),
|
243 |
Input("lang1-select", "value")
|
|
|
264 |
[Output("script-output", "value"),
|
265 |
Output("script-progress", "value")],
|
266 |
Input("generate-btn", "n_clicks"),
|
267 |
+
[State("content-input", "value"),
|
|
|
268 |
State("duration", "value"),
|
269 |
State("num-hosts", "value")],
|
270 |
prevent_initial_call=True
|
271 |
)
|
272 |
+
def generate_script(n_clicks, content, duration, num_hosts):
|
273 |
if n_clicks is None:
|
274 |
raise PreventUpdate
|
275 |
try:
|
|
|
277 |
time.sleep(0.5) # Simulate progress
|
278 |
# Instead of yielding, we'll just pass and update at the end
|
279 |
pass
|
280 |
+
script = generate_podcast_script(content, duration, num_hosts)
|
281 |
return script, 100
|
282 |
except Exception as e:
|
283 |
logger.error(f"Error generating script: {str(e)}")
|
|
|
288 |
Output("download-audio", "data"),
|
289 |
Output("podcast-progress", "value")],
|
290 |
Input("generate-podcast-btn", "n_clicks"),
|
291 |
+
[State("script-output", "value"),
|
|
|
292 |
State("voice1-select", "value"),
|
293 |
State("voice2-select", "value"),
|
294 |
State("num-hosts", "value")],
|
295 |
prevent_initial_call=True
|
296 |
)
|
297 |
+
def render_and_download_podcast(n_clicks, script, voice1, voice2, num_hosts):
|
298 |
if n_clicks is None:
|
299 |
raise PreventUpdate
|
300 |
try:
|
301 |
# Run the async function in a synchronous context
|
302 |
+
sample_rate, audio_data = asyncio.run(render_podcast(script, voice1, voice2, num_hosts))
|
303 |
|
304 |
# Convert numpy array to WAV
|
305 |
wav_audio = AudioSegment(
|
|
|
367 |
if __name__ == '__main__':
|
368 |
print("Starting the Dash application...")
|
369 |
app.run(debug=True, host='0.0.0.0', port=7860)
|
370 |
+
print("Dash application has finished running.")
|