o
    iS                  
   @   sZ  d Z ddlZddlZddlZddlZddlmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZmZmZmZmZmZmZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlm Z m!Z! ddl"m#Z# ddl$m%Z% zddl&m'Z( ddl)m*Z* W n  e+y Z, ze-de,  e-d e.de, dZ,[,ww eG dd deZ/G dd deZ0dS )zAWS Transcribe Speech-to-Text service implementation.

This module provides a WebSocket-based connection to AWS Transcribe for real-time
speech-to-text transcription with support for multiple languages and audio formats.
    N)	dataclass)AnyAsyncGeneratorOptional)logger)CancelFrameEndFrame
ErrorFrameFrameInterimTranscriptionFrame
StartFrameTranscriptionFrame)build_event_messagedecode_eventget_presigned_url)STTSettings)AWS_TRANSCRIBE_TTFS_P99)WebsocketSTTService)Languageresolve_language)time_now_iso8601)
traced_stt)connect)StatezException: zHIn order to use AWS services, you need to `pip install pipecat-ai[aws]`.zMissing module: c                   @   s   e Zd ZdZdS )AWSTranscribeSTTSettingsz%Settings for AWSTranscribeSTTService.N)__name__
__module____qualname____doc__ r   r   L/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/services/aws/stt.pyr   0   s    r   c                       s  e Zd ZU dZeZeed< dddddddeddee	 dee	 dee	 dee	 d	ee
 d
ee dee dee f fddZdefddZde	de	fddZdedee	ef f fddZdef fddZdef fddZdef fddZdedeedf fd d!Z fd"d#Z fd$d%Z d&d' Z!d(d) Z"d
ede	dB fd*d+Z#e$	d4d,e	d-ed
ee	 fd.d/Z%d0d1 Z&d2d3 Z'  Z(S )5AWSTranscribeSTTServicea
  AWS Transcribe Speech-to-Text service using WebSocket streaming.

    Provides real-time speech transcription using AWS Transcribe's streaming API.
    Supports multiple languages, configurable sample rates, and both interim and
    final transcription results.
    	_settingsN)api_keyaws_access_key_idaws_session_tokenregionsample_ratelanguagesettingsttfs_p99_latencyr#   r$   r%   r&   r'   r(   r)   r*   c                   s   | j dtjd}
|dur| dd ||
_|dur|
| t jd|||
d|	 d| _d| _	d| _
d| _|p=td|pCtd	|pItd
|pPtddd| _d| _dS )a  Initialize the AWS Transcribe STT service.

        Args:
            api_key: AWS secret access key. If None, uses AWS_SECRET_ACCESS_KEY environment variable.
            aws_access_key_id: AWS access key ID. If None, uses AWS_ACCESS_KEY_ID environment variable.
            aws_session_token: AWS session token for temporary credentials. If None, uses AWS_SESSION_TOKEN environment variable.
            region: AWS region for the service.
            sample_rate: Audio sample rate in Hz. If None, uses the pipeline sample rate.
                AWS Transcribe only supports 8000 or 16000 Hz; other values are
                clamped to 16000 Hz at connect time.
            language: Language for transcription.

                .. deprecated:: 0.0.105
                    Use ``settings=AWSTranscribeSTTService.Settings(language=...)`` instead.

            settings: Runtime-updatable settings. When provided alongside deprecated
                parameters, ``settings`` values take precedence.
            ttfs_p99_latency: P99 latency from speech end to final transcript in seconds.
                Override for your deployment. See https://github.com/pipecat-ai/stt-benchmark
            **kwargs: Additional arguments passed to parent STTService class.
        N)modelr(   r(   )r'   r*   r)   linear16   FAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN
AWS_REGIONz	us-east-1)r$   aws_secret_access_keyr%   r&   r   )Settingsr   EN"_warn_init_param_moved_to_settingsr(   apply_updatesuper__init___media_encoding_number_of_channels_show_speaker_label_enable_channel_identificationosgetenv_credentials_receive_task)selfr#   r$   r%   r&   r'   r(   r)   r*   kwargsdefault_settings	__class__r   r    r8   B   s4   #

z AWSTranscribeSTTService.__init__returnc                 C   s   dS )zCheck if this service can generate processing metrics.

        Returns:
            True, as AWS Transcribe STT supports metrics generation.
        Tr   rA   r   r   r    can_generate_metrics   s   z,AWSTranscribeSTTService.can_generate_metricsencodingc                 C   s   ddi}| ||S )zConvert internal encoding format to AWS Transcribe format.

        Args:
            encoding: Internal encoding format string.

        Returns:
            AWS Transcribe compatible encoding format.
        r,   pcm)get)rA   rI   encoding_mapr   r   r    get_service_encoding   s   
