Coco-18 commited on
Commit
4c12485
Β·
verified Β·
1 Parent(s): da8916e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +195 -186
app.py CHANGED
@@ -1,187 +1,196 @@
1
- # app.py - Main application file
2
-
3
- import os
4
- import sys
5
- import logging
6
- import traceback
7
-
8
- # Configure logging
9
- logging.basicConfig(
10
- level=logging.INFO,
11
- format='%(asctime)s - %(levelname)s - %(message)s',
12
- datefmt='%Y-%m-%d %H:%M:%S'
13
- )
14
- logger = logging.getLogger("speech_api")
15
-
16
- # Set all cache directories to locations within /tmp
17
- cache_dirs = {
18
- "HF_HOME": "/tmp/hf_home",
19
- "TRANSFORMERS_CACHE": "/tmp/transformers_cache",
20
- "HUGGINGFACE_HUB_CACHE": "/tmp/huggingface_hub_cache",
21
- "TORCH_HOME": "/tmp/torch_home",
22
- "XDG_CACHE_HOME": "/tmp/xdg_cache"
23
- }
24
-
25
- # Set environment variables and create directories
26
- for env_var, path in cache_dirs.items():
27
- os.environ[env_var] = path
28
- try:
29
- os.makedirs(path, exist_ok=True)
30
- logger.info(f"πŸ“ Created cache directory: {path}")
31
- except Exception as e:
32
- logger.error(f"❌ Failed to create directory {path}: {str(e)}")
33
-
34
- # Now import the rest of the libraries
35
- try:
36
- import librosa
37
- import glob
38
- import numpy as np
39
- import torch
40
- from pydub import AudioSegment
41
- import tempfile
42
- import soundfile as sf
43
- from flask import Flask, request, jsonify, send_file, g
44
- from flask_cors import CORS
45
- from werkzeug.utils import secure_filename
46
-
47
- # Import functionality from other modules
48
- from translator import (
49
- init_models, check_model_status, handle_asr_request,
50
- handle_tts_request, handle_translation_request
51
- )
52
- from evaluate import (
53
- handle_evaluation_request, handle_upload_reference,
54
- init_reference_audio, calculate_similarity
55
- )
56
-
57
- logger.info("βœ… All required libraries imported successfully")
58
- except ImportError as e:
59
- logger.critical(f"❌ Failed to import necessary libraries: {str(e)}")
60
- sys.exit(1)
61
-
62
- # Check CUDA availability
63
- if torch.cuda.is_available():
64
- logger.info(f"πŸš€ CUDA available: {torch.cuda.get_device_name(0)}")
65
- device = "cuda"
66
- else:
67
- logger.info("⚠️ CUDA not available, using CPU")
68
- device = "cpu"
69
-
70
- # Constants
71
- SAMPLE_RATE = 16000
72
- OUTPUT_DIR = "/tmp/audio_outputs"
73
- REFERENCE_AUDIO_DIR = "./reference_audio"
74
-
75
- try:
76
- os.makedirs(OUTPUT_DIR, exist_ok=True)
77
- logger.info(f"πŸ“ Created output directory: {OUTPUT_DIR}")
78
- except Exception as e:
79
- logger.error(f"❌ Failed to create output directory: {str(e)}")
80
-
81
- # Initialize Flask app
82
- app = Flask(__name__)
83
- CORS(app)
84
-
85
- # Load models
86
- init_models(device)
87
-
88
-
89
- # Define routes
90
- @app.route("/", methods=["GET"])
91
- def home():
92
- return jsonify({"message": "Speech API is running", "status": "active"})
93
-
94
-
95
- @app.route("/health", methods=["GET"])
96
- def health_check():
97
- health_status = check_model_status()
98
- health_status["api_status"] = "online"
99
- health_status["device"] = device
100
- return jsonify(health_status)
101
-
102
-
103
- @app.route("/asr", methods=["POST"])
104
- def transcribe_audio():
105
- return handle_asr_request(request, OUTPUT_DIR, SAMPLE_RATE)
106
-
107
-
108
- @app.route("/tts", methods=["POST"])
109
- def generate_tts():
110
- return handle_tts_request(request, OUTPUT_DIR)
111
-
112
-
113
- @app.route("/translate", methods=["POST"])
114
- def translate_text():
115
- return handle_translation_request(request)
116
-
117
-
118
- @app.route("/download/<filename>", methods=["GET"])
119
- def download_audio(filename):
120
- file_path = os.path.join(OUTPUT_DIR, filename)
121
- if os.path.exists(file_path):
122
- logger.info(f"πŸ“€ Serving audio file: {file_path}")
123
- return send_file(file_path, mimetype="audio/wav", as_attachment=True)
124
-
125
- logger.warning(f"⚠️ Requested file not found: {file_path}")
126
- return jsonify({"error": "File not found"}), 404
127
-
128
-
129
- @app.route("/evaluate", methods=["POST"])
130
- def evaluate_pronunciation():
131
- return handle_evaluation_request(request, REFERENCE_AUDIO_DIR, OUTPUT_DIR, SAMPLE_RATE)
132
-
133
-
134
- @app.route("/check_references", methods=["GET"])
135
- def check_references():
136
- """Endpoint to check if reference files exist and are accessible"""
137
- ref_patterns = ["mayap_a_abak", "mayap_a_ugtu", "mayap_a_gatpanapun",
138
- "mayap_a_bengi", "komusta_ka"]
139
- results = {}
140
-
141
- for pattern in ref_patterns:
142
- pattern_dir = os.path.join(REFERENCE_AUDIO_DIR, pattern)
143
- if os.path.exists(pattern_dir):
144
- wav_files = glob.glob(os.path.join(pattern_dir, "*.wav"))
145
- results[pattern] = {
146
- "exists": True,
147
- "path": pattern_dir,
148
- "file_count": len(wav_files),
149
- "files": [os.path.basename(f) for f in wav_files]
150
- }
151
- else:
152
- results[pattern] = {
153
- "exists": False,
154
- "path": pattern_dir
155
- }
156
-
157
- return jsonify({
158
- "reference_audio_dir": REFERENCE_AUDIO_DIR,
159
- "directory_exists": os.path.exists(REFERENCE_AUDIO_DIR),
160
- "patterns": results
161
- })
162
-
163
-
164
- @app.route("/upload_reference", methods=["POST"])
165
- def upload_reference_audio():
166
- return handle_upload_reference(request, REFERENCE_AUDIO_DIR, SAMPLE_RATE)
167
-
168
-
169
- # Add an initialization route that will be called before the first request
170
- @app.before_request
171
- def before_request():
172
- if not hasattr(g, 'initialized'):
173
- init_reference_audio(REFERENCE_AUDIO_DIR, OUTPUT_DIR)
174
- g.initialized = True
175
-
176
-
177
- if __name__ == "__main__":
178
- init_reference_audio(REFERENCE_AUDIO_DIR, OUTPUT_DIR)
179
- logger.info("πŸš€ Starting Speech API server")
180
-
181
- # Get the status for logging
182
- status = check_model_status()
183
- logger.info(f"πŸ“Š System status: ASR model: {'βœ…' if status['asr_model'] == 'loaded' else '❌'}")
184
- for lang, model_status in status['tts_models'].items():
185
- logger.info(f"πŸ“Š TTS model {lang}: {'βœ…' if model_status == 'loaded' else '❌'}")
186
-
 
 
 
 
 
 
 
 
 
