
    5i                        d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
ZddlmZmZ ddlmZmZmZ dd	lmZ dd
lmZ  G d de      Zd Z G d de      Z G d d      Ze G d d             Ze G d d             Ze G d d             Z G d de	      Ze G d d             Z G d de	      Z G d d      Z  G d  d!e!      Z"y)"zA
MQTT

All network operations in `awscrt.mqtt` are asynchronous.
    N)Future)IntEnum)	signature)NativeResource)HttpProxyOptionsHttpRequest)ClientBootstrapClientTlsContextSocketOptions)	dataclass)Clientc                   (    e Zd ZdZdZ	 dZ	 dZ	 d Zy)QoSz3Quality of Service enumeration

    [MQTT-4.3]
    r         c                 4    ddl m} 	  || j                        S )Nr   r   )awscrt.mqtt5r   value)selfMqtt5QoSs     m/home/marpiech/ifpan-abm-pgxpred/analysis/marpiech-gwas-test/venv/lib/python3.12/site-packages/awscrt/mqtt.pyto_mqtt5zQoS.to_mqtt54   s    0	 

##    N)__name__
__module____qualname____doc__AT_MOST_ONCEAT_LEAST_ONCEEXACTLY_ONCEr    r   r   r   r      s0    
 L M
 L$r   r   c                 8    	 t        |       S # t        $ r Y yw xY w)zPReturn None if the value cannot be converted to Qos (ex: 0x80 subscribe failure)N)r   	Exception)	qos_values    r   _try_qosr&   <   s#    9~ s   
 	c                   2    e Zd ZdZdZ	 dZ	 dZ	 dZ	 dZ	 dZ	y)	ConnectReturnCodez9Connect return code enumeration.

    [MQTT-3.2.2.3]
    r   r   r            N)
r   r   r   r   ACCEPTEDUNACCEPTABLE_PROTOCOL_VERSIONIDENTIFIER_REJECTEDSERVER_UNAVAILABLEBAD_USERNAME_OR_PASSWORDNOT_AUTHORIZEDr"   r   r   r(   r(   D   sO    
 H$%!
 
 
  !
 Nr   r(   c                       e Zd ZdZdZd Zy)Willa/  A Will message is published by the server if a client is lost unexpectedly.

    The Will message is stored on the server when a client connects.
    It is published if the client connection is lost without the server
    receiving a DISCONNECT packet.

    [MQTT-3.1.2-8]

    Args:
        topic (str): Topic to publish Will message on.
        qos (QoS): QoS used when publishing the Will message.
        payload (bytes): Content of Will message.
        retain (bool): Whether the Will message is to be retained when it is published.

    Attributes:
        topic (str): Topic to publish Will message on.
        qos (QoS): QoS used when publishing the Will message.
        payload (bytes): Content of Will message.
        retain (bool): Whether the Will message is to be retained when it is published.
    topicqospayloadretainc                 <    || _         || _        || _        || _        y Nr4   )r   r5   r6   r7   r8   s        r   __init__zWill.__init__   s    
r   N)r   r   r   r   	__slots__r;   r"   r   r   r3   r3   l   s    ( 6Ir   r3   c                   .    e Zd ZU dZdZeed<   dZeed<   y)OnConnectionSuccessDataa3  Dataclass containing data related to a on_connection_success Callback

    Args:
        return_code (ConnectReturnCode): Connect return. code received from the server.
        session_present (bool): True if the connection resumes an existing session.
                                False if new session. Note that the server has forgotten all previous subscriptions
                                if this is False.
                                Subscriptions can be re-established via resubscribe_existing_topics() if the connection was a reconnection.
    Nreturn_codeFsession_present)	r   r   r   r   r?   r(   __annotations__r@   boolr"   r   r   r>   r>      s     &*K")!OT!r   r>   c                   H    e Zd ZU dZdZej                  j                  ed<   y)OnConnectionFailureDatazDataclass containing data related to a on_connection_failure Callback

    Args:
        error (ConnectReturnCode): Error code with reason for connection failure
    Nerror)	r   r   r   r   rE   awscrt
