Vedika commited on
Commit
00701d3
·
verified ·
1 Parent(s): f24ca65

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -46
app.py CHANGED
@@ -2,26 +2,35 @@ import os
2
  import requests
3
  import json
4
  import re
5
- import io
6
- import tempfile
7
  from datetime import datetime, timedelta, timezone
8
  from bs4 import BeautifulSoup
9
  from flask import Flask, request, Response, stream_with_context, render_template_string
10
- from supertonic import TTS
11
 
12
  app = Flask(__name__)
13
 
14
  # ----------------------------------------------------
15
- # INIT TTS MODEL (SUPERTONIC 3) LOADED IN MEMORY
16
  # ----------------------------------------------------
17
- print("Loading Supertonic TTS Model...")
18
- try:
19
- tts = TTS(auto_download=True)
20
- print("TTS Model loaded successfully!")
21
- except Exception as e:
22
- print(f"Error initializing TTS: {e}")
23
- tts = None
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  VOICES = ["M1", "M2", "M3", "M4", "M5", "F1", "F2", "F3", "F4", "F5"]
26
  LANGUAGES = {
27
  "English": "en", "Korean": "ko", "Japanese": "ja", "Arabic": "ar",
@@ -34,8 +43,6 @@ LANGUAGES = {
34
  "Turkish": "tr", "Ukrainian": "uk", "Vietnamese": "vi"
35
  }
36
 
37
- VOICE_STYLES_CACHE = {}
38
-
39
  # ----------------------------------------------------
40
  # GPS REVERSE GEOCODING
41
  # ----------------------------------------------------
@@ -68,7 +75,6 @@ def web_search_scraper(query, num_results=5, user_address=None):
68
  params = {"engine": "google", "q": search_query, "api_key": serpapi_key, "num": num_results, "hl": "en", "gl": "in"}
69
  response = requests.get("https://serpapi.com/search", params=params, timeout=10)
70
  data = response.json()
71
-
72
  if "organic_results" in data:
73
  for item in data["organic_results"]:
74
  title = item.get("title", "")
@@ -128,7 +134,7 @@ def home():
128
  return f"<h1>System Error</h1><p>index.html missing: {str(e)}</p>"
129
 
130
  # ----------------------------------------------------
131
- # CHAT API ENDPOINT
132
  # ----------------------------------------------------
133
  @app.route('/api/chat', methods=['POST'])
134
  def chat():
@@ -239,6 +245,33 @@ STRICT DIRECTIVES:
239
  "stream": True
240
  }
241
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  try:
243
  response = requests.post(INVOKE_URL, headers=headers, json=payload, stream=True, timeout=60)
244
  if response.status_code != 200:
@@ -265,20 +298,16 @@ STRICT DIRECTIVES:
265
  yield decoded + "\n\n"
266
  else:
267
  yield decoded + "\n\n"
268
-
269
  return Response(stream_with_context(generate()), mimetype='text/event-stream')
270
  except Exception as e:
271
  err_msg = json.dumps({"error": str(e)})
272
  return Response(f"data: {err_msg}\n\n", mimetype='text/event-stream')
273
 
274
  # ----------------------------------------------------
275
- # TTS DIRECT API ENDPOINT - MATCHING GRADIO SPACE LOGIC
276
  # ----------------------------------------------------
277
  @app.route('/api/tts', methods=['POST'])
278
  def generate_tts():
279
- if tts is None:
280
- return Response(json.dumps({"error": "TTS model failed to load on server."}), status=500, mimetype='application/json')
281
-
282
  data = request.get_json() or {}
283
  text = data.get("text", "")
284
  voice = data.get("voice", "M2")
@@ -287,32 +316,10 @@ def generate_tts():
287
  if not text.strip():
288
  return Response(json.dumps({"error": "Text is empty."}), status=400, mimetype='application/json')
289
 
290
- try:
291
- lang_code = LANGUAGES.get(language_name, "en")
292
- # Get voice style (cached for efficiency)
293
- if voice not in VOICE_STYLES_CACHE:
294
- VOICE_STYLES_CACHE[voice] = tts.get_voice_style(voice_name=voice)
295
- style = VOICE_STYLES_CACHE[voice]
296
- if style is None:
297
- return Response(json.dumps({"error": f"Voice '{voice}' not available."}), status=400, mimetype='application/json')
298
-
299
- # Synthesize - exactly like Gradio: raw text, no cleaning
300
- wav, duration = tts.synthesize(text, voice_style=style, lang=lang_code)
301
-
302
- # Save to a temporary file using tts.save_audio (ensures correct WAV encoding)
303
- with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as tmp_file:
304
- tmp_path = tmp_file.name
305
- tts.save_audio(wav, tmp_path)
306
-
307
- # Read the WAV file and return it
308
- with open(tmp_path, 'rb') as f:
309
- audio_data = f.read()
310
- os.unlink(tmp_path) # clean up
311
-
312
- return Response(audio_data, mimetype="audio/wav")
313
- except Exception as e:
314
- print(f"TTS Synthesis Error: {e}")
315
- return Response(json.dumps({"error": f"TTS synthesis failed: {str(e)}"}), status=500, mimetype='application/json')
316
 
317
  if __name__ == '__main__':
318
  app.run(host='0.0.0.0', port=7860)
 
2
  import requests
