
    qi	T                        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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& 	 ddl'm(Z) ddl*m+Z+ e G d de             Z0 G d de      Z1y# e,$ r7Z- ej\                  de-         ej\                  d        e/de-       dZ-[-ww xY w)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_warn_deprecated_param)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                       e Zd ZdZy)AWSTranscribeSTTSettingsz%Settings for AWSTranscribeSTTService.N)__name__
__module____qualname____doc__     J/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/services/aws/stt.pyr   r   0   s    /r#   r   c                       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ZdefdZde	de	fdZdedee	ef   f fdZdef fdZdef fdZdef fdZdedeedf   fdZ fdZ fdZ d Z!d Z"d
ede	dz  fdZ#e$	 d$de	d ed
ee	   fd!       Z%d" Z&d# Z' xZ(S )%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                   t        d| j                  t        j                              }
|'t	        dt         d       | j                  |      |
_        ||
j                  |       t        |    d|||
d|	 d| _	        d| _
        d| _        d| _        |xs t        j                  d      |xs t        j                  d	      |xs t        j                  d
      |xs t        j                  dd      d| _        d| _        y)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=AWSTranscribeSTTSettings(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"   )r   language_to_service_languager   ENr   r-   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__s              r$   r=   z AWSTranscribeSTTService.__init__B   s   F 466x{{C
 ":/GT(,(I(I((S%
 ))(3 	
#-%	
 		
  *#$ #( .3+ "3!Tbii@S6T%,%R		:Q0R!2!Tbii@S6TD		, D	
 "r#   returnc                      y)zCheck if this service can generate processing metrics.

        Returns:
            True, as AWS Transcribe STT supports metrics generation.
        Tr"   rF   s    r$   can_generate_metricsz,AWSTranscribeSTTService.can_generate_metrics   s     r#   encodingc                 .    ddi}|j                  ||      S )zConvert internal encoding format to AWS Transcribe format.

        Args:
            encoding: Internal encoding format string.

        Returns:
            AWS Transcribe compatible encoding format.
        r2   pcm)get)rF   rN   encoding_maps      r$   get_service_encodingz,AWSTranscribeSTTService.get_service_encoding   s%     
 (33r#   deltac                    K   t         |   |       d{   }|r<| j                  r0| j                          d{    | j	                          d{    |S 7 D7  7 
w)z9Apply a settings delta and reconnect if anything changed.N)r<   _update_settings
_websocket_disconnect_connect)rF   rT   changedrI   s      r$   rV   z(AWSTranscribeSTTService._update_settings   sW     077t""$$$--/!! 8 %!s1   A!A%A!AA!AA!A!A!framec                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zInitialize the connection when the service starts.

        Args:
            frame: Start frame signaling service initialization.
        N)r<   startrY   rF   r[   rI   s     r$   r]   zAWSTranscribeSTTService.start   s3      gmE"""mmo 	#   848688c                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zStop the service and disconnect from AWS Transcribe.

        Args:
            frame: End frame signaling service shutdown.
        N)r<   stoprX   r^   s     r$   ra   zAWSTranscribeSTTService.stop   s6      gl5!!!    	" r_   c                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zCancel the service and disconnect from AWS Transcribe.

        Args:
            frame: Cancel frame signaling service cancellation.
        N)r<   cancelrX   r^   s     r$   rc   zAWSTranscribeSTTService.cancel   s6      gnU###    	$ r_   audioc                `  K   | j                   rm| j                   j                  t        j                  u rG	 t	        |      }| j                   j                  |       d{    | j                          d{    d y7 "7 # t        $ r}t        d|        Y d}~*d}~ww xY ww)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)	rW   stater   OPENr   sendstart_processing_metrics	Exceptionr
   )rF   rd   event_messagees       r$   run_sttzAWSTranscribeSTTService.run_stt   s      ??t44

B	D 3E : oo**=99933555 
 :5 D )>qc'BCCCDsR   3B.)B B B 7B8B <B.B B 	B+B&!B.&B++B.c                   K   t         |           d{    | j                          d{    | j                  r=| j                  s0| j                  | j                  | j                              | _        yyy7 f7 Pw)zrConnect to the AWS Transcribe service.

        Establishes websocket connection and starts receive task.
        N)r<   rY   _connect_websocketrW   rE   create_task_receive_task_handler_report_error)rF   rI   s    r$   rY   z AWSTranscribeSTTService._connect   so     
 g   %%'''??4#5#5!%!1!1$2L2LTM_M_2`!aD $6?	 	!'s    B A<B A>AB >B c                 ,  K   t         |           d{    | j                  r*| j                  | j                         d{    d| _        | j                  rb| j                  j
                  t        j                  u r<	 ddd}| j                  j                  t        j                  |             d{    | j                          d{    y7 7 7 !# t        $ r)}| j                  d| |       d{  7   Y d}~Ld}~ww xY w7 @w)zeDisconnect from the AWS Transcribe service.

        Sends end-stream message and cleans up.
        Neventend)zmessage-typeru   zError sending end-stream: 	error_msg	exception)r<   rX   rE   cancel_taskrW   rg   r   rh   ri   jsondumpsrk   
push_error_disconnect_websocket)rF   
end_streamrm   rI   s      r$   rX   z#AWSTranscribeSTTService._disconnect   s     
 g!###""4#5#5666!%D ??t44

B_.5F
oo**4::j+ABBB ((*** 	$ 7 C _oo2LQC0P\]o^^^_ 	+su   DC.DC=D6C 9C:C >DDDDC 	D&D
?D D
D
DDc                 H  K   	 | j                   r'| j                   j                  t        j                  u ryt	        j
                  d       | j                  j                  }|st        d|       | j                  }|dvrt	        j                  d| d       d}dj                  t        j                  t        j                  t        j                   z   t        j"                  z   d	
            }d|ddd}t%        | j&                  d   | j&                  d   | j&                  d   | j&                  d   d|| j)                  | j*                        || j,                  dd| j.                  | j0                  
      }t	        j
                  |  d|dd  d       t3        ||dgddd       d{   | _         | j5                  d       d{    t	        j6                  |  d       y7 ;7 # t8        $ r%}| j;                  d| |       d{  7    d}~ww xY 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.r       )kzhttps://localhost13z
keep-alive)OriginzSec-WebSocket-KeyzSec-WebSocket-Version
Connectionr+   r)   r8   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: rw   )rW   rg   r   rh   r   debugr'   r-   
ValueErrorr,   warningjoinrandomchoicesstringascii_uppercaseascii_lowercasedigitsr   rD   rS   r>   r?   r@   rA   websocket_connect_call_event_handlerinfork   r}   )rF   r   connect_sample_ratewebsocket_keyr   presigned_urlrm   s          r$   rp   z*AWSTranscribeSTTService._connect_websocket   s:    H	4??#8#8EJJ#FLLAB NN33M  #9-!IJJ #'"2"2"-7'':&;;KM ',# GG**V-C-CCfmmSWYM .%2)-*	" .((2"&"3"34G"H"&"3"34K"L%)%6%67J%K
 ,#88((  0#'#;#;59*0#'#;#;.2.Q.Q!M& LLD6!D]SWTWEXDYY\]^ %6#5$X"! % DO **>:::KK4& IJK ; 	//A!EQR "    		sc   H"2G1 H"E:G1 1G-2G1 G/G1 ,H"-G1 /G1 1	H:HHHHH"c                   K   	 | j                   r7t        j                  d       | j                   j                          d{    d| _         | j                  d       d{    y7 %# t        $ r)}| j                  d| |       d{  7   Y d}~Pd}~ww xY w7 <# d| _         | j                  d       d{  7   w xY ww)z1Close the websocket connection to AWS Transcribe.z+Disconnecting from AWS Transcribe WebSocketNzError closing websocket: rw   on_disconnected)rW   r   r   closerk   r}   r   )rF   rm   s     r$   r~   z-AWSTranscribeSTTService._disconnect_websocketJ  s     	>JKoo++--- #DO**+<=== . 	Z//.Gs,KWX/YYY	Z > #DO**+<===sv   C>A* A(A* C"B#C(A* *	B3BBBB! BB! C!C=C >CCc                    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         j0                  dt         j2                  dt         j4                  dt         j6                  dt         j8                  dt         j:                  dt         j<                  dt         j>                  dt         j@                  dt         jB                  dt         jD                  di t         jF                  dt         jH                  dt         jJ                  dt         jL                  dt         jN                  dt         jP                  dt         jR                  dt         jT                  dt         jV                  dt         jX                  dt         jZ                  dt         j\                  dt         j^                  dt         j`                  dt         jb                  dt         jd                  dt         jf                  di t         jh                  dt         jj                  d t         jl                  d t         jn                  d!t         jp                  d!t         jr                  d"t         jt                  d"t         jv                  d#t         jx                  d#t         jz                  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                  d0t         j                  d0t         j                  d1t         j                  d1t         j                  d1t         j                  d2t         j                  d2t         j                  d3t         j                  d3t         j                  d4t         j                  d4t         j                  d5t         j                  d5i}t        ||d67      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_NLr:   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   )rF   r-   LANGUAGE_MAPs      r$   r9   z4AWSTranscribeSTTService.language_to_service_languageV  s   J
KKJ
 NNGJ

 KKJ
 NNGJ
 NNGJ
 KKJ
 NNGJ
 KKJ
 NNGJ
 KKJ
  NNG!J
" NNG#J
$ NNG%J
& LL''J
* KK+J
, NNG-J
0 KK1J
2 NNG3J
6 KK7J
8 NNG9J
< KK=J
> NNG?J
B KKCJ
D NNGEJ
F NNGGJ
H NNGIJ
J NNGKJ
L NNGMJ
P NNGQJ
R NNGSJ
V KKWJ
X NNGYJ
\ KK]J
^ NNG_J
b KKcJ
d NNGeJ
f NNGgJ
j KKkJ
l NNGmJ
p KKqJ
r NNGsJ
v KKwJ
x NNGyJ
z NNG{J
~ KKJ
@ NNGAJ
D KKEJ
F NNGGJ
J KKKJ
L NNGMJ
P KKQJ
R NNGSJ
V KKWJ
X NNGYJ
\ KK]J
^ NNG_J
b KKcJ
d NNGeJ
h KKiJ
j NNGkJ
n KKoJ
p NNGqJ
t KKuJ
v NNGwJ
x KKyJ
| KK}J
~ NNGJ
B KKCJ
D NNGEJ
F NNGGJ
J KKKJ
L NNGMJ
P KKQJ
R NNGSJ
V KKWJ
X NNGYJ
\ KK]J
^ NNG_J
b KKcJ
d NNGeJ
h KKiJ
j NNGkJ
l NNGmJ
p KKqJ
r NNGsJ
v KKLL'OOWKKNNGKKNNGKKNNGKKNNGSJ
X  ,eLLr#   
transcriptis_finalc                    K   y wNr"   )rF   r  r  r-   s       r$   _handle_transcriptionz-AWSTranscribeSTTService._handle_transcription  s      	s   c                 H    | 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)rW   rk   rL   s    r$   _get_websocketz&AWSTranscribeSTTService._get_websocket  s!     ????"122r#   c           
        K   | j                         2 3 d{   }	 t        |      \  }}|j                  d      dk(  rO|j                  di       j                  dg       }|r|d   }|j                  dg       }|r|d   j                  dd      }|j                  d	d
       }|r]|r| j                  t	        || j
                  t               | j                  j                  |             d{    | j                  ||| j                  j                         d{    | j                          d{    n| j                  t        || j
                  t               | j                  j                  |             d{    nx|j                  d      dk(  r0|j                  dd      }	| j                  d|	        d{    n4t        j                  |  d|        t        j                  |  d|        7 7 7 7 7 7 G# t        $ r#}
t        j                   d|
        Y d}
~
+d}
~
ww xY w6 yw)zxReceive and process websocket messages.

        Continuously processes messages from the websocket connection.
        Nz:message-typeru   
TranscriptResultsr   Alternativesr   	IsPartialT)resultry   MessagezUnknown errorzAWS Transcribe error: )rx   z Other message type received: z
 Payload: zError processing message: )r  r   rQ   
push_framer   _user_idr   r'   r-   r  stop_processing_metricsr   r}   r   r   rk   r   )rF   responseheaderspayloadresultsr  alternativesr  r  rx   rm   s              r$   _receive_messagesz)AWSTranscribeSTTService._receive_messages  s7    
 #113 0	A 0	A(/A#/#9 ;;/7:%kk,;??	2NG!('-zz."'E')5a)<)<\2)NJ+1::k4+H'HH)#+*.//(:,6,0MM,<,>,0NN,C,C39)*+& %& %& +/*D*D(2(0(,(?(?+& %& %&
 +/*F*F*H$H$H*.//(A,6,0MM,<,>,0NN,C,C39)*+& %& %& [[1[@ 'I GI//6LYK4X/YYYLLD6)Gy!QRLLD6G9!=>]0	A %&%&
 %I%& Z  A!;A3?@@A_ 4s   IIH	IICH4H5.H#H$H;H<AH	H
AHH9HI	IHHHHH	I H>8I>IIr  ))r   r   r    r!   r   Settings__annotations__r   r   strintr   floatr=   boolrM   rS   r   dictr   rV   r   r]   r	   ra   r   rc   bytesr   r   rn   rY   rX   rp   r~   r9   r   r  r  r'  __classcell__)rI   s   @r$   r&   r&   7   s    (H''
 "&+/+/ $%)'+7;,CG" #G" $C=	G"
 $C=G" G" c]G" 8$G" 34G" #5/G"Rd 4S 4S 4K DcN  ! !!+ !5 ^E4K-H .
b+*JX
>YMX YM#* YMv IM)-9A# 
35Ar#   r&   )2r!   r{   rB   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   r   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   ModuleNotFoundErrorrm   rf   rk   r   r&   r"   r#   r$   <module>r?     s     	   ! 0 0    \ [ I @ < F / ?,F) 	{ 	 	BA1 BA  ,FLL;qc"#FLL[\
&qc*
++,s   .B C2CC