z,AWSTranscribeSTTService.get_service_encodingdeltac                    s>   t  |I dH }|r| jr|  I dH  |  I dH  |S )z9Apply a settings delta and reconnect if anything changed.N)r7   _update_settings
_websocket_disconnect_connect)rA   rN   changedrD   r   r    rO      s   
z(AWSTranscribeSTTService._update_settingsframec                    &   t  |I dH  |  I dH  dS )zInitialize the connection when the service starts.

        Args:
            frame: Start frame signaling service initialization.
        N)r7   startrR   rA   rT   rD   r   r    rV         zAWSTranscribeSTTService.startc                    rU   )zStop the service and disconnect from AWS Transcribe.

        Args:
            frame: End frame signaling service shutdown.
        N)r7   stoprQ   rW   rD   r   r    rY      rX   zAWSTranscribeSTTService.stopc                    rU   )zCancel the service and disconnect from AWS Transcribe.

        Args:
            frame: Cancel frame signaling service cancellation.
        N)r7   cancelrQ   rW   rD   r   r    rZ      rX   zAWSTranscribeSTTService.cancelaudioc              
   C  s   | j r=| j jtju r=zt|}| j |I dH  |  I dH  W n ty< } ztd| dV  W Y d}~nd}~ww dV  dS )zProcess audio data and send to AWS Transcribe.

        Args:
            audio: Raw audio bytes to transcribe.

        Yields:
            ErrorFrame: If processing fails or connection issues occur.
        NzError sending audio: )error)	rP   stater   OPENr   sendstart_processing_metrics	Exceptionr	   )rA   r[   event_messageer   r   r    run_stt   s   	
zAWSTranscribeSTTService.run_sttc                    sL   t   I dH  |  I dH  | jr"| js$| | | j| _dS dS dS )zrConnect to the AWS Transcribe service.

        Establishes websocket connection and starts receive task.
        N)r7   rR   _connect_websocketrP   r@   create_task_receive_task_handler_report_errorrG   rD   r   r    rR      s   z AWSTranscribeSTTService._connectc              
      s   t   I dH  | jr| | jI dH  d| _| jrU| jjtju rUzddd}| jt	
|I dH  W n tyT } z| jd| |dI dH  W Y d}~nd}~ww |  I dH  dS )zeDisconnect from the AWS Transcribe service.

        Sends end-stream message and cleans up.
        Neventend)zmessage-typeri   zError sending end-stream: 	error_msg	exception)r7   rQ   r@   cancel_taskrP   r]   r   r^   r_   jsondumpsra   
push_error_disconnect_websocket)rA   
end_streamrc   rD   r   r    rQ      s   
&z#AWSTranscribeSTTService._disconnectc                    sv  z| j r| j jtju rW dS td | jj}|s!td| | j	}|dvr3t
d| d d}dtjtjtj tj d	d
}d|ddd}t| jd | jd | jd | jd d|| | j|| jdd| j| jd
}t|  d|dd  d t||dgddddI dH | _ | dI dH  t|  d W dS  ty } z| jd| |dI dH   d}~ww ) z5Establish the websocket connection to AWS Transcribe.Nz&Connecting to AWS Transcribe WebSocketzUnsupported language: )i@  >  zOAWS Transcribe only supports 8000 Hz or 16000 Hz sample rates. Converting from z Hz to 16000 Hz.rt       )kzhttps://localhost13z
keep-alive)OriginzSec-WebSocket-KeyzSec-WebSocket-Version
Connectionr&   r$   r2   r%   )
access_key
secret_keysession_tokenThigh)
r&   credentialslanguage_codemedia_encodingr'   number_of_channels$enable_partial_results_stabilizationpartial_results_stabilityshow_speaker_labelenable_channel_identificationz# Connecting to WebSocket with URL: d   z...mqtt)additional_headerssubprotocolsping_intervalping_timeoutcompressionon_connectedz) Successfully connected to AWS Transcribez%Unable to connect to AWS Transcribe: rk   )rP   r]   r   r^   r   debugr"   r(   
ValueErrorr'   warningjoinrandomchoicesstringascii_uppercaseascii_lowercasedigitsr   r?   rM   r9   r:   r;   r<   websocket_connect_call_event_handlerinfora   rq   )rA   r   connect_sample_ratewebsocket_keyr   presigned_urlrc   r   r   r    re      sz   
	
z*AWSTranscribeSTTService._connect_websocketc              
      s   zNz| j rtd | j  I dH  W n ty3 } z| jd| |dI dH  W Y d}~nd}~ww W d| _ | dI dH  dS W d| _ | dI dH  dS d| _ | dI dH  w )z1Close the websocket connection to AWS Transcribe.z+Disconnecting from AWS Transcribe WebSocketNzError closing websocket: rk   on_disconnected)rP   r   r   closera   rq   r   )rA   rc   r   r   r    rr   J  s$   
