WillemVH commited on
Commit
13593ef
·
verified ·
1 Parent(s): 8395ca3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -169
app.py CHANGED
@@ -1,192 +1,60 @@
1
  from flask import Flask, request, jsonify
2
  from flask_cors import CORS
3
  from faster_whisper import WhisperModel
4
- import os
5
  import tempfile
6
- import logging
7
- from werkzeug.utils import secure_filename
8
- import traceback
9
-
10
- # Configure logging
11
- logging.basicConfig(level=logging.INFO)
12
- logger = logging.getLogger(__name__)
13
 
14
- # Initialize Flask app
15
  app = Flask(__name__)
16
- CORS(app) # Enable CORS for cross-origin requests
17
-
18
- # Configuration
19
- app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 # 50MB max file size
20
- app.config['ALLOWED_EXTENSIONS'] = {'wav', 'mp3', 'm4a', 'flac', 'ogg', 'webm'}
21
 
22
- # Load Whisper model
23
- MODEL_SIZE = os.getenv('WHISPER_MODEL', 'tiny') # Can be overridden via env var
24
- DEVICE = 'cpu'
25
- COMPUTE_TYPE = 'int8'
 
26
 
27
- logger.info(f"Loading Whisper model: {MODEL_SIZE}...")
28
- model = WhisperModel(MODEL_SIZE, device=DEVICE, compute_type=COMPUTE_TYPE)
29
- logger.info("Model loaded successfully!")
30
-
31
- def allowed_file(filename):
32
- """Check if file has an allowed extension"""
33
- return '.' in filename and \
34
- filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
35
-
36
- def transcribe_audio(audio_path):
37
- """Transcribe audio file and return text"""
38
- try:
39
- segments, info = model.transcribe(audio_path, beam_size=5, language=None)
40
-
41
- # Collect all segments
42
- transcription = []
43
- for segment in segments:
44
- transcription.append(segment.text)
45
-
46
- return {
47
- 'success': True,
48
- 'text': ' '.join(transcription),
49
- 'language': str(info.language),
50
- 'duration': info.duration
51
- }
52
- except Exception as e:
53
- logger.error(f"Transcription error: {str(e)}")
54
- return {
55
- 'success': False,
56
- 'error': str(e)
57
- }
58
 
59
  @app.route('/health', methods=['GET'])
60
- def health_check():
61
- """Health check endpoint"""
62
- return jsonify({
63
- 'status': 'healthy',
64
- 'model': MODEL_SIZE,
65
- 'device': DEVICE
66
- })
67
 
68
  @app.route('/transcribe', methods=['POST'])
69
- def transcribe():
70
- """
71
- Transcribe audio file
72
- Expected: multipart/form-data with 'audio' file field
73
- Optional: 'language' form field (ISO code, e.g., 'en', 'fr')
74
- """
75
- # Check if file is present
76
  if 'audio' not in request.files:
77
- return jsonify({'error': 'No audio file provided'}), 400
78
 
79
  file = request.files['audio']
80
-
81
- # Check if filename is empty
82
  if file.filename == '':
83
- return jsonify({'error': 'No file selected'}), 400
84
 
85
- # Check file type
86
- if not allowed_file(file.filename):
87
- return jsonify({'error': f'File type not allowed. Allowed: {", ".join(app.config["ALLOWED_EXTENSIONS"])}'}), 400
 
88
 
89
- # Save file temporarily
90
- temp_file = None
91
  try:
92
- # Create temporary file
93
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=f".{file.filename.rsplit('.', 1)[1].lower()}")
94
- file.save(temp_file.name)
95
-
96
- # Get optional language parameter
97
- language = request.form.get('language', None)
98
-
99
- # Transcribe
100
- logger.info(f"Transcribing file: {file.filename}")
101
- result = transcribe_audio(temp_file.name)
102
-
103
- if result['success']:
104
- return jsonify({
105
- 'success': True,
106
- 'transcription': result['text'],
107
- 'language': result['language'],
108
- 'duration': result['duration'],
109
- 'filename': secure_filename(file.filename)
110
- })
111
- else:
112
- return jsonify({'error': result['error']}), 500
113
-
114
  except Exception as e:
115
- logger.error(f"Error processing request: {traceback.format_exc()}")
116
- return jsonify({'error': str(e)}), 500
117
-
118
  finally:
