HARI PREETHAM commited on
Commit
dff797e
·
1 Parent(s): 44e7f68

\Integrate Sarvam AI STT engine"

Browse files
Files changed (2) hide show
  1. app.py +89 -0
  2. requirements.txt +1 -0
app.py CHANGED
@@ -1,5 +1,6 @@
1
 
2
  import os
 
3
  import logging
4
  import tempfile
5
  import time
@@ -12,6 +13,8 @@ from pydantic import BaseModel
12
  from faster_whisper import WhisperModel
13
  import azure.cognitiveservices.speech as speechsdk
14
  import subprocess
 
 
15
 
16
  logging.basicConfig(level=logging.INFO)
17
  logger = logging.getLogger(__name__)
@@ -206,6 +209,92 @@ async def transcribe_azure(
206
  if p and os.path.exists(p):
207
  os.unlink(p)
208
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  if __name__ == "__main__":
210
  import uvicorn
211
  uvicorn.run(app, host="0.0.0.0", port=8000)
 
1
 
2
  import os
3
+ import asyncio
4
  import logging
5
  import tempfile
6
  import time
 
13
  from faster_whisper import WhisperModel
14
  import azure.cognitiveservices.speech as speechsdk
15
  import subprocess
16
+ import base64
17
+ from sarvamai import AsyncSarvamAI
18
 
19
  logging.basicConfig(level=logging.INFO)
20
  logger = logging.getLogger(__name__)
 
209
  if p and os.path.exists(p):
210
  os.unlink(p)
211
 
212
+ @app.post("/api/transcribe/sarvam", response_model=TranscriptionResponse)
213
+ async def transcribe_sarvam(
214
+ file: UploadFile = File(...),
215
+ language: Optional[str] = Form(None)
216
+ ):
217
+ """Transcribes audio using Sarvam AI (Saaras v3)"""
218
+ key = os.getenv("SARVAM_API_KEY")
219
+ if not key:
220
+ raise HTTPException(status_code=500, detail="Sarvam API key not configured on server.")
221
+
222
+ # Map language codes to Sarvam format (e.g., 'te' -> 'te-IN')
223
+ # Sarvam supports: hi-IN, bn-IN, kn-IN, ml-IN, mr-IN, or-IN, pa-IN, ta-IN, te-IN, gu-IN, en-IN
224
+ lang_map = {
225
+ "te": "te-IN",
226
+ "hi": "hi-IN",
227
+ "en": "en-IN",
228
+ "ta": "ta-IN",
229
+ "kn": "kn-IN",
230
+ "ml": "ml-IN",
231
+ "bn": "bn-IN",
232
+ "mr": "mr-IN",
233
+ "gu": "gu-IN",
234
+ "pa": "pa-IN"
235
+ }
236
+
237
+ sarvam_lang = lang_map.get(language, "en-IN")
238
+
239
+ temp_path = None
240
+ try:
241
+ validate_audio_file(file)
242
+ content = await file.read()
243
+
244
+ # Convert to base64 as required by the streaming SDK example
245
+ audio_data = base64.b64encode(content).decode("utf-8")
246
+
247
+ client = AsyncSarvamAI(api_subscription_key=key)
248
+
249
+ logger.info(f"Sarvam Transcribing {file.filename} | Lang: {sarvam_lang}")
250
+
251
+ async with client.speech_to_text_streaming.connect(
252
+ model="saaras:v3",
253
+ mode="transcribe",
254
+ language_code=sarvam_lang,
255
+ high_vad_sensitivity=True
256
+ ) as ws:
257
+ await ws.transcribe(audio=audio_data)
258
+ # Finish transcription
259
+ await ws.transcribe(audio="")
260
+
261
+ # Collect results
262
+ full_text = ""
263
+ while True:
264
+ try:
265
+ # Sarvam streaming returns partial components
266
+ response = await asyncio.wait_for(ws.recv(), timeout=10.0)
267
+ if not response:
268
+ break
269
+
270
+ # Log the response structure for debugging
271
+ logger.debug(f"Sarvam Response: {response}")
272
+
273
+ # The response is usually a dict or object with transcript
274
+ # Based on typical streaming SDKs, it might have 'transcript' or similar
275
+ if hasattr(response, 'transcript'):
276
+ full_text += response.transcript
277
+ elif isinstance(response, dict) and 'transcript' in response:
278
+ full_text += response['transcript']
279
+
280
+ # If it's a final response, break
281
+ if getattr(response, 'is_final', False) or (isinstance(response, dict) and response.get('is_final')):
282
+ break
283
+
284
+ except asyncio.TimeoutError:
285
+ break
286
+
287
+ return TranscriptionResponse(
288
+ text=full_text.strip() or "Transcription failed or returned empty.",
289
+ language=language or "unknown",
290
+ confidence=1.0,
291
+ duration=0.0
292
+ )
293
+
294
+ except Exception as e:
295
+ logger.error(f"Sarvam STT Error: {e}")
296
+ raise HTTPException(status_code=500, detail=str(e))
297
+
298
  if __name__ == "__main__":
299
  import uvicorn
300
  uvicorn.run(app, host="0.0.0.0", port=8000)
requirements.txt CHANGED
@@ -9,3 +9,4 @@ ffmpeg-python
9
  # Force rebuild trigger for large-v3 model download
10
  numpy
11
  azure-cognitiveservices-speech
 
 
9
  # Force rebuild trigger for large-v3 model download
10
  numpy
11
  azure-cognitiveservices-speech
12
+ sarvamai