&z-AWSTranscribeSTTService._disconnect_websocketc                 C   s  i t jdt jdt jdt jdt jdt jdt jdt jdt j	dt j
dt jdt jdt jdt jdt jd	t jd	t jd
i t jd
t jdt jdt jdt jdt jdt jdt jdt jdt jdt jdt jdt jdt jdt j dt j!dt j"di t j#dt j$dt j%dt j&dt j'dt j(dt j)dt j*dt j+dt j,dt j-dt j.dt j/dt j0dt j1dt j2dt j3di t j4dt j5d t j6d t j7d!t j8d!t j9d"t j:d"t j;d#t j<d#t j=d$t j>d$t j?d%t j@d%t jAd%t jBd&t jCd&t jDd'i t jEd't jFd(t jGd)t jHd)t jId*t jJd*t jKd+t jLd+t jMd,t jNd,t jOd-t jPd-t jQd.t jRd.t jSd/t jTd0t jUd0t jVd1t jWd1t jXd1t jYd2t jZd2t j[d3t j\d3t j]d4t j^d4t j_d5t j`d5i}ta||d6d7S )8a  Convert internal language enum to AWS Transcribe language code.

        Source:
        https://docs.aws.amazon.com/transcribe/latest/dg/supported-languages.html
        All language codes that support streaming are included.

        Args:
            language: Internal language enumeration value.

        Returns:
            AWS Transcribe compatible language code, or None if unsupported.
        zaf-ZAzar-SAzar-AEzeu-ESzca-ESzzh-CNzzh-TWzzh-HKzhr-HRzcs-CZzda-DKznl-NLzen-USzen-AUzen-GBzen-INzen-IEzen-NZzen-ZAzfa-IRzfi-FIzfr-FRzfr-CAzgl-ESzka-GEzde-DEzde-CHzel-GRzhe-ILzhi-INzid-IDzit-ITzja-JPzko-KRzlv-LVzms-MYzno-NOzpl-PLzpt-PTzpt-BRzro-ROzru-RUzsr-RSzsk-SKzso-SOzes-ESzes-USzsv-SEztl-PHzth-THzuk-UAzvi-VNzzu-ZAF)use_base_code)br   AFAF_ZAARAR_AEAR_SAEUEU_ESCACA_ESZHZH_CNZH_TWZH_HKYUEHRHR_HRCSCS_CZDADA_DKNLNL_NLr4   EN_AUEN_GBEN_INEN_IEEN_NZEN_ZAEN_USFAFA_IRFIFI_FIFRFR_FRFR_CAGLGL_ESKAKA_GEDEDE_DEDE_CHELEL_GRHEHE_ILHIHI_INIDID_IDITIT_ITJAJA_JPKOKO_KRLVLV_LVMSMS_MYNBNB_NONOPLPL_PLPTPT_PTPT_BRRORO_RORURU_RUSRSR_RSSKSK_SKSOSO_SOESES_ESES_USSVSV_SETLFILFIL_PHTHTH_THUKUK_UAVIVI_VNZUZU_ZAr   )rA   r(   LANGUAGE_MAPr   r   r    language_to_service_languageV  st  	
!"#$%&()+,./1235689;<=?@BCEFHIKLNOQRTUWXZ[\^_abcefhiklnoqrtuvxy{  z4AWSTranscribeSTTService.language_to_service_language
transcriptis_finalc                    s   d S Nr   )rA   r  r  r(   r   r   r    _handle_transcription  s   z-AWSTranscribeSTTService._handle_transcriptionc                 C   s   | j r| j S td)zGet the current WebSocket connection.

        Returns:
            The WebSocket connection.

        Raises:
            Exception: If WebSocket is not connected.
        zWebsocket not connected)rP   ra   rG   r   r   r    _get_websocket  s   	z&AWSTranscribeSTTService._get_websocketc                    s  |   2 z3 dH W }zt|\}}|ddkr|di dg }|r~|d }|dg }|r~|d dd}|d	d
 }|r~|rk| t|| jt | jj|dI dH  | 	||| jjI dH  | 
 I dH  nB| t|| jt | jj|dI dH  n.|ddkr|dd}	| jd|	 dI dH  nt|  d|  t|  d|  W q ty }
 ztd|
  W Y d}
~
qd}
~
ww 6 dS )zxReceive and process websocket messages.

        Continuously processes messages from the websocket connection.
        Nz:message-typeri   
TranscriptResultsr   Alternativesru   	IsPartialT)resultrm   MessagezUnknown errorzAWS Transcribe error: )rl   z Other message type received: z
 Payload: zError processing message: )r  r   rK   
push_framer   _user_idr   r"   r(   r  stop_processing_metricsr   rq   r   r   ra   r   )rA   responseheaderspayloadresultsr  alternativesr  r  rl   rc   r   r   r    _receive_messages  sd   
	

	z)AWSTranscribeSTTService._receive_messagesr  ))r   r   r   r   r   r3   __annotations__r   r   strintr   floatr8   boolrH   rM   r   dictr   rO   r   rV   r   rY   r   rZ   bytesr   r
   rd   rR   rQ   re   rr   r  r   r  r  r  __classcell__r   r   rD   r    r!   7   sj   
 	
I
			L r!   )1r   ro   r=   r   r   dataclassesr   typingr   r   r   logurur   pipecat.frames.framesr   r   r	   r
   r   r   r   pipecat.services.aws.utilsr   r   r   pipecat.services.settingsr   pipecat.services.stt_latencyr   pipecat.services.stt_servicer   pipecat.transcriptions.languager   r   pipecat.utils.timer   (pipecat.utils.tracing.service_decoratorsr   websockets.asyncio.clientr   r   websockets.protocolr   ModuleNotFoundErrorrc   r\   ra   r   r!   r   r   r   r    <module>   s8   $	