119
- # Clean up temporary file
120
- if temp_file and os.path.exists(temp_file.name):
121
- os.unlink(temp_file.name)
122
-
123
- @app.route('/transcribe_url', methods=['POST'])
124
- def transcribe_url():
125
- """
126
- Transcribe audio from URL
127
- Expected JSON: {'url': 'https://example.com/audio.mp3', 'language': 'en'}
128
- """
129
- data = request.get_json()
130
-
131
- if not data or 'url' not in data:
132
- return jsonify({'error': 'No URL provided'}), 400
133
-
134
- audio_url = data['url']
135
- language = data.get('language', None)
136
-
137
- import requests
138
- import urllib.parse
139
-
140
- # Download audio from URL
141
- temp_file = None
142
- try:
143
- # Download file
144
- response = requests.get(audio_url, stream=True, timeout=30)
145
- response.raise_for_status()
146
-
147
- # Get filename from URL or content-disposition
148
- filename = urllib.parse.unquote(audio_url.split('/')[-1])
149
- if '.' not in filename:
150
- filename = 'audio.mp3' # Default extension
151
-
152
- # Create temporary file
153
- extension = filename.rsplit('.', 1)[1].lower() if '.' in filename else 'mp3'
154
- temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=f".{extension}")
155
-
156
- # Save downloaded content
157
- for chunk in response.iter_content(chunk_size=8192):
158
- if chunk:
159
- temp_file.write(chunk)
160
- temp_file.close()
161
-
162
- # Transcribe
163
- logger.info(f"Transcribing from URL: {audio_url}")
164
- result = transcribe_audio(temp_file.name)
165
-
166
- if result['success']:
167
- return jsonify({
168
- 'success': True,
169
- 'transcription': result['text'],
170
- 'language': result['language'],
171
- 'duration': result['duration'],
172
- 'source_url': audio_url
173
- })
174
- else:
175
- return jsonify({'error': result['error']}), 500
176
-
177
- except requests.exceptions.RequestException as e:
178
- return jsonify({'error': f'Failed to download audio: {str(e)}'}), 400
179
- except Exception as e:
180
- logger.error(f"Error processing URL: {traceback.format_exc()}")
181
- return jsonify({'error': str(e)}), 500
182
- finally:
183
- if temp_file and os.path.exists(temp_file.name):
184
- os.unlink(temp_file.name)
185
-
186
- @app.errorhandler(413)
187
- def too_large(e):
188
- return jsonify({'error': 'File too large. Maximum size is 50MB'}), 413
189
 
190
  if __name__ == '__main__':
191
- port = int(os.getenv('PORT', 5000))
192
- app.run(host='0.0.0.0', port=port, debug=False)
 
1
  from flask import Flask, request, jsonify
2
  from flask_cors import CORS
3
  from faster_whisper import WhisperModel
 
4
  import tempfile
5
+ import os
 
 
 
 
 
 
6
 
 
7
  app = Flask(__name__)
8
+ CORS(app)
 
 
 
 
9
 
10
+ # Load model (same as your working Gradio code)
11
+ model_size = "tiny"
12
+ device = "cpu"
13
+ compute_type = "int8"
14
+ model = WhisperModel(model_size, device=device, compute_type=compute_type)
15
 
16
+ def transcribe(audio_path):
17
+ """Same transcription logic that works in your Gradio app"""
18
+ if audio_path is None:
19
+ return None
20
+ segments, _ = model.transcribe(audio_path, beam_size=5)
21
+ return "".join([segment.text for segment in segments])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
  @app.route('/health', methods=['GET'])
24
+ def health():
25
+ return jsonify({"status": "healthy", "model": model_size})
 
 
 
 
 
26
 
27
  @app.route('/transcribe', methods=['POST'])
28
+ def transcribe_audio():
29
+ # Check if audio file was uploaded
 
 
 
 
 
30
  if 'audio' not in request.files:
31
+ return jsonify({"error": "No audio file provided"}), 400
32
 
33
  file = request.files['audio']
 
 
34
  if file.filename == '':
35
+ return jsonify({"error": "No file selected"}), 400
36
 
37
+ # Save uploaded file temporarily
38
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp_file:
39
+ file.save(tmp_file.name)
40
+ tmp_path = tmp_file.name
41
 
 
 
42
  try:
43
+ # Transcribe using your working function
44
+ text = transcribe(tmp_path)
45
+ if text is None:
46
+ return jsonify({"error": "No audio detected"}), 400
47
+
48
+ return jsonify({
49
+ "success": True,
50
+ "transcription": text
51
+ })
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  except Exception as e:
53
+ return jsonify({"error": str(e)}), 500
 
 
54
  finally:
55
+ # Clean up temp file
56
+ if os.path.exists(tmp_path):
57
+ os.unlink(tmp_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
  if __name__ == '__main__':
60
+ app.run(host='0.0.0.0', port=5000, debug=False)