exceptionsAwsCrtErrorrA   r"   r   r   rD   rD      s    
 ,0E6((/r   rD   c                       e Zd ZdZy)OnConnectionClosedDataz`Dataclass containing data related to a on_connection_closed Callback.
    Currently unused.
    Nr   r   r   r   r"   r   r   rJ   rJ      s     	r   rJ   c                   (     e Zd ZdZdZd fd	Z xZS )r   ao  MQTT client.

    Args:
        bootstrap (Optional [ClientBootstrap]): Client bootstrap to use when initiating new socket connections.
            If None is provided, the default singleton is used.

        tls_ctx (Optional[ClientTlsContext]): TLS context for secure socket connections.
            If None is provided, then an unencrypted connection is used.
    tls_ctxc                     t        |t              s|J |t        |t              sJ t        |           || _        |st        j                         }t        j                  ||      | _	        y r:   )

isinstancer	   r
   superr;   rM   get_or_create_static_default_awscrtmqtt_client_new_binding)r   	bootstraprM   	__class__s      r   r;   zClient.__init__   sd    )_59JJJ*W6F"GGG'DDFI//	7Cr   )NN)r   r   r   r   r<   r;   __classcell__rV   s   @r   r   r      s     ID Dr   r   c                   J    e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	eed<   y)OperationStatisticsDataa1  Dataclass containing some simple statistics about the current state of the connection's queue of operations

    Args:
        incomplete_operation_count (int): total number of operations submitted to the connection that have not yet been completed.  Unacked operations are a subset of this.
        incomplete_operation_size (int): total packet size of operations submitted to the connection that have not yet been completed.  Unacked operations are a subset of this.
        unacked_operation_count (int): total number of operations that have been sent to the server and are waiting for a corresponding ACK before they can be completed.
        unacked_operation_size (int): total packet size of operations that have been sent to the server and are waiting for a corresponding ACK before they can be completed.
    r   incomplete_operation_countincomplete_operation_sizeunacked_operation_countunacked_operation_sizeN)
r   r   r   r   r[   intrA   r\   r]   r^   r"   r   r   rZ   rZ      s5     '('%&s&#$S$"#C#r   rZ   c                        e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fd	Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd ZddZd Zd Zd ZddZd Z xZS )
Connectiona\  MQTT client connection.

    Args:
        client (Client): MQTT client to spawn connection from.

        host_name (str): Server name to connect to.

        port (int): Server port to connect to.

        client_id (str): ID to place in CONNECT packet. Must be unique across all devices/clients.
            If an ID is already in use, the other client will be disconnected.

        clean_session (bool): Whether or not to start a clean session with each reconnect.
            If True, the server will forget all subscriptions with each reconnect.
            Set False to request that the server resume an existing session
            or start a new session that may be resumed after a connection loss.
            The `session_present` bool in the connection callback informs
            whether an existing session was successfully resumed.
            If an existing session is resumed, the server remembers previous subscriptions
            and sends messages (with QoS1 or higher) that were published while the client was offline.

        on_connection_interrupted: Optional callback invoked whenever the MQTT connection is lost.
            The MQTT client will automatically attempt to reconnect.
            The function should take the following arguments return nothing:

                *   `connection` (:class:`Connection`): This MQTT Connection.

                *   `error` (:class:`awscrt.exceptions.AwsCrtError`): Exception which caused connection loss.

                *   `**kwargs` (dict): Forward-compatibility kwargs.

        on_connection_resumed: Optional callback invoked whenever the MQTT connection
            is automatically resumed. Function should take the following arguments and return nothing:

                *   `connection` (:class:`Connection`): This MQTT Connection

                *   `return_code` (:class:`ConnectReturnCode`): Connect return
                    code received from the server.

                *   `session_present` (bool): True if resuming existing session. False if new session.
                    Note that the server has forgotten all previous subscriptions if this is False.
                    Subscriptions can be re-established via resubscribe_existing_topics().

                *   `**kwargs` (dict): Forward-compatibility kwargs.

        on_connection_success: Optional callback invoked whenever the connection successfully connects.
            This callback is invoked for every successful connect and every successful reconnect.

            Function should take the following arguments and return nothing:

                * `connection` (:class:`Connection`): This MQTT Connection

                * `callback_data` (:class:`OnConnectionSuccessData`): The data returned from the connection success.

        on_connection_failure: Optional callback invoked whenever the connection fails to connect.
            This callback is invoked for every failed connect and every failed reconnect.

            Function should take the following arguments and return nothing:

                * `connection` (:class:`Connection`): This MQTT Connection

                * `callback_data` (:class:`OnConnectionFailureData`): The data returned from the connection failure.

        on_connection_closed: Optional callback invoked whenever the connection has been disconnected and shutdown successfully.
            Function should take the following arguments and return nothing:

                * `connection` (:class:`Connection`): This MQTT Connection

                * `callback_data` (:class:`OnConnectionClosedData`): The data returned from the connection close.

        reconnect_min_timeout_secs (int): Minimum time to wait between reconnect attempts.
            Must be <= `reconnect_max_timeout_secs`.
            Wait starts at min and doubles with each attempt until max is reached.

        reconnect_max_timeout_secs (int): Maximum time to wait between reconnect attempts.
            Must be >= `reconnect_min_timeout_secs`.
            Wait starts at min and doubles with each attempt until max is reached.

        keep_alive_secs (int): The keep alive value, in seconds, to send in CONNECT packet.
            A PING will automatically be sent at this interval.
            The server will assume the connection is lost if no PING is received after 1.5X this value.
            This duration must be longer than ping_timeout_ms.

        ping_timeout_ms (int): Milliseconds to wait for ping response before client assumes
            the connection is invalid and attempts to reconnect.
            This duration must be shorter than `keep_alive_secs`.

        protocol_operation_timeout_ms (int): Milliseconds to wait for the response to the operation
            requires response by protocol. Set to zero to disable timeout. Otherwise,
            the operation will fail if no response is received within this amount of time after
            the packet is written to the socket
            It applied to PUBLISH (QoS>0) and UNSUBSCRIBE now.

        will (Will): Will to send with CONNECT packet. The will is
            published by the server when its connection to the client is unexpectedly lost.

        username (str): Username to connect with.

        password (str): Password to connect with.

        socket_options (Optional[awscrt.io.SocketOptions]): Optional socket options.

        use_websocket (bool): If true, connect to MQTT over websockets.

        websocket_proxy_options (Optional[awscrt.http.HttpProxyOptions]):
            Optional proxy options for websocket connections.  Deprecated, use `proxy_options` instead.

        websocket_handshake_transform: Optional function to transform websocket handshake request.
            If provided, function is called each time a websocket connection is attempted.
            The function may modify the HTTP request before it is sent to the server.
            See :class:`WebsocketHandshakeTransformArgs` for more info.
            Function should take the following arguments and return nothing:

                *   `transform_args` (:class:`WebsocketHandshakeTransformArgs`):
                    Contains HTTP request to be transformed. Function must call
                    `transform_args.done()` when complete.

                *   `**kwargs` (dict): Forward-compatibility kwargs.

        proxy_options (Optional[awscrt.http.HttpProxyOptions]):
            Optional proxy options for all connections.
        c                    t        |t              st        |t              sJ t        |      s|J t        |      s|J t        |t              s|J t        |t
              s|J t        |t              s|J t        |t              s|J t        |      s|J t        |      s|J t        |      s|J t        |      s|J ||	kD  rt        d      |
dz  |k  rt        d      |r|rt        d      t        | %          || _
        t        |t              rdnd| _        || _        || _        || _        || _        || _        || _        || _        || _        || _        || _        || _        || _        |	| _        |
| _        || _        || _        || _        || _        || _        |r|n	t               | _        |r|n|| _         tC        jD                  | ||| j                        | _#        y )NzG'reconnect_min_timeout_secs' cannot exceed 'reconnect_max_timeout_secs'i  z@'keep_alive_secs' duration must be longer than 'ping_timeout_ms'zk'websocket_proxy_options' has been deprecated in favor of 'proxy_options'.  Both parameters may not be set.r+   r)   )$rO   r   Mqtt5Clientcallabler3   r   r   
ValueErrorrP   r;   client_client_version_on_connection_interrupted_cb_on_connection_resumed_cb_use_websockets_ws_handshake_transform_cb_on_connection_success_cb_on_connection_failure_cb_on_connection_closed_cb	client_id	host_nameportclean_sessionreconnect_min_timeout_secsreconnect_max_timeout_secskeep_alive_secsping_timeout_msprotocol_operation_timeout_mswillusernamepasswordsocket_optionsproxy_optionsrR   mqtt_client_connection_newrT   )r   rf   rp   rq   ro   rr   on_connection_interruptedon_connection_resumedrs   rt   ru   rv   rw   rx   ry   rz   r{   use_websocketswebsocket_proxy_optionswebsocket_handshake_transformr|   on_connection_successon_connection_failureon_connection_closedrV   s                           r   r;   zConnection.__init__O  s7   4 &&)Z-LLL126O6WWW-.2G2OOO$%55.-8N<RRR13CDH_Hggg-)9:m>SSS56:W:___-.2G2OOO-.2G2OOO,-1E1MMM%(BBfggT!_4_``4 ? @ @ 	 $.v{$Cq-F*)>&-*G')>&)>&(<% #"	**D'*D'..-J*	  0>nMO.;]AX::  	
r   c                     t        |      }	 |j                  dddt        d      d       y# t        $ r |j                  dd       Y yw xY w)Nr5   r7   Tr   r5   r7   dupr6   r8   Fr5   r7   )r   bindr   	TypeError)r   callbackcallback_sigs      r   *_check_uses_old_message_callback_signaturez5Connection._check_uses_old_message_callback_signature  sZ    
 !*	GYDcRSf]ab 	GY?	s   - AAc                 ~    | j                   r1| j                  | t        j                  j                  |             y y )N)
connectionrE   )rh   rF   rG   	from_code)r   
error_codes     r   _on_connection_interruptedz%Connection._on_connection_interrupted  s5    --..$fFWFWFaFablFm.n .r   c                 X    | j                   r| j                  | t        |      |       y y )N)r   r?   r@   )ri   r(   )r   r?   r@   s      r   _on_connection_resumedz!Connection._on_connection_resumed  s1    ))**-k: / + 1 *r   c                 r   | j                   t        j                  d d       y fd}t               }|j	                  |       t        j                  ||      }t        | ||      }	 | j                  |       y # t        $ r0}|j                         s|j                  |       Y d }~y Y d }~y d }~ww xY w)Nr   c                     d}| j                         }t        |t        j                  j                        r|j
                  }t        j                  | j                         |       y )Nr   )	exceptionrO   rF   rG   rH   coderR   $mqtt_ws_handshake_transform_complete)fr   hs_exceptionnative_userdatas      r   _on_completez8Connection._ws_handshake_transform.<locals>._on_complete  sM    J;;=L,(9(9(E(EF)..
88Ycdr   )transform_args)rk   rR   r   r   add_done_callbackr   _from_bindingsWebsocketHandshakeTransformArgsr$   doneset_done)	r   http_request_bindinghttp_headers_bindingr   r   futurehttp_requestr   es	      `     r   _ws_handshake_transformz"Connection._ws_handshake_transform  s    **288PQR	e   ."112FH\]8|VT	+++>+J 	+ ;;=''** !	+s   *A= =	B6!B11B6c                 ^    | r+| j                   rt               }| j                  | |       y y y )Nr   callback_data)rn   rJ   )r   datas     r   _on_connection_closedz Connection._on_connection_closed  s3    ,,-/--T-R - r   c                 v    | r7| j                   r*t        t        |      |      }| j                  | |       y y y )N)r?   r@   r   )rl   r>   r(   )r   r?   r@   r   s       r   _on_connection_successz!Connection._on_connection_success  sB    --. 1+ >$35 ..$d.S	 . r   c                     | rJ| j                   r=t        t        j                  j	                  |            }| j                  | |       y y y )N)rE   r   )rm   rD   rF   rG   r   )r   r   r   s      r   _on_connection_failurez!Connection._on_connection_failure  sG    --.V5F5F5P5PQ[5\]..$d.S . r   c                    t               fd}	 t        j                  | j                  | j                  | j
                  | j                  | j                  | j                  j                  | j                  | j                  | j                  | j                  | j                  | j                  | j                   | j"                  | j$                  || j&                         S # t(        $ r}j+                  |       Y d}~S d}~ww xY w)a  Open the actual connection to the server (async).

        Returns:
            concurrent.futures.Future: Future which completes when connection succeeds or fails.
            If connection fails, Future will contain an exception.
            If connection succeeds, Future will contain a dict with the following members:

            * ['session_present'] (bool): is True if resuming existing session and False if new session.
        c                     |r$j                  t        t        |                   y | r/j                  t        j                  j                  |              y j                  t        |             y N)r@   set_exceptionr$   r(   rF   rG   r   
set_resultdictr   r?   r@   r   s      r   
on_connectz&Connection.connect.<locals>.on_connect  T    $$Y/@/M%NO$$V%6%6%@%@%LM!!$"GHr   N)r   rR   mqtt_client_connection_connectrT   ro   rp   rq   r{   rf   rM   rs   rt   ru   rv   rw   rx   ry   rz   rr   r|   r$   r   r   r   r   r   s      @r   connectzConnection.connect  s     	I	$22		####////$$$$22		""""#.   	$  ##	$s   CC# #	D,DDc                     t               fd}	 t        j                  | j                  |       S # t        $ r}j                  |       Y d}~S d}~ww xY w)zDEPRECATED.

        awscrt.mqtt.ClientConnection automatically reconnects.
        To cease reconnect attempts, call disconnect().
        To resume the connection, call connect().
        c                     |r$j                  t        t        |                   y | r/j                  t        j                  j                  |              y j                  t        |             y r   r   r   s      r   r   z(Connection.reconnect.<locals>.on_connect   r   r   N)r   rR    mqtt_client_connection_reconnectrT   r$   r   r   s      @r   	reconnectzConnection.reconnect  sZ     	I	$44T]]JO   	$  ##	$    4 	AAAc                     t               fd}	 t        j                  | j                  |       S # t        $ r}j                  |       Y d}~S d}~ww xY w)zClose the connection (async).

        Returns:
            concurrent.futures.Future: Future which completes when the connection is closed.
            The future will contain an empty dict.
        c                  8     j                  t                      y r:   )r   r   )r   s   r   on_disconnectz,Connection.disconnect.<locals>.on_disconnect9  s    df%r   N)r   rR   !mqtt_client_connection_disconnectrT   r$   r   )r   r   r   r   s      @r   
disconnectzConnection.disconnect/  sY     	&	$55dmm]S
   	$  ##	$r   c                   	
 t               	d}r| j                        

fd}nd}	fd}	 t              sJ ddlm} t        ||      r|j                         }t        |t              sJ t        j                  | j                  ||j                  ||      }	|fS # t        $ r}	j                  |       Y d}~	|fS d}~ww xY w)a	  Subscribe to a topic filter (async).

        The client sends a SUBSCRIBE packet and the server responds with a SUBACK.

        subscribe() may be called while the device is offline, though the async
        operation cannot complete successfully until the connection resumes.

        Once subscribed, `callback` is invoked each time a message matching
        the `topic` is received. It is possible for such messages to arrive before
        the SUBACK is received.

        Args:
            topic (str): Subscribe to this topic filter, which may include wildcards.
            qos (QoS): Maximum requested QoS that server may use when sending messages to the client.
                The server may grant a lower QoS in the SUBACK (see returned Future)
            callback: Optional callback invoked when message received.
                Function should take the following arguments and return nothing:

                    *   `topic` (str): Topic receiving message.

                    *   `payload` (bytes): Payload of message.

                    *   `dup` (bool): DUP flag. If True, this might be re-delivery
                        of an earlier attempt to send the message.

                    *   `qos` (:class:`QoS`): Quality of Service used to deliver the message.

                    *   `retain` (bool): Retain flag. If True, the message was sent
                        as a result of a new subscription being made by the client.

                    *   `**kwargs` (dict): Forward-compatibility kwargs.

        Returns:
            Tuple[concurrent.futures.Future, int]: Tuple containing a Future and
            the ID of the SUBSCRIBE packet. The Future completes when a
            SUBACK is received from the server. If successful, the Future will
            contain a dict with the following members:

                *   ['packet_id'] (int): ID of the SUBSCRIBE packet being acknowledged.

                *   ['topic'] (str): Topic filter of the SUBSCRIBE packet being acknowledged.

                *   ['qos'] (:class:`QoS`): Maximum QoS that was granted by the server.
                    This may be lower than the requested QoS.

            If unsuccessful, the Future contains an exception. The exception
            will be a :class:`SubscribeError` if a SUBACK was received
            in which the server rejected the subscription. Other exception
            types indicate other errors with the operation.
        r   c                 L    r | |       y  | ||t        |      |       y Nr   r   r   r5   r7   r   r6   r8   r   uses_old_signatures        r   callback_wrapperz.Connection.subscribe.<locals>.callback_wrapper~  %    %5':5'sCY_`r   Nc                     |r/j                  t        j                  j                  |             y t	        |      }|j                  t        |             y j                  t        | ||             y )N)	packet_idr5   r6   )r   rF   rG   r   r&   SubscribeErrorr   r   )r   r5   r6   r   r   s       r   subackz$Connection.subscribe.<locals>.suback  sd    $$V%6%6%@%@%LMsm;(()>?%%d"+#' r   r   )r   r   rd   r   r   rO   to_mqtt3rR    mqtt_client_connection_subscriberT   r   r$   r   )r   r5   r6   r   r   r   r   r   r   r   r   s      `     @@r   	subscribezConnection.subscribeD  s    h 	!%!P!PQY!Za  $			$H%)99943)llnc3'''@@ucii1A6KI
 y    	$  ##y  	$s   A0B& &	C/CCc                     t              sJ r| j                        fd}nd}t        j                  | j                  |       y)a)  Set callback to be invoked when ANY message is received.

        callback: Callback to invoke when message received, or None to disable.
            Function should take the following arguments and return nothing:

                *   `topic` (str): Topic receiving message.

                *   `payload` (bytes): Payload of message.

                *   `dup` (bool): DUP flag. If True, this might be re-delivery
                    of an earlier attempt to send the message.

                *   `qos` (:class:`QoS`): Quality of Service used to deliver the message.

                *   `retain` (bool): Retain flag. If True, the message was sent
                    as a result of a new subscription being made by the client.

                *   `**kwargs` (dict): Forward-compatibility kwargs.
        Nc                 L    r | |       y  | ||t        |      |       y r   r   r   s        r   r   z/Connection.on_message.<locals>.callback_wrapper  r   r   )rd   r   rR   !mqtt_client_connection_on_messagerT   )r   r   r   r   s    ` @r   
on_messagezConnection.on_message  sP    ( !X%555!%!P!PQY!Za  $11$--AQRr   c                     t               d}fd}	 t        j                  | j                  ||      }|fS # t        $ r}j                  |       Y d}~|fS d}~ww xY w)ac  Unsubscribe from a topic filter (async).

        The client sends an UNSUBSCRIBE packet, and the server responds with an UNSUBACK.

        Args:
            topic (str): Unsubscribe from this topic filter.

        Returns:
            Tuple[concurrent.futures.Future, int]: Tuple containing a Future and
            the ID of the UNSUBSCRIBE packet. The Future completes when an
            UNSUBACK is received from the server. If successful, the Future
            will contain a dict with the following members:

            * ['packet_id'] (int): ID of the UNSUBSCRIBE packet being acknowledged.
        r   c                     |dk7  r/j                  t        j                  j                  |             y j	                  t        |              y Nr   )r   r   rF   rG   r   r   r   r   r   r   s     r   unsubackz(Connection.unsubscribe.<locals>.unsuback  <    Q$$V%6%6%@%@%LM!!$";<r   N)r   rR   "mqtt_client_connection_unsubscriberT   r$   r   )r   r5   r   r   r   r   s        @r   unsubscribezConnection.unsubscribe  sp      		=	$BB4==RWYabI
 y    	$  ##y  	$s   !9 	A AA c                     d}t               fd}	 t        j                  | j                  |      }|j	                  t        dg              |fS # t        $ r}j                  |       Y d}~|fS d}~ww xY w)a  
        Subscribe again to all current topics.

        This is to help when resuming a connection with a clean session.

        **Important**: Currently the resubscribe function does not take the AWS IoT Core maximum subscriptions
        per subscribe request quota into account. If the client has more subscriptions than the maximum,
        resubscribing must be done manually using the `subscribe()` function for each desired topic
        filter. The client will be disconnected by AWS IoT Core if the resubscribe exceeds the subscriptions
        per subscribe request quota.

        The AWS IoT Core maximum subscriptions per subscribe request quota is listed at the following URL:
        https://docs.aws.amazon.com/general/latest/gr/iot-core.html#genref_max_subscriptions_per_subscribe_request

        Returns:
            Tuple[concurrent.futures.Future, int]: Tuple containing a Future and
            the ID of the SUBSCRIBE packet. The Future completes when a SUBACK
            is received from the server. If successful, the Future will contain
            a dict with the following members:

            *   ['packet_id']: ID of the SUBSCRIBE packet being acknowledged,
                or None if there were no topics to resubscribe to.

            *   ['topics']: A list of (topic, qos) tuples, where qos will be
                None if the topic failed to resubscribe. If there were no topics
                to resubscribe to, then the list will be empty.
        r   c                     |r/j                  t        j                  j                  |             y j	                  t        | |D cg c]  \  }}|t        |      f c}}             y c c}}w )Nr   topics)r   rF   rG   r   r   r   r&   )r   topic_qos_tuplesr   r5   r6   r   s        r   	on_subackz9Connection.resubscribe_existing_topics.<locals>.on_suback  s[    $$V%6%6%@%@%LM!!$'GWX|sUHSM2X# Xs   	A.Nr   )r   rR   2mqtt_client_connection_resubscribe_existing_topicsrT   r   r   r$   r   )r   r   r   r   r   s       @r   resubscribe_existing_topicsz&Connection.resubscribe_existing_topics  s    8 			$RRSWS`S`bklI !!$b"AB
 y    	$  ##y  	$s   >A 	A=A88A=c                 H  	 t               	d}	fd}	 ddlm} t        ||      r|j	                         }t        |t              sJ t        j                  | j                  |||j                  ||      }	|fS # t        $ r}	j                  |       Y d}~	|fS d}~ww xY w)a8  Publish message (async).

        If the device is offline, the PUBLISH packet will be sent once the connection resumes.

        Args:
            topic (str): Topic name.
            payload (Union[str, bytes, bytearray]): Contents of message.
            qos (QoS): Quality of Service for delivering this message.
            retain (bool): If True, the server will store the message and its QoS
                so that it can be delivered to future subscribers whose subscriptions
                match its topic name.

        Returns:
            Tuple[concurrent.futures.Future, int]: Tuple containing a Future and
            the ID of the PUBLISH packet. The QoS determines when the Future completes:

            *   For QoS 0, completes as soon as the packet is sent.
            *   For QoS 1, completes when PUBACK is received.
            *   For QoS 2, completes when PUBCOMP is received.

            If successful, the Future will contain a dict with the following members:

            *   ['packet_id'] (int): ID of the PUBLISH packet that is complete.
        r   c                     |dk7  r/j                  t        j                  j                  |             y j	                  t        |              y r   r   r   s     r   pubackz"Connection.publish.<locals>.puback7  r   r   r   N)r   r   r   rO   r   rR   mqtt_client_connection_publishrT   r   r$   r   )
r   r5   r7   r6   r8   r   r   r   r   r   s
            @r   publishzConnection.publish  s    2 		=	$43)llnc3'''>>t}}eU\^a^g^gioqwxI y    	$  ##y  	$s   A"A: :	B!BB!c                 t    t        j                  | j                        }t        |d   |d   |d   |d         S )zQueries the connection's internal statistics for incomplete operations.

        Returns:
            The (:class:`OperationStatisticsData`) containing the statistics
        r   r   r   r)   )rR    mqtt_client_connection_get_statsrT   rZ   )r   results     r   	get_statszConnection.get_statsH  s9     99$--H&vay&)VAYq	RRr   )TNNr+   <   i  i  r   NNNNFNNNNNNr:   )F)r   r   r   r   r;   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rW   rX   s   @r   ra   ra      s    y@  $+/'+,-,.!%!%/0 $ %)-/3#'+'+&*/R
ho1+0STT,\0*\!|#SJ!B1!f+!ZSr   ra   c                       e Zd ZdZd ZddZy)r   a  
    Argument to a "websocket_handshake_transform" function.

    A websocket_handshake_transform function has signature:
    ``fn(transform_args: WebsocketHandshakeTransformArgs, **kwargs) -> None``

    The function implementer may modify `transform_args.http_request` as desired.
    They MUST call `transform_args.set_done()` when complete, passing an
    exception if something went wrong. Failure to call `set_done()`
    will hang the application.

    The implementer may do asynchronous work before calling `transform_args.set_done()`,
    they are not required to call `set_done()` within the scope of the transform function.
    An example of async work would be to fetch credentials from another service,
    sign the request headers, and finally call `set_done()` to mark the transform complete.

    The default websocket handshake request uses path "/mqtt".
    All required headers are present,
    plus the optional header "Sec-WebSocket-Protocol: mqtt".

    Args:
        mqtt_connection (Connection): Connection this handshake is for.
        http_request (awscrt.http.HttpRequest): HTTP request for this handshake.
        done_future (concurrent.futures.Future): Future to complete when the
            :meth:`set_done()` is called. It will contain None if successful,
            or an exception will be set.

    Attributes:
        mqtt_connection (Connection): Connection this handshake is for.
        http_request (awscrt.http.HttpRequest): HTTP request for this handshake.
    c                 .    || _         || _        || _        y r:   )mqtt_connectionr   _done_future)r   r   r   done_futures       r   r;   z(WebsocketHandshakeTransformArgs.__init__t  s    .('r   Nc                 v    || j                   j                  d       y| j                   j                  |       y)zq
        Mark the transformation complete.
        If exception is passed in, the handshake is canceled.
        N)r   r   r   )r   r   s     r   r   z(WebsocketHandshakeTransformArgs.set_doney  s2    
 ((.++I6r   r:   )r   r   r   r   r;   r   r"   r   r   r   r   S  s    @(
7r   r   c                       e Zd ZdZy)r   z*
    Subscription rejected by server.
    NrK   r"   r   r   r   r     s     	r   r   )#r   rR   concurrent.futuresr   enumr   inspectr   rF   r   awscrt.exceptionsawscrt.httpr   r   	awscrt.ior	   r
   r   dataclassesr   r   r   rc   r   r&   r(   r3   r>   rD   rJ   rZ   ra   r   r$   r   r"   r   r   <module>r     s     %   !  5 F F ! .$$' $$N% %P < " " " 0 0 0 	 	 	D^ D0 $ $ $}	S }	S@.7 .7b	Y 	r   