o
    iO6                     @   s   d Z ddlZddlZddlZddlZddlZddlZddlZddl	m
Z
mZ dddddddd	d	d
	dede
eee f dededededededee dee dededefddZG dd dZdededefddZd edefd!d"Zd#d$ ZdS )%zAWS Transcribe utility functions and classes for WebSocket streaming.

This module provides utilities for creating presigned URLs, building event messages,
and handling AWS event stream protocol for real-time transcription services.
    N)DictOptionalpcmi>     ThighF)	media_encodingsample_ratenumber_of_channels$enable_partial_results_stabilizationpartial_results_stabilityvocabulary_namevocabulary_filter_nameshow_speaker_labelenable_channel_identificationregioncredentialslanguage_coder   r   r	   r
   r   r   r   r   r   returnc                 C   s\   | d}| d}| d}|r|stdt|||| d}|j|||||	|
||||d
S )aX  Create a presigned URL for AWS Transcribe streaming.

    Args:
        region: AWS region for the service.
        credentials: Dictionary containing AWS credentials. Must include
            'access_key' and 'secret_key', with optional 'session_token'.
        language_code: Language code for transcription (e.g., "en-US").
        media_encoding: Audio encoding format. Defaults to "pcm".
        sample_rate: Audio sample rate in Hz. Defaults to 16000.
        number_of_channels: Number of audio channels. Defaults to 1.
        enable_partial_results_stabilization: Whether to enable partial result stabilization.
        partial_results_stability: Stability level for partial results.
        vocabulary_name: Custom vocabulary name to use.
        vocabulary_filter_name: Vocabulary filter name to apply.
        show_speaker_label: Whether to include speaker labels.
        enable_channel_identification: Whether to enable channel identification.

    Returns:
        Presigned WebSocket URL for AWS Transcribe streaming.

    Raises:
        ValueError: If required AWS credentials are missing.
    
access_key
secret_keysession_tokenzAWS credentials are required)r   r   r   r   )
r   r   r   r   r   r   r   r	   r
   r   )get
ValueErrorAWSTranscribePresignedURLget_request_url)r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   url_generator r   N/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/services/aws/utils.pyget_presigned_url   s(   
&

r   c                   @   sx   e Zd ZdZ	ddedededefddZ			
										ddededededededededededefddZdS )r   zGenerator for AWS Transcribe presigned WebSocket URLs.

    Handles AWS Signature Version 4 signing process to create authenticated
    WebSocket URLs for streaming transcription requests.
    	us-east-1r   r   r   r   c                 C   s   || _ || _|| _d| _d| _|| _d| _d| _d| _d| _	d| _
d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _dS )a*  Initialize the presigned URL generator.

        Args:
            access_key: AWS access key ID.
            secret_key: AWS secret access key.
            session_token: AWS session token for temporary credentials.
            region: AWS region for the service. Defaults to "us-east-1".
        GET
transcribe z/stream-transcription-websockethostzAWS4-HMAC-SHA256N)r   r   r   methodservicer   endpointr#   amz_date	datestampcanonical_uricanonical_headerssigned_headers	algorithmcredential_scopecanonical_querystringpayload_hashcanonical_requeststring_to_sign	signaturerequest_url)selfr   r   r   r   r   r   r   __init___   s*   
z"AWSTranscribePresignedURL.__init__r"   r   Fr   r   r   r   r   r   r   r   r	   r
   r   r   c                 C   s,  d| j  d| _d| j  d| _tj }|d| _|d| _d| j d| _| j d| j  d| j	 d	| _
d
| j | _|  jd| j d | j
 7  _|  jd| j 7  _|  jd7  _| jrq|  jdtjj| jdd 7  _|  jd| j 7  _|r|  jd7  _|	r|  jd7  _|r|  jd| 7  _|r|  jd| 7  _|dkr|  jdt| 7  _|
r|  jd|
 7  _|r|  jdt| 7  _|r|  jd7  _|r|  jd| 7  _|r|  jd| 7  _tdd | _| j d| j d| j d| j d| j d| j | _| j d| j  d| j	 d}| j d| j d| dt| jd  }td | j d| jdtj }t|| j dtj }t|| j	dtj }t|d!tj }t||dtj | _ |  jd"| j  7  _| j| j d# | j | _!| j!S )$a6  Generate a presigned WebSocket URL for AWS Transcribe.

        Args:
            sample_rate: Audio sample rate in Hz.
            language_code: Language code for transcription.
            media_encoding: Audio encoding format.
            vocabulary_name: Custom vocabulary name.
            vocabulary_filter_name: Vocabulary filter name.
            show_speaker_label: Whether to include speaker labels.
            enable_channel_identification: Whether to enable channel identification.
            number_of_channels: Number of audio channels.
            enable_partial_results_stabilization: Whether to enable partial result stabilization.
            partial_results_stability: Stability level for partial results.

        Returns:
            Presigned WebSocket URL with authentication parameters.
        zwss://transcribestreaming.z.amazonaws.com:8443ztranscribestreaming.z%Y%m%dT%H%M%SZz%Y%m%dzhost:
z%2Fz%2Faws4_requestzX-Amz-Algorithm=z&X-Amz-Credential=z&X-Amz-Date=z&X-Amz-Expires=300z&X-Amz-Security-Token=r"   )safez&X-Amz-SignedHeaders=z#&enable-channel-identification=truez*&enable-partial-results-stabilization=truez&language-code=z&media-encoding=r   z&number-of-channels=z&partial-results-stability=z&sample-rate=z&show-speaker-label=truez&vocabulary-filter-name=z&vocabulary-name=utf-8/z/aws4_requestAWS4s   aws4_requestz&X-Amz-Signature=?)"r   r&   r#   datetimeutcnowstrftimer'   r(   r*   r%   r-   r,   r.   r   r   urllibparsequoter+   strhashlibsha256encode	hexdigestr/   r$   r)   r0   hmacnewr   digestr2   r3   )r4   r   r   r   r   r   r   r   r	   r
   r   nowr-   r1   k_datek_region	k_service	k_signingr   r   r   r      sz   
4z)AWSTranscribePresignedURL.get_request_urlN)r   )	r"   r   r"   r"   FFr   Fr"   )	__name__
__module____qualname____doc__rB   r5   intboolr   r   r   r   r   r   X   sX    
$	
r   header_nameheader_valuec                 C   sx   |  d}tt|g}tdg}| d}tdt|}t }|| || || || || |S )zBuild a header following AWS event stream format.

    Args:
        header_name: Name of the header.
        header_value: Value of the header.

    Returns:
        Encoded header as a bytearray following AWS event stream protocol.
    r8      >H)rE   byteslenstructpack	bytearrayextend)rU   rV   namename_byte_length
value_typevaluevalue_byte_lengthheader_listr   r   r   get_headers   s   








re   payloadc                 C   s  t dd}t dd}t dd}t }|| || || tdt|t|  d }tdt|}td	gd
 }||dd< ||dd< tdt|d@ }t }	|	| |	| |	| |	|  t|	}
tdt|
d@ }|	| t|	S )aM  Build an event message for AWS Transcribe streaming.

    Creates a properly formatted AWS event stream message containing audio data
    for real-time transcription. Follows the AWS event stream protocol with
    prelude, headers, payload, and CRC checksums.

    Args:
        payload: Raw audio bytes to include in the event message.

    Returns:
        Complete event message as bytes, ready to send via WebSocket.

    Note:
        Implementation matches AWS sample:
        https://github.com/aws-samples/amazon-transcribe-streaming-python-websockets/blob/main/eventstream.py
    z:content-typezapplication/octet-streamz:event-type
AudioEventz:message-typeevent>I   r      N       )	re   r]   r^   r[   r\   rZ   binasciicrc32rY   )rf   content_type_headerevent_type_headermessage_type_headerheaderstotal_byte_lengthheaders_byte_lengthpreludeprelude_crcmessage_as_listmessagemessage_crcr   r   r   build_event_message  s,   










r{   c                 C   sF  | dd }t d|\}}t d| dd d }| dd|  }| d| d }t d| dd d }|t|d@ ksCJ d	|t| dd d@ ksTJ d
i }|r|d }	|dd|	  d}
|d|	  }t d|d|	 d|	  d }|d|	 d|	 |  d}|||
< |d|	 | d }|sX|t|fS )a  Decode an AWS event stream message.

    Parses an AWS event stream message to extract headers and payload,
    verifying CRC checksums for data integrity.

    Args:
        message: Raw event stream message bytes received from AWS.

    Returns:
        A tuple of (headers, payload) where:

        - headers: Dictionary of parsed headers
        - payload: Dictionary of parsed JSON payload

    Raises:
        AssertionError: If CRC checksum verification fails.
    Nrk   z>IIri      r   rm   zPrelude CRC check failedzMessage CRC check failedr   r8   rX      rl   )r[   unpackrn   ro   decodejsonloads)ry   rv   total_lengthheaders_lengthrw   rs   rf   rz   headers_dictname_lenr_   ra   	value_lenrb   r   r   r   decode_event<  s&   " 	r   )rR   rn   r<   rC   rG   r   r[   urllib.parser?   typingr   r   rB   rS   rT   r   r   r]   re   rY   r{   r   r   r   r   r   <module>   sd   	

A 9