187
  app.run(host="0.0.0.0", port=7860, debug=True)
 
1
+ # app.py - Main application file
2
+
3
+ import os
4
+ import sys
5
+ import logging
6
+ import traceback
7
+
8
+ # Configure logging
9
+ logging.basicConfig(
10
+ level=logging.INFO,
11
+ format='%(asctime)s - %(levelname)s - %(message)s',
12
+ datefmt='%Y-%m-%d %H:%M:%S'
13
+ )
14
+ logger = logging.getLogger("speech_api")
15
+
16
+ # Set all cache directories to locations within /tmp
17
+ cache_dirs = {
18
+ "HF_HOME": "/tmp/hf_home",
19
+ "TRANSFORMERS_CACHE": "/tmp/transformers_cache",
20
+ "HUGGINGFACE_HUB_CACHE": "/tmp/huggingface_hub_cache",
21
+ "TORCH_HOME": "/tmp/torch_home",
22
+ "XDG_CACHE_HOME": "/tmp/xdg_cache"
23
+ }
24
+
25
+ # Set environment variables and create directories
26
+ for env_var, path in cache_dirs.items():
27
+ os.environ[env_var] = path
28
+ try:
29
+ os.makedirs(path, exist_ok=True)
30
+ logger.info(f"πŸ“ Created cache directory: {path}")
31
+ except Exception as e:
32
+ logger.error(f"❌ Failed to create directory {path}: {str(e)}")
33
+
34
+ # Now import the rest of the libraries
35
+ try:
36
+ import librosa
37
+ import glob
38
+ import numpy as np
39
+ import torch
40
+ from pydub import AudioSegment
41
+ import tempfile
42
+ import soundfile as sf
43
+ from flask import Flask, request, jsonify, send_file, g
44
+ from flask_cors import CORS
45
+ from werkzeug.utils import secure_filename
46
+
47
+ # Import functionality from other modules
48
+ from translator import (
49
+ init_models, check_model_status, handle_asr_request,
50
+ handle_tts_request, handle_translation_request
51
+ )
52
+ from evaluate import (
53
+ handle_evaluation_request, handle_upload_reference,
54
+ init_reference_audio, calculate_similarity
55
+ )
56
+
57
+ logger.info("βœ… All required libraries imported successfully")
58
+ except ImportError as e:
59
+ logger.critical(f"❌ Failed to import necessary libraries: {str(e)}")
60
+ sys.exit(1)
61
+
62
+ # Check CUDA availability
63
+ if torch.cuda.is_available():
64
+ logger.info(f"πŸš€ CUDA available: {torch.cuda.get_device_name(0)}")
65
+ device = "cuda"
66
+ else:
67
+ logger.info("⚠️ CUDA not available, using CPU")
68
+ device = "cpu"
69
+
70
+ # Constants
71
+ SAMPLE_RATE = 16000
72
+ OUTPUT_DIR = "/tmp/audio_outputs"
73
+ REFERENCE_AUDIO_DIR = "./reference_audio"
74
+
75
+ try:
76
+ os.makedirs(OUTPUT_DIR, exist_ok=True)
77
+ logger.info(f"πŸ“ Created output directory: {OUTPUT_DIR}")
78
+ except Exception as e:
79
+ logger.error(f"❌ Failed to create output directory: {str(e)}")
80
+
81
+ # Initialize Flask app
82
+ app = Flask(__name__)
83
+ CORS(app)
84
+
85
+ # Load models
86
+ init_models(device)
87
+
88
+
89
+ # Define routes
90
+ @app.route("/", methods=["GET"])
91
+ def home():
92
+ return jsonify({"message": "Speech API is running", "status": "active"})
93
+
94
+
95
+ @app.route("/health", methods=["GET"])
96
+ def health_check():
97
+ health_status = check_model_status()
98
+ health_status["api_status"] = "online"
99
+ health_status["device"] = device
100
+ return jsonify(health_status)
101
+
102
+
103
+ @app.route("/asr", methods=["POST"])
104
+ def transcribe_audio():
105
+ return handle_asr_request(request, OUTPUT_DIR, SAMPLE_RATE)
106
+
107
+
108
+ @app.route("/tts", methods=["POST"])
109
+ def generate_tts():
110
+ return handle_tts_request(request, OUTPUT_DIR)
111
+
112
+
113
+ @app.route("/translate", methods=["POST"])
114
+ def translate_text():
115
+ return handle_translation_request(request)
116
+
117
+
118
+ @app.route("/download/<filename>", methods=["GET"])
119
+ def download_audio(filename):
120
+ file_path = os.path.join(OUTPUT_DIR, filename)
121
+ if os.path.exists(file_path):
122
+ logger.info(f"πŸ“€ Serving audio file: {file_path}")
123
+ return send_file(file_path, mimetype="audio/wav", as_attachment=True)
124
+
125
+ logger.warning(f"⚠️ Requested file not found: {file_path}")
126
+ return jsonify({"error": "File not found"}), 404
127
+
128
+
129
+ @app.route("/evaluate", methods=["POST"])
130
+ def evaluate_pronunciation():
131
+ return handle_evaluation_request(request, REFERENCE_AUDIO_DIR, OUTPUT_DIR, SAMPLE_RATE)
132
+
133
+
134
+ @app.route("/check_references", methods=["GET"])
135
+ def check_references():
136
+ """Endpoint to check if reference files exist and are accessible"""
137
+ ref_patterns = ["mayap_a_abak", "mayap_a_ugtu", "mayap_a_gatpanapun",
138
+ "mayap_a_bengi", "komusta_ka"]
139
+ results = {}
140
+
141
+ for pattern in ref_patterns:
142
+ pattern_dir = os.path.join(REFERENCE_AUDIO_DIR, pattern)
143
+ if os.path.exists(pattern_dir):
144
+ wav_files = glob.glob(os.path.join(pattern_dir, "*.wav"))
145
+ results[pattern] = {
146
+ "exists": True,
147
+ "path": pattern_dir,
148
+ "file_count": len(wav_files),
149
+ "files": [os.path.basename(f) for f in wav_files]
150
+ }
151
+ else:
152
+ results[pattern] = {
153
+ "exists": False,
154
+ "path": pattern_dir
155
+ }
156
+
157
+ return jsonify({
158
+ "reference_audio_dir": REFERENCE_AUDIO_DIR,
159
+ "directory_exists": os.path.exists(REFERENCE_AUDIO_DIR),
160
+ "patterns": results
161
+ })
162
+
163
+
164
+ @app.route("/upload_reference", methods=["POST"])
165
+ def upload_reference_audio():
166
+ return handle_upload_reference(request, REFERENCE_AUDIO_DIR, SAMPLE_RATE)
167
+
168
+
169
+ @app.before_request
170
+ def before_request():
171
+ global REFERENCE_AUDIO_DIR # Add this line
172
+ if not hasattr(g, 'initialized'):
173
+ # This might return an updated path if the original fails
174
+ updated_ref_dir = init_reference_audio(REFERENCE_AUDIO_DIR, OUTPUT_DIR)
175
+ if updated_ref_dir and updated_ref_dir != REFERENCE_AUDIO_DIR:
176
+ REFERENCE_AUDIO_DIR = updated_ref_dir
177
+ logger.info(f"πŸ“ Updated reference audio directory to: {REFERENCE_AUDIO_DIR}")
178
+ g.initialized = True
179
+
180
+ if __name__ == "__main__":
181
+ global REFERENCE_AUDIO_DIR # Add this line
182
+ # This might return an updated path if the original fails
183
+ updated_ref_dir = init_reference_audio(REFERENCE_AUDIO_DIR, OUTPUT_DIR)
184
+ if updated_ref_dir and updated_ref_dir != REFERENCE_AUDIO_DIR:
185
+ REFERENCE_AUDIO_DIR = updated_ref_dir
186
+ logger.info(f"πŸ“ Updated reference audio directory to: {REFERENCE_AUDIO_DIR}")
187
+
188
+ logger.info("πŸš€ Starting Speech API server")
189
+
190
+ # Get the status for logging
191
+ status = check_model_status()
192
+ logger.info(f"πŸ“Š System status: ASR model: {'βœ…' if status['asr_model'] == 'loaded' else '❌'}")
193
+ for lang, model_status in status['tts_models'].items():
194
+ logger.info(f"πŸ“Š TTS model {lang}: {'βœ…' if model_status == 'loaded' else '❌'}")
195
+
196
  app.run(host="0.0.0.0", port=7860, debug=True)