o
    %j                     @  s   d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	m
Z
 ddlZddlmZmZ eeZdZdZd	ZdddZdddZdddZG dd deZdS )a  
Sarvam AI Speech-to-Text provider.

Uses the `speech_to_text_translate_job` batch API (model saaras:v2.5) with
speaker diarisation.  Audio is downloaded to a temp file, uploaded to Sarvam,
polled until complete, and the result JSON is parsed into an STTResult.
    )annotationsN)AnyDictList   )BaseSTT	STTResult      i,  
speaker_idstrreturn
int | Nonec              	   C  s0   zt t| ddW S  ttfy   Y d S w )Nspeaker_ )intr   replace	TypeError
ValueErrorr    r   5/home/aiteam/pcaa-dev/dashboard-backend/stt/sarvam.py_speaker_numeric_id   s
   r   segmentsList[Dict[str, Any]]Nonec                 C  sx   dd | D }dd |D }|sd S dd t tt|D }| D ]}t|dd}|d u r0q!d||  |d	< q!d S )
Nc                 S  s   g | ]
}t |d dqS )r   r   )r   get.0segr   r   r   
<listcomp>#   s    z1_apply_display_speaker_labels.<locals>.<listcomp>c                 S     g | ]}|d ur|qS Nr   r   nr   r   r   r    $       c                 S  s   i | ]	\}}||d  qS )r   r   )r   ir$   r   r   r   
<dictcomp>'   s    z1_apply_display_speaker_labels.<locals>.<dictcomp>r   r   Speaker speaker)	enumeratesortedsetr   r   )r   numsid_to_displayr   r$   r   r   r   _apply_display_speaker_labels"   s   r/   resultDict[str, Any]r   c                 C  s^  |  dpd}|  dpi }t|tr| dg ng }g }|D ]L}t| dd}|dr7|}|dd}nd| }|}| dpCd }	|	sIqt| dpPd	}
t| d
pYd	}|d| ||	|
||
|d q|rdd |D }dd |D }|rt	|nd	}|D ]}t
|d }||krdnd|d< qt| |r|d d nd}t|||ddS )z9Convert raw Sarvam JSON output to a normalised STTResult.
transcriptr   diarized_transcriptentriesr   0r   start_time_secondsr   end_time_secondsr(   )r)   r   textstartend
start_timeend_timec                 S  s   g | ]}t |d  qS r   )r   r   r   r   r   r    R   r%   z(_parse_sarvam_result.<locals>.<listcomp>c                 S  r!   r"   r   r#   r   r   r   r    S   r%   agentcustomerroler:   g        sarvam)r2   speaker_segmentsdurationprovider)r   
isinstancedictr   
startswithr   stripfloatappendminr   r/   r   )r0   transcript_textdiarizedr4   rB   entryraw_idr   numr8   r9   r:   r-   min_numr   r$   rC   r   r   r   _parse_sarvam_result/   sP   

rR   c                   @  s2   e Zd ZdZdddZedddZdddZdS )	SarvamSTTz'Sarvam AI batch transcription provider.api_keyr   c                 C  s   |st d|| _d S )Nz#SARVAM_SUBSCRIPTION_KEY is required)r   _api_key)selfrT   r   r   r   __init__f   s   
zSarvamSTT.__init__r   c                 C  s   dS )NrA   r   )rV   r   r   r   provider_namek   s   zSarvamSTT.provider_name	audio_urlcallidr   c                 C  s  ddl m} || jd}d}z&td|| tj|dd}|jdkr.td	|j d
| t	j
dddd}||j |j}W d   n1 sJw   Y  d}ttD ]I}	z|jjddddd}||g}
|
rmW  n2W qU ty } z$dt|v r|	td k rtd||	d  td d}n W Y d}~qUd}~ww |stdt d|  td|t |jttd}| std| dd}|jr|jD ]}|jdkr|jr|jd j} nq|jj |j!|gd}d}|j"r||j"v r|j"| j#}|std tj|dd}|jdkrtd!|j td"| t$|% W |r4t&j'(|r5t&)| S S S |rFt&j'(|rGt&)| w w w )#z8Download *audio_url*, submit to Sarvam, wait for result.r   )SarvamAI)api_subscription_keyNz[%s] Downloading audio: %s<   )timeout   zAudio download failed: HTTP z for z.wavFz/tmp)suffixdeletedirzsaaras:v2.5T   zTranslate all speech to English)modelwith_diarizationnum_speakersprompt403r   u2   [%s] Upload attempt %d/5 failed (403), retrying…zAll z upload attempts failedu-   [%s] Sarvam job started, waiting (max %ds)…)poll_intervalr^   z#Sarvam job did not succeed (status=)z0.jsonSuccess)job_idfilesz$No download URL in Sarvam job resultzResult download failed: HTTP z[%s] Transcription complete.)*sarvamair[   rU   loggerinforequestsr   status_codeRuntimeErrortempfileNamedTemporaryFilewritecontentnamerange_MAX_UPLOAD_RETRIESspeech_to_text_translate_job
create_jobupload_filesr   warningtimesleepr9   _JOB_TIMEOUT_Swait_until_complete_POLL_INTERVAL_Sis_successfuljob_detailsstateoutputs	file_nameget_download_linksrl   download_urlsfile_urlrR   jsonospathexistsunlink)rV   rY   rZ   r[   clienttmp_pathresptmpjobattemptokexcstatusoutput_filedetaillinksdl_urlresult_respr   r   r   
transcribeo   s   


zSarvamSTT.transcribeN)rT   r   )r   r   )rY   r   rZ   r   r   r   )__name__
__module____qualname____doc__rW   propertyrX   r   r   r   r   r   rS   c   s    
rS   )r   r   r   r   )r   r   r   r   )r0   r1   r   r   )r   
__future__r   loggingr   rt   r   typingr   r   r   rq   baser   r   	getLoggerr   ro   rz   r   r   r   r/   rR   rS   r   r   r   r   <module>   s"    



4