o
    eiwF                     @   s  d dl Z d dlZd dlmZmZ ejejd edZd dl	m
Z
mZmZ d dlmZ d dlmZmZ zd dlmZmZmZmZmZ W n) eym   d dlZeje je je d dlmZmZmZmZmZ Y nw zd d	lm Z m!Z!m"Z"m#Z#m$Z$ W n) ey   d dlZeje je je d d	lm Z m!Z!m"Z"m#Z#m$Z$ Y nw G d
d deZ%G dd deZ&G dd deZ'G dd deZ(G dd deZ)G dd deZ*G dd deZ+G dd deZ,e
dde dd-e de$ dd-e" d d!Z.e.j/ed"gd#d"gd"gd$ e.j0d%e&d&d'e d(d)d*id)d+id)d,id-d.gd/d0e%fd1d2Z1e.j0d3e*d4d5e" d6d)d7id)d8id)d9id-d:gd/d0e)fd;d<Z2e.j3d=e(d>d?d@gdAdBdC Z4e.j3dDe,dEdFd@gdAdGdH Z5e.j3dIdJdKd@gdLdMdN Z6dS )O    N)ListOptional)levelresponse_iq_api)FastAPIHTTPExceptionstatus)CORSMiddleware)	BaseModelField)analyze_responseLANGUAGE_CONFIGDEFAULT_LANGUAGESUPPORTED_LANGUAGESOLLAMA_MODEL)generate_ttsTTS_LANGUAGE_CONFIGTTS_SUPPORTED_LANGUAGESTTS_DEFAULT_LANGUAGETTS_MODEL_IDc                   @   s   e Zd ZU dZedddZeed< edddZeed< edddZ	eed	< ed
ddZ
ee ed< eede de ddZee ed< G dd dZd
S )ResponseIQRequestuf  
    Request payload for the /response_iq_data endpoint.

    Fields
    ------
    question          : The interview / assessment question.
    predefinedAnswer  : The ideal / expected answer.
    userAnswer        : The candidate's actual text answer.
    userVoice         : Optional — URL or Base64-encoded audio of the candidate's voice.
    language          : Language key controlling the script and output language.
                        Supported values: english, hindi, marathi, tamil,
                        telugu, kannada, punjabi.
                        Defaults to 'english' when omitted.
    .z$The interview / assessment question.descriptionquestionzThe ideal / expected answer.predefinedAnswerzThe candidate's actual answer.
userAnswerNz-URL or Base64 audio of the candidate's voice.	userVoicez$Language of the content. Supported: . Defaults to ''.defaultr   languagec                   @      e Zd ZdZdS )zResponseIQRequest.ConfigignoreN__name__
__module____qualname__extra r)   r)   H/var/www/eduai.edurigo.com/responseiq/production/response_iq_fast_api.pyConfigY       r+   )r%   r&   r'   __doc__r   r   str__annotations__r   r   r   r   r   r   r!   r+   r)   r)   r)   r*   r   <   s   
 	r   c                   @   s   e Zd ZU dZedddZeed< edddZe	ed< edddZ
e	ed	< ed
ddZee	 ed< edddZee	 ed< ed
ddZee	 ed< d
S )ResponseIQResponseu  
    Structured analysis result returned by /response_iq_data.

    Fields
    ------
    matchScore        : Semantic similarity score 0–100.
    comparison        : Rationale for the score (in requested language).
    behavioralAnalysis: Communication style insights (in requested language).
    tonalAnalysis     : Voice delivery or text-tone analysis (in requested language).
    visuals           : Exactly 3 vibe keywords (in requested language).
    .u   Semantic match score (0–100).r   
matchScorez*Score rationale in the requested language.
comparisonzCommunication style insights.behavioralAnalysisNz%Voice delivery or text-tone analysis.tonalAnalysisz*3 vibe keywords in the requested language.visualszGWhisper transcription of the user's voice (when userVoice is provided).voiceTranscription)r%   r&   r'   r-   r   r1   intr/   r2   r.   r3   r4   r   r5   r   r6   r)   r)   r)   r*   r0   ]   s   
 r0   c                   @   J   e Zd ZU edddZeed< edddZeed< edddZeed< d	S )
SupportedLanguageItem.-Language key to pass in the 'language' field.r   keyHuman-readable language name.display_namez Language and script description.script_nameN)	r%   r&   r'   r   r;   r.   r/   r=   r>   r)   r)   r)   r*   r9   r      
 r9   c                   @   s"   e Zd ZU ee ed< eed< dS )SupportedLanguagesResponsesupported_languagesdefault_languageN)r%   r&   r'   r   r9   r/   r.   r)   r)   r)   r*   r@   x   s   
 r@   c                   @   s\   e Zd ZU dZeddddZeed< eede	 de d	d
