Novachrono93 commited on
Commit
db6fd1b
·
verified ·
1 Parent(s): 6155efd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -28
app.py CHANGED
@@ -1,38 +1,60 @@
1
- from flask import Flask, request, Response, stream_with_context, jsonify
2
- import soundfile as sf
3
  import io
 
 
 
4
 
5
- # --- CRITICAL FIX FOR HUGGING FACE SPACES ---
6
- # This "patches" the missing function that causes the crash.
7
  import phonemizer.backend.espeak.wrapper
8
  from phonemizer.backend.espeak.wrapper import EspeakWrapper
9
-
10
- def dummy_set_data_path(path):
11
- # We ignore this because Docker sets the path automatically
12
- pass
13
-
14
- # We force the library to use our dummy function instead of crashing
15
  EspeakWrapper.set_data_path = dummy_set_data_path
16
- # --------------------------------------------
17
 
18
  from kokoro_onnx import Kokoro
19
 
20
  app = Flask(__name__)
21
 
22
- print("--- STARTUP ---")
23
- print("Loading Kokoro...")
24
- # Now this line won't crash because we fixed the wrapper above
25
- kokoro = Kokoro("kokoro-v1.0.int8.onnx", "voices-v1.0.bin")
26
- print("SUCCESS: Model Loaded!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  @app.route("/", methods=["GET"])
29
  def home():
30
- return "Kokoro TTS API is Online!"
31
 
32
- # Universal Route (Accepts both /v1 and standard paths)
33
- @app.route("/audio/speech", methods=["POST"])
34
  @app.route("/v1/audio/speech", methods=["POST"])
 
35
  def generate_speech():
 
 
 
 
 
36
  try:
37
  data = request.json
38
  text = data.get("input", "")
@@ -40,12 +62,7 @@ def generate_speech():
40
  speed = float(data.get("speed", 1.0))
41
 
42
  def generate_stream():
43
- samples, sample_rate = kokoro.create(
44
- text,
45
- voice=voice,
46
- speed=speed,
47
- lang="en-us"
48
- )
49
  buffer = io.BytesIO()
50
  sf.write(buffer, samples, sample_rate, format='WAV')
51
  buffer.seek(0)
@@ -54,7 +71,6 @@ def generate_speech():
54
  return Response(stream_with_context(generate_stream()), mimetype="audio/wav")
55
 
56
  except Exception as e:
57
- print(f"Error: {e}")
58
  return jsonify({"error": str(e)}), 500
59
 
60
  @app.route("/v1/models", methods=["GET"])
@@ -65,7 +81,11 @@ def list_models():
65
  @app.route("/v1/audio/voices", methods=["GET"])
66
  @app.route("/audio/voices", methods=["GET"])
67
  def list_voices():
68
- return jsonify({"voices": list(kokoro.get_voices())})
 
 
 
69
 
70
  if __name__ == "__main__":
71
- app.run(host="0.0.0.0", port=7860)
 
 
1
+ import os
 
2
  import io
3
+ import threading
4
+ import soundfile as sf
5
+ from flask import Flask, request, Response, stream_with_context, jsonify
6
 
7
+ # --- MONKEY PATCH (Prevents Startup Crash) ---
 
8
  import phonemizer.backend.espeak.wrapper
9
  from phonemizer.backend.espeak.wrapper import EspeakWrapper
10
+ def dummy_set_data_path(path): pass
 
 
 
 
 
11
  EspeakWrapper.set_data_path = dummy_set_data_path
12
+ # ---------------------------------------------
13
 
14
  from kokoro_onnx import Kokoro
15
 
16
  app = Flask(__name__)
17
 
18
+ # GLOBAL VARIABLES
19
+ kokoro = None
20
+ model_loading = False
21
+
22
+ def load_model_lazy():
23
+ """Loads the model only when needed"""
24
+ global kokoro, model_loading
25
+ if kokoro is not None:
26
+ return kokoro
27
+
28
+ if model_loading:
29
+ return None
30
+
31
+ print("--- LOADING KOKORO AI ---")
32
+ model_loading = True
33
+ try:
34
+ k = Kokoro("kokoro-v1.0.int8.onnx", "voices-v1.0.bin")
35
+ kokoro = k
36
+ print("--- KOKORO LOADED SUCCESS ---")
37
+ return kokoro
38
+ except Exception as e:
39
+ print(f"FATAL ERROR: {e}")
40
+ return None
41
+ finally:
42
+ model_loading = False
43
 
44
  @app.route("/", methods=["GET"])
45
  def home():
46
+ return "<h1>Kokoro API is Online</h1>"
47
 
48
+ # --- THE FIX FOR YOUR 404 ERROR ---
49
+ # We accept BOTH standard URL and /v1 URL
50
  @app.route("/v1/audio/speech", methods=["POST"])
51
+ @app.route("/audio/speech", methods=["POST"])
52
  def generate_speech():
53
+ model = load_model_lazy()
54
+
55
+ if not model:
56
+ return jsonify({"error": "Model loading..."}), 503
57
+
58
  try:
59
  data = request.json
60
  text = data.get("input", "")
 
62
  speed = float(data.get("speed", 1.0))
63
 
64
  def generate_stream():
65
+ samples, sample_rate = model.create(text, voice=voice, speed=speed, lang="en-us")
 
 
 
 
 
66
  buffer = io.BytesIO()
67
  sf.write(buffer, samples, sample_rate, format='WAV')
68
  buffer.seek(0)
 
71
  return Response(stream_with_context(generate_stream()), mimetype="audio/wav")
72
 
73
  except Exception as e:
 
74
  return jsonify({"error": str(e)}), 500
75
 
76
  @app.route("/v1/models", methods=["GET"])
 
81
  @app.route("/v1/audio/voices", methods=["GET"])
82
  @app.route("/audio/voices", methods=["GET"])
83
  def list_voices():
84
+ model = load_model_lazy()
85
+ if model:
86
+ return jsonify({"voices": list(model.get_voices())})
87
+ return jsonify({"voices": []})
88
 
89
  if __name__ == "__main__":
90
+ print("Starting Flask Server...")
91
+ app.run(host="0.0.0.0", port=7860)