3
  import json
4
  import re
5
+ import base64
 
6
  from datetime import datetime, timedelta, timezone
7
  from bs4 import BeautifulSoup
8
  from flask import Flask, request, Response, stream_with_context, render_template_string
 
9
 
10
  app = Flask(__name__)
11
 
12
  # ----------------------------------------------------
13
+ # REMOTE TTS HELPER (CALLS EXTERNAL FASTAPI ENDPOINT)
14
  # ----------------------------------------------------
15
+ REMOTE_TTS_URL = "https://vedalabs-rekha-tts-demo.hf.space/synthesize"
 
 
 
 
 
 
16
 
17
+ def get_remote_tts(text, voice='M2', language='English'):
18
+ try:
19
+ payload = {
20
+ "text": text,
21
+ "voice": voice,
22
+ "language": language
23
+ }
24
+ response = requests.post(REMOTE_TTS_URL, json=payload, timeout=30)
25
+ if response.status_code != 200:
26
+ return None, f"TTS API error: {response.status_code}"
27
+ return response.content, None
28
+ except Exception as e:
29
+ return None, str(e)
30
+
31
+ # ----------------------------------------------------
32
+ # AVAILABLE VOICES & LANGUAGES (for reference)
33
+ # ----------------------------------------------------
34
  VOICES = ["M1", "M2", "M3", "M4", "M5", "F1", "F2", "F3", "F4", "F5"]
35
  LANGUAGES = {
36
  "English": "en", "Korean": "ko", "Japanese": "ja", "Arabic": "ar",
 
43
  "Turkish": "tr", "Ukrainian": "uk", "Vietnamese": "vi"
44
  }
45
 
 
 
46
  # ----------------------------------------------------
47
  # GPS REVERSE GEOCODING
48
  # ----------------------------------------------------
 
75
  params = {"engine": "google", "q": search_query, "api_key": serpapi_key, "num": num_results, "hl": "en", "gl": "in"}
76
  response = requests.get("https://serpapi.com/search", params=params, timeout=10)
77
  data = response.json()
 
78
  if "organic_results" in data:
79
  for item in data["organic_results"]:
80
  title = item.get("title", "")
 
134
  return f"<h1>System Error</h1><p>index.html missing: {str(e)}</p>"
135
 
136
  # ----------------------------------------------------
137
+ # CHAT API ENDPOINT (with TTS via remote endpoint)
138
  # ----------------------------------------------------
139
  @app.route('/api/chat', methods=['POST'])
140
  def chat():
 
245
  "stream": True
246
  }
247
 
248
+ tts_flag = data.get("tts", False)
249
+ if tts_flag:
250
+ payload["stream"] = False
251
+ try:
252
+ response = requests.post(INVOKE_URL, headers=headers, json=payload, timeout=60)
253
+ if response.status_code != 200:
254
+ return Response(json.dumps({"error": f"API Error {response.status_code}"}), status=500, mimetype='application/json')
255
+ resp_json = response.json()
256
+ full_text = resp_json['choices'][0]['message']['content']
257
+ clean_text = re.sub(r'<think>.*?</think>', '', full_text, flags=re.DOTALL).strip()
258
+ if not clean_text:
259
+ clean_text = full_text
260
+ voice_tts = data.get("voice", "M2")
261
+ lang_tts = data.get("language_name", "English")
262
+ audio_bytes, error = get_remote_tts(clean_text, voice=voice_tts, language=lang_tts)
263
+ if error:
264
+ return Response(json.dumps({"error": error}), status=500, mimetype='application/json')
265
+ return Response(
266
+ json.dumps({
267
+ "text": full_text,
268
+ "audio_base64": base64.b64encode(audio_bytes).decode('utf-8')
269
+ }),
270
+ mimetype='application/json'
271
+ )
272
+ except Exception as e:
273
+ return Response(json.dumps({"error": str(e)}), status=500, mimetype='application/json')
274
+
275
  try:
276
  response = requests.post(INVOKE_URL, headers=headers, json=payload, stream=True, timeout=60)
277
  if response.status_code != 200:
 
298
  yield decoded + "\n\n"
299
  else:
300
  yield decoded + "\n\n"
 
301
  return Response(stream_with_context(generate()), mimetype='text/event-stream')
302
  except Exception as e:
303
  err_msg = json.dumps({"error": str(e)})
304
  return Response(f"data: {err_msg}\n\n", mimetype='text/event-stream')
305
 
306
  # ----------------------------------------------------
307
+ # TTS DIRECT API ENDPOINT (NOW REMOTE)
308
  # ----------------------------------------------------
309
  @app.route('/api/tts', methods=['POST'])
310
  def generate_tts():
 
 
 
311
  data = request.get_json() or {}
312
  text = data.get("text", "")
313
  voice = data.get("voice", "M2")
 
316
  if not text.strip():
317
  return Response(json.dumps({"error": "Text is empty."}), status=400, mimetype='application/json')
318
 
319
+ audio_bytes, error = get_remote_tts(text, voice=voice, language=language_name)
320
+ if error:
321
+ return Response(json.dumps({"error": error}), status=500, mimetype='application/json')
322
+ return Response(audio_bytes, mimetype="audio/wav")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
 
324
  if __name__ == '__main__':
325
  app.run(host='0.0.0.0', port=7860)