Z
ee ed< G dd dZdS )ResponseIQTTSRequestuj  
    Request payload for the /response_iq_tts endpoint.

    Fields
    ──────
    predefinedAnswer : The text to be converted to speech.
                       Typically the ideal/model answer for a question.

    language         : Language key that controls the voice, accent, and
                       script used during synthesis.
                       Supported values: english, hinglish, hindi, marathi,
                       punjabi, tamil, telugu, kannada, gujarati, bengali,
                       odia, assamese, maithili, urdu.
                       Defaults to 'english' when omitted.
    .z#The text to synthesise into speech.   )r   
min_lengthr   z$Target language for TTS. Supported: r   r   r   r!   c                   @   r"   )zResponseIQTTSRequest.Configr#   Nr$   r)   r)   r)   r*   r+      r,   r+   N)r%   r&   r'   r-   r   r   r.   r/   r   r   r!   r   r+   r)   r)   r)   r*   rC      s    
 	rC   c                   @   sv   e Zd ZU dZedddZeed< edddZeed< edddZ	e
ed	< edd
dZeed< edddZe
ed< dS )ResponseIQTTSResponseu  
    TTS result returned by /response_iq_tts.

    Fields
    ──────
    audio_tts    : Base64-encoded WAV audio string. Decode and play directly.
    language     : Normalised language key used for synthesis.
    sample_rate  : Sample rate of the returned audio (Hz).
    duration_sec : Duration of the synthesised audio in seconds.
    char_count   : Number of characters that were synthesised.
    .z3Base64-encoded WAV audio of the synthesised speech.r   	audio_ttsz Language key used for synthesis.r!   zAudio sample rate in Hz.sample_ratez)Duration of synthesised audio in seconds.duration_secz!Number of characters synthesised.
char_countN)r%   r&   r'   r-   r   rG   r.   r/   r!   rH   r7   rI   floatrJ   r)   r)   r)   r*   rF      s   
 rF   c                   @   r8   )
TTSSupportedLanguageItem.r:   r   r;   r<   r=   z'BCP-47 language tag used for synthesis.	bcp47_tagN)	r%   r&   r'   r   r;   r.   r/   r=   rM   r)   r)   r)   r*   rL      r?   rL   c                   @   s*   e Zd ZU ee ed< eed< eed< dS )TTSSupportedLanguagesResponserA   rB   model_idN)r%   r&   r'   r   rL   r/   r.   r)   r)   r)   r*   rN      s   
 rN   zResponse IQ APIu   ## Response IQ — Intelligent Answer Analysis & Text-to-Speech

### Analysis (`/response_iq_data`)
Analyses a candidate's interview answer against an ideal answer using the **z{** model via Ollama. Supports multi-language content and optional voice tonal analysis.

**Supported analysis languages:** z, zw

---

### Text-to-Speech (`/response_iq_tts`)
Converts text to natural human-like speech using **Indic Parler-TTS** (`zd`) running on the local GPU server. Returns Base64-encoded WAV audio.

**Supported TTS languages:** z3.0.0)titler   version*T)allow_originsallow_credentialsallow_methodsallow_headersz/response_iq_datazAnalyse a candidate's responsezAccepts a question, the ideal answer, and the candidate's answer. Optionally accepts a voice recording (URL or Base64). The **`language`** field controls which language the analysis is written in. Supported values: `u   `. Returns a structured evaluation with match score, behavioural analysis, tonal analysis, and 3 vibe keywords — all in the requested language.r   zSuccessful analysis result.z"Unsupported language key supplied.zLLM or audio-processing error.)   i  i  Analysis)response_modelsummaryr   	responsestagspayloadc              
      s   | j pt  }|tvrttjd| dt ddt	
d| d| jr'dnd d	| jd
d  d t| j| j| j| j|d}d|v rYt	d|d   ttj|d d|S )z
    1. Validates the language key.
    2. Optionally extracts acoustic features from the voice recording.
    3. Calls the LLM to produce a language-aware analysis.
    4. Returns the structured result.
    Unsupported language 'z'. Valid values are: .status_codedetailz"POST /response_iq_data | language=z | has_voice=yesnoz | question='N2   z...')r   predefined_answeruser_answeruser_voice_urlr!   errorzAnalysis failed: )r!   r   striplowerr   r   r   HTTP_400_BAD_REQUESTr   loggerinfor   r   r   r   r   ri   HTTP_500_INTERNAL_SERVER_ERROR)r]   requested_languageanalysis_resultr)   r)   r*   response_iq_data_endpoint   s<   	rr   z/response_iq_ttsz(Convert predefined answer text to speecha  Synthesises the `predefinedAnswer` text into natural, human-like speech using **Indic Parler-TTS** (`ai4bharat/indic-parler-tts`) running on the local GPU server.

The `language` field selects the speaker's accent, voice profile, and script-aware phoneme rendering. Supported values: `a  `.

The response contains a **Base64-encoded WAV** string in `audio_tts`. Decode it on the client and play directly, or save as a `.wav` file.

**Example client usage (PHP):**
```php
$audioData = base64_decode($response['audio_tts']);
file_put_contents('answer.wav', $audioData);
```

**Example client usage (JavaScript):**
```js
const blob = new Blob(
  [Uint8Array.from(atob(response.audio_tts), c => c.charCodeAt(0))],
  { type: 'audio/wav' }
);
const url = URL.createObjectURL(blob);
new Audio(url).play();
```z'Base64 WAV audio returned successfully.z0Unsupported language key or empty text supplied.z*TTS model error or GPU processing failure.zText-to-Speechc                    s  | j pt  }|tvrttjd| dt dd| j	p d }|s,ttjddt
d| dt| d	|d
d  t|dkrEdnd d t||d}d|v rht
d|d   ttj|d dt
d| d|d dt|dd  |S )a(  
    1. Validates the language key against TTS_LANGUAGE_CONFIG.
    2. Normalises and chunks the predefinedAnswer text.
    3. Synthesises each chunk via Indic Parler-TTS (GPU inference).
    4. Concatenates chunks, resamples, encodes as Base64 WAV.
    5. Returns the structured TTS result.
    r^   z' for TTS. Valid values are: r_   r`    z%'predefinedAnswer' must not be empty.z!POST /response_iq_tts | language=z	 | chars=z | preview='N<   z...')textr!   ri   zTTS failed: zTTS response ready | language=z | duration=rI   zs | base64_len=rG   )r!   r   rj   rk   r   r   r   rl   r   r   rm   rn   lenr   ri   ro   get)r]   rp   rv   
tts_resultr)   r)   r*   response_iq_tts_endpoint-  sT   -	
rz   z/supported_languagesz!List supported analysis languageszReturns all language keys accepted by the `language` field of `/response_iq_data`, along with their display names and script descriptions. Use this to populate language selector dropdowns in your frontend.Metadata)rY   rZ   r   r\   c                      s   dd t  D tdS )zQReturns every supported analysis language key along with human-readable metadata.c                 S   $   g | ]\}}||d  |d dqS )r=   r>   )r;   r=   r>   r)   .0r;   cfgr)   r)   r*   
<listcomp>      z0supported_languages_endpoint.<locals>.<listcomp>)rA   rB   )r   itemsr   r)   r)   r)   r*   supported_languages_endpoint  s   r   z/tts_supported_languageszList supported TTS languageszReturns all language keys accepted by the `language` field of `/response_iq_tts`, along with display names and BCP-47 tags. Use this to populate language selector dropdowns in your frontend.c                      s   dd t  D ttdS )zLReturns every supported TTS language key along with human-readable metadata.c                 S   r|   )r=   bcp47_lang_tag)r;   r=   rM   r)   r}   r)   r)   r*   r     r   z4tts_supported_languages_endpoint.<locals>.<listcomp>)rA   rB   rO   )r   r   r   r   r)   r)   r)   r*    tts_supported_languages_endpoint  s   r   z/healthzHealth checkz>Returns API status, active LLM model name, and TTS model name.)rZ   r   r\   c                      s   dt tttdS )zSimple liveness probe.ok)r   	llm_model	tts_modelrA   tts_supported_languages)r   r   r   r   r)   r)   r)   r*   health_check  s   	r   )7osloggingtypingr   r   basicConfigINFO	getLoggerrm   fastapir   r   r   fastapi.middleware.corsr	   pydanticr
   r   response_iq_analysisr   r   r   r   r   ImportErrorsyspathappenddirnameabspath__file__response_iq_ttsr   r   r   r   r   r   r0   r9   r@   rC   rF   rL   rN   joinappadd_middlewarepostrr   rz   rx   r   r   r   r)   r)   r)   r*   <module>   s    
    !	#
	2#=

