pamoja.mqtt
Idiomatic async MQTT client facade.
Wraps the native pamoja._native.MqttClient with a Python-native surface:
awaitable methods, async for iteration over messages, async with
lifecycle management, a string enum for quality of service, and keyword
construction. It adds ergonomics only; every operation delegates to the Rust
core.
1"""Idiomatic async MQTT client facade. 2 3Wraps the native :class:`pamoja._native.MqttClient` with a Python-native surface: 4awaitable methods, ``async for`` iteration over messages, ``async with`` 5lifecycle management, a string enum for quality of service, and keyword 6construction. It adds ergonomics only; every operation delegates to the Rust 7core. 8""" 9 10from __future__ import annotations 11 12import enum 13from typing import AsyncIterator, Optional, Union 14 15from pamoja._native import MqttClient as _NativeMqttClient 16from pamoja._native import MqttMessage, MqttTls, MqttWill 17 18__all__ = ["MqttClient", "MqttMessage", "MqttTls", "MqttWill", "Qos"] 19 20 21class Qos(str, enum.Enum): 22 """MQTT delivery guarantee, mirroring the protocol's quality-of-service levels.""" 23 24 #: Fire and forget; the broker does not acknowledge delivery. 25 AT_MOST_ONCE = "AtMostOnce" 26 #: Delivered at least once and acknowledged. 27 AT_LEAST_ONCE = "AtLeastOnce" 28 #: Delivered exactly once via a four-step handshake. 29 EXACTLY_ONCE = "ExactlyOnce" 30 31 32class MqttClient: 33 """An MQTT client transport. 34 35 Construct it with broker settings, :meth:`connect`, then :meth:`publish`, 36 :meth:`subscribe`, and read inbound messages with :meth:`recv` or by 37 iterating the client with ``async for``. The client also works as an async 38 context manager, connecting on entry and disconnecting on exit. 39 40 Example:: 41 42 async with MqttClient(client_id="sensor-1", host="localhost", port=1883) as client: 43 await client.subscribe("sensors/+/temperature") 44 await client.publish("sensors/1/temperature", "21.5") 45 async for message in client: 46 print(message.topic, message.payload.decode()) 47 """ 48 49 def __init__( 50 self, 51 *, 52 client_id: str, 53 host: str, 54 port: int, 55 keep_alive_secs: Optional[int] = None, 56 capacity: Optional[int] = None, 57 qos: Optional[Qos] = None, 58 max_packet_size: Optional[int] = None, 59 username: Optional[str] = None, 60 password: Optional[str] = None, 61 will: Optional[MqttWill] = None, 62 tls: Optional[MqttTls] = None, 63 ) -> None: 64 """Create a disconnected client from the given broker settings. 65 66 :param client_id: The MQTT client identifier presented to the broker. 67 :param host: The broker hostname or IP address. 68 :param port: The broker TCP port, conventionally 1883 for plaintext MQTT. 69 :param keep_alive_secs: Keep-alive interval in seconds. Defaults to 30. 70 :param capacity: Bound on outstanding client requests. Defaults to 64. 71 :param qos: Default quality of service. Defaults to ``Qos.AT_LEAST_ONCE``. 72 :param max_packet_size: The largest packet the connection sends or accepts, in 73 bytes. Defaults to 10,240. A publish that would be larger is refused and the 74 connection stays up, but a larger packet arriving from the broker ends the 75 connection, so every client that shares a topic needs a limit that fits it. 76 :param username: The name to sign in to the broker with. 77 :param password: The password to sign in with, which needs a username. It travels 78 in the clear unless the connection uses ``tls``. 79 :param will: A message the broker publishes if the connection ends without a 80 goodbye. 81 :param tls: TLS settings; a connection with them is secured, conventionally on 82 port 8883. 83 :raises PamojaError: If a password comes without a username. 84 """ 85 qos_value = qos.value if isinstance(qos, Qos) else qos 86 self._native = _NativeMqttClient( 87 client_id=client_id, 88 host=host, 89 port=port, 90 keep_alive_secs=keep_alive_secs, 91 capacity=capacity, 92 qos=qos_value, 93 max_packet_size=max_packet_size, 94 username=username, 95 password=password, 96 will=will, 97 tls=tls, 98 ) 99 100 async def connect(self) -> None: 101 """Connect to the broker and start the background event loop. 102 103 :raises PamojaError: If the connection cannot be established. 104 """ 105 await self._native.connect() 106 107 async def publish( 108 self, 109 topic: str, 110 payload: Union[str, bytes], 111 *, 112 qos: Optional[Qos] = None, 113 retain: bool = False, 114 ) -> None: 115 """Publish a payload to a topic, returning once it is queued for the broker. 116 117 This returns before the broker acknowledges the message; 118 :meth:`publish_confirmed` waits for that. 119 120 :param topic: The destination topic. 121 :param payload: The message body; ``str`` payloads are encoded as UTF-8. 122 :param qos: The quality of service for this message. Defaults to the client's. 123 :param retain: Whether the broker keeps the message for clients that subscribe 124 later. An empty retained message clears the one the broker holds. 125 """ 126 data = payload.encode("utf-8") if isinstance(payload, str) else bytes(payload) 127 qos_value = qos.value if isinstance(qos, Qos) else qos 128 await self._native.publish(topic, data, qos=qos_value, retain=retain) 129 130 async def send(self, topic: str, payload: Union[str, bytes]) -> None: 131 """Publish a payload to a topic at the client's default quality of service. 132 133 This is the ``send`` every link has, so a profile's :class:`~pamoja.profile.Node` 134 or a :class:`~pamoja.profile.RuleEngine` publishes over an MQTT client the way it 135 publishes over any other link. 136 137 :param topic: The destination topic. 138 :param payload: The message body; ``str`` payloads are encoded as UTF-8. 139 """ 140 await self.publish(topic, payload) 141 142 async def publish_confirmed( 143 self, 144 topic: str, 145 payload: Union[str, bytes], 146 *, 147 qos: Optional[Qos] = None, 148 retain: bool = False, 149 ) -> None: 150 """Publish a payload to a topic and wait for the broker to acknowledge it. 151 152 The broker answers with a ``PUBACK`` at ``Qos.AT_LEAST_ONCE`` and a ``PUBCOMP`` 153 at ``Qos.EXACTLY_ONCE``; at ``Qos.AT_MOST_ONCE`` MQTT acknowledges nothing, so 154 this returns once the connection has taken the message. 155 156 :param topic: The destination topic. 157 :param payload: The message body; ``str`` payloads are encoded as UTF-8. 158 :param qos: The quality of service for this message. Defaults to the client's. 159 :param retain: Whether the broker keeps the message for clients that subscribe 160 later. 161 :raises PamojaError: If the connection ends before the acknowledgment, when the 162 message may or may not have arrived. 163 """ 164 data = payload.encode("utf-8") if isinstance(payload, str) else bytes(payload) 165 qos_value = qos.value if isinstance(qos, Qos) else qos 166 await self._native.publish_confirmed(topic, data, qos=qos_value, retain=retain) 167 168 async def subscribe(self, topic: str) -> None: 169 """Subscribe to a topic filter. 170 171 :param topic: The topic or wildcard filter to subscribe to. 172 """ 173 await self._native.subscribe(topic) 174 175 async def recv(self) -> Optional[MqttMessage]: 176 """Await the next message from any subscribed topic. 177 178 Wrap it in :func:`asyncio.wait_for` to stop waiting; the receive it cancels 179 leaves its message queued for the next one. 180 181 :returns: The next message, or ``None`` once the connection has ended. 182 :raises PamojaError: Once, saying why, when the connection ended on its own, 183 because the broker went away or another client connected with the same id. 184 """ 185 return await self._native.recv() 186 187 async def is_connected(self) -> bool: 188 """Report whether the client currently holds an active connection.""" 189 return await self._native.is_connected() 190 191 async def disconnect(self) -> None: 192 """Close the connection and stop the background event loop.""" 193 await self._native.disconnect() 194 195 async def messages(self) -> AsyncIterator[MqttMessage]: 196 """Yield messages from subscribed topics until the connection ends. 197 198 A connection that ends on its own raises its reason out of the loop. 199 """ 200 while True: 201 message = await self._native.recv() 202 if message is None: 203 return 204 yield message 205 206 def __aiter__(self) -> AsyncIterator[MqttMessage]: 207 """Iterate incoming messages, so a client can be used with ``async for``.""" 208 return self.messages() 209 210 async def __aenter__(self) -> "MqttClient": 211 await self.connect() 212 return self 213 214 async def __aexit__(self, *_exc: object) -> None: 215 await self.disconnect()
33class MqttClient: 34 """An MQTT client transport. 35 36 Construct it with broker settings, :meth:`connect`, then :meth:`publish`, 37 :meth:`subscribe`, and read inbound messages with :meth:`recv` or by 38 iterating the client with ``async for``. The client also works as an async 39 context manager, connecting on entry and disconnecting on exit. 40 41 Example:: 42 43 async with MqttClient(client_id="sensor-1", host="localhost", port=1883) as client: 44 await client.subscribe("sensors/+/temperature") 45 await client.publish("sensors/1/temperature", "21.5") 46 async for message in client: 47 print(message.topic, message.payload.decode()) 48 """ 49 50 def __init__( 51 self, 52 *, 53 client_id: str, 54 host: str, 55 port: int, 56 keep_alive_secs: Optional[int] = None, 57 capacity: Optional[int] = None, 58 qos: Optional[Qos] = None, 59 max_packet_size: Optional[int] = None, 60 username: Optional[str] = None, 61 password: Optional[str] = None, 62 will: Optional[MqttWill] = None, 63 tls: Optional[MqttTls] = None, 64 ) -> None: 65 """Create a disconnected client from the given broker settings. 66 67 :param client_id: The MQTT client identifier presented to the broker. 68 :param host: The broker hostname or IP address. 69 :param port: The broker TCP port, conventionally 1883 for plaintext MQTT. 70 :param keep_alive_secs: Keep-alive interval in seconds. Defaults to 30. 71 :param capacity: Bound on outstanding client requests. Defaults to 64. 72 :param qos: Default quality of service. Defaults to ``Qos.AT_LEAST_ONCE``. 73 :param max_packet_size: The largest packet the connection sends or accepts, in 74 bytes. Defaults to 10,240. A publish that would be larger is refused and the 75 connection stays up, but a larger packet arriving from the broker ends the 76 connection, so every client that shares a topic needs a limit that fits it. 77 :param username: The name to sign in to the broker with. 78 :param password: The password to sign in with, which needs a username. It travels 79 in the clear unless the connection uses ``tls``. 80 :param will: A message the broker publishes if the connection ends without a 81 goodbye. 82 :param tls: TLS settings; a connection with them is secured, conventionally on 83 port 8883. 84 :raises PamojaError: If a password comes without a username. 85 """ 86 qos_value = qos.value if isinstance(qos, Qos) else qos 87 self._native = _NativeMqttClient( 88 client_id=client_id, 89 host=host, 90 port=port, 91 keep_alive_secs=keep_alive_secs, 92 capacity=capacity, 93 qos=qos_value, 94 max_packet_size=max_packet_size, 95 username=username, 96 password=password, 97 will=will, 98 tls=tls, 99 ) 100 101 async def connect(self) -> None: 102 """Connect to the broker and start the background event loop. 103 104 :raises PamojaError: If the connection cannot be established. 105 """ 106 await self._native.connect() 107 108 async def publish( 109 self, 110 topic: str, 111 payload: Union[str, bytes], 112 *, 113 qos: Optional[Qos] = None, 114 retain: bool = False, 115 ) -> None: 116 """Publish a payload to a topic, returning once it is queued for the broker. 117 118 This returns before the broker acknowledges the message; 119 :meth:`publish_confirmed` waits for that. 120 121 :param topic: The destination topic. 122 :param payload: The message body; ``str`` payloads are encoded as UTF-8. 123 :param qos: The quality of service for this message. Defaults to the client's. 124 :param retain: Whether the broker keeps the message for clients that subscribe 125 later. An empty retained message clears the one the broker holds. 126 """ 127 data = payload.encode("utf-8") if isinstance(payload, str) else bytes(payload) 128 qos_value = qos.value if isinstance(qos, Qos) else qos 129 await self._native.publish(topic, data, qos=qos_value, retain=retain) 130 131 async def send(self, topic: str, payload: Union[str, bytes]) -> None: 132 """Publish a payload to a topic at the client's default quality of service. 133 134 This is the ``send`` every link has, so a profile's :class:`~pamoja.profile.Node` 135 or a :class:`~pamoja.profile.RuleEngine` publishes over an MQTT client the way it 136 publishes over any other link. 137 138 :param topic: The destination topic. 139 :param payload: The message body; ``str`` payloads are encoded as UTF-8. 140 """ 141 await self.publish(topic, payload) 142 143 async def publish_confirmed( 144 self, 145 topic: str, 146 payload: Union[str, bytes], 147 *, 148 qos: Optional[Qos] = None, 149 retain: bool = False, 150 ) -> None: 151 """Publish a payload to a topic and wait for the broker to acknowledge it. 152 153 The broker answers with a ``PUBACK`` at ``Qos.AT_LEAST_ONCE`` and a ``PUBCOMP`` 154 at ``Qos.EXACTLY_ONCE``; at ``Qos.AT_MOST_ONCE`` MQTT acknowledges nothing, so 155 this returns once the connection has taken the message. 156 157 :param topic: The destination topic. 158 :param payload: The message body; ``str`` payloads are encoded as UTF-8. 159 :param qos: The quality of service for this message. Defaults to the client's. 160 :param retain: Whether the broker keeps the message for clients that subscribe 161 later. 162 :raises PamojaError: If the connection ends before the acknowledgment, when the 163 message may or may not have arrived. 164 """ 165 data = payload.encode("utf-8") if isinstance(payload, str) else bytes(payload) 166 qos_value = qos.value if isinstance(qos, Qos) else qos 167 await self._native.publish_confirmed(topic, data, qos=qos_value, retain=retain) 168 169 async def subscribe(self, topic: str) -> None: 170 """Subscribe to a topic filter. 171 172 :param topic: The topic or wildcard filter to subscribe to. 173 """ 174 await self._native.subscribe(topic) 175 176 async def recv(self) -> Optional[MqttMessage]: 177 """Await the next message from any subscribed topic. 178 179 Wrap it in :func:`asyncio.wait_for` to stop waiting; the receive it cancels 180 leaves its message queued for the next one. 181 182 :returns: The next message, or ``None`` once the connection has ended. 183 :raises PamojaError: Once, saying why, when the connection ended on its own, 184 because the broker went away or another client connected with the same id. 185 """ 186 return await self._native.recv() 187 188 async def is_connected(self) -> bool: 189 """Report whether the client currently holds an active connection.""" 190 return await self._native.is_connected() 191 192 async def disconnect(self) -> None: 193 """Close the connection and stop the background event loop.""" 194 await self._native.disconnect() 195 196 async def messages(self) -> AsyncIterator[MqttMessage]: 197 """Yield messages from subscribed topics until the connection ends. 198 199 A connection that ends on its own raises its reason out of the loop. 200 """ 201 while True: 202 message = await self._native.recv() 203 if message is None: 204 return 205 yield message 206 207 def __aiter__(self) -> AsyncIterator[MqttMessage]: 208 """Iterate incoming messages, so a client can be used with ``async for``.""" 209 return self.messages() 210 211 async def __aenter__(self) -> "MqttClient": 212 await self.connect() 213 return self 214 215 async def __aexit__(self, *_exc: object) -> None: 216 await self.disconnect()
An MQTT client transport.
Construct it with broker settings, connect(), then publish(),
subscribe(), and read inbound messages with recv() or by
iterating the client with async for. The client also works as an async
context manager, connecting on entry and disconnecting on exit.
Example::
async with MqttClient(client_id="sensor-1", host="localhost", port=1883) as client:
await client.subscribe("sensors/+/temperature")
await client.publish("sensors/1/temperature", "21.5")
async for message in client:
print(message.topic, message.payload.decode())
50 def __init__( 51 self, 52 *, 53 client_id: str, 54 host: str, 55 port: int, 56 keep_alive_secs: Optional[int] = None, 57 capacity: Optional[int] = None, 58 qos: Optional[Qos] = None, 59 max_packet_size: Optional[int] = None, 60 username: Optional[str] = None, 61 password: Optional[str] = None, 62 will: Optional[MqttWill] = None, 63 tls: Optional[MqttTls] = None, 64 ) -> None: 65 """Create a disconnected client from the given broker settings. 66 67 :param client_id: The MQTT client identifier presented to the broker. 68 :param host: The broker hostname or IP address. 69 :param port: The broker TCP port, conventionally 1883 for plaintext MQTT. 70 :param keep_alive_secs: Keep-alive interval in seconds. Defaults to 30. 71 :param capacity: Bound on outstanding client requests. Defaults to 64. 72 :param qos: Default quality of service. Defaults to ``Qos.AT_LEAST_ONCE``. 73 :param max_packet_size: The largest packet the connection sends or accepts, in 74 bytes. Defaults to 10,240. A publish that would be larger is refused and the 75 connection stays up, but a larger packet arriving from the broker ends the 76 connection, so every client that shares a topic needs a limit that fits it. 77 :param username: The name to sign in to the broker with. 78 :param password: The password to sign in with, which needs a username. It travels 79 in the clear unless the connection uses ``tls``. 80 :param will: A message the broker publishes if the connection ends without a 81 goodbye. 82 :param tls: TLS settings; a connection with them is secured, conventionally on 83 port 8883. 84 :raises PamojaError: If a password comes without a username. 85 """ 86 qos_value = qos.value if isinstance(qos, Qos) else qos 87 self._native = _NativeMqttClient( 88 client_id=client_id, 89 host=host, 90 port=port, 91 keep_alive_secs=keep_alive_secs, 92 capacity=capacity, 93 qos=qos_value, 94 max_packet_size=max_packet_size, 95 username=username, 96 password=password, 97 will=will, 98 tls=tls, 99 )
Create a disconnected client from the given broker settings.
Parameters
- client_id: The MQTT client identifier presented to the broker.
- host: The broker hostname or IP address.
- port: The broker TCP port, conventionally 1883 for plaintext MQTT.
- keep_alive_secs: Keep-alive interval in seconds. Defaults to 30.
- capacity: Bound on outstanding client requests. Defaults to 64.
- qos: Default quality of service. Defaults to
Qos.AT_LEAST_ONCE. - max_packet_size: The largest packet the connection sends or accepts, in bytes. Defaults to 10,240. A publish that would be larger is refused and the connection stays up, but a larger packet arriving from the broker ends the connection, so every client that shares a topic needs a limit that fits it.
- username: The name to sign in to the broker with.
- password: The password to sign in with, which needs a username. It travels
in the clear unless the connection uses
tls. - will: A message the broker publishes if the connection ends without a goodbye.
- tls: TLS settings; a connection with them is secured, conventionally on port 8883.
Raises
- PamojaError: If a password comes without a username.
101 async def connect(self) -> None: 102 """Connect to the broker and start the background event loop. 103 104 :raises PamojaError: If the connection cannot be established. 105 """ 106 await self._native.connect()
Connect to the broker and start the background event loop.
Raises
- PamojaError: If the connection cannot be established.
108 async def publish( 109 self, 110 topic: str, 111 payload: Union[str, bytes], 112 *, 113 qos: Optional[Qos] = None, 114 retain: bool = False, 115 ) -> None: 116 """Publish a payload to a topic, returning once it is queued for the broker. 117 118 This returns before the broker acknowledges the message; 119 :meth:`publish_confirmed` waits for that. 120 121 :param topic: The destination topic. 122 :param payload: The message body; ``str`` payloads are encoded as UTF-8. 123 :param qos: The quality of service for this message. Defaults to the client's. 124 :param retain: Whether the broker keeps the message for clients that subscribe 125 later. An empty retained message clears the one the broker holds. 126 """ 127 data = payload.encode("utf-8") if isinstance(payload, str) else bytes(payload) 128 qos_value = qos.value if isinstance(qos, Qos) else qos 129 await self._native.publish(topic, data, qos=qos_value, retain=retain)
Publish a payload to a topic, returning once it is queued for the broker.
This returns before the broker acknowledges the message;
publish_confirmed() waits for that.
Parameters
- topic: The destination topic.
- payload: The message body;
strpayloads are encoded as UTF-8. - qos: The quality of service for this message. Defaults to the client's.
- retain: Whether the broker keeps the message for clients that subscribe later. An empty retained message clears the one the broker holds.
131 async def send(self, topic: str, payload: Union[str, bytes]) -> None: 132 """Publish a payload to a topic at the client's default quality of service. 133 134 This is the ``send`` every link has, so a profile's :class:`~pamoja.profile.Node` 135 or a :class:`~pamoja.profile.RuleEngine` publishes over an MQTT client the way it 136 publishes over any other link. 137 138 :param topic: The destination topic. 139 :param payload: The message body; ``str`` payloads are encoded as UTF-8. 140 """ 141 await self.publish(topic, payload)
Publish a payload to a topic at the client's default quality of service.
This is the send every link has, so a profile's ~pamoja.profile.Node
or a ~pamoja.profile.RuleEngine publishes over an MQTT client the way it
publishes over any other link.
Parameters
- topic: The destination topic.
- payload: The message body;
strpayloads are encoded as UTF-8.
143 async def publish_confirmed( 144 self, 145 topic: str, 146 payload: Union[str, bytes], 147 *, 148 qos: Optional[Qos] = None, 149 retain: bool = False, 150 ) -> None: 151 """Publish a payload to a topic and wait for the broker to acknowledge it. 152 153 The broker answers with a ``PUBACK`` at ``Qos.AT_LEAST_ONCE`` and a ``PUBCOMP`` 154 at ``Qos.EXACTLY_ONCE``; at ``Qos.AT_MOST_ONCE`` MQTT acknowledges nothing, so 155 this returns once the connection has taken the message. 156 157 :param topic: The destination topic. 158 :param payload: The message body; ``str`` payloads are encoded as UTF-8. 159 :param qos: The quality of service for this message. Defaults to the client's. 160 :param retain: Whether the broker keeps the message for clients that subscribe 161 later. 162 :raises PamojaError: If the connection ends before the acknowledgment, when the 163 message may or may not have arrived. 164 """ 165 data = payload.encode("utf-8") if isinstance(payload, str) else bytes(payload) 166 qos_value = qos.value if isinstance(qos, Qos) else qos 167 await self._native.publish_confirmed(topic, data, qos=qos_value, retain=retain)
Publish a payload to a topic and wait for the broker to acknowledge it.
The broker answers with a PUBACK at Qos.AT_LEAST_ONCE and a PUBCOMP
at Qos.EXACTLY_ONCE; at Qos.AT_MOST_ONCE MQTT acknowledges nothing, so
this returns once the connection has taken the message.
Parameters
- topic: The destination topic.
- payload: The message body;
strpayloads are encoded as UTF-8. - qos: The quality of service for this message. Defaults to the client's.
- retain: Whether the broker keeps the message for clients that subscribe later.
Raises
- PamojaError: If the connection ends before the acknowledgment, when the message may or may not have arrived.
169 async def subscribe(self, topic: str) -> None: 170 """Subscribe to a topic filter. 171 172 :param topic: The topic or wildcard filter to subscribe to. 173 """ 174 await self._native.subscribe(topic)
Subscribe to a topic filter.
Parameters
- topic: The topic or wildcard filter to subscribe to.
176 async def recv(self) -> Optional[MqttMessage]: 177 """Await the next message from any subscribed topic. 178 179 Wrap it in :func:`asyncio.wait_for` to stop waiting; the receive it cancels 180 leaves its message queued for the next one. 181 182 :returns: The next message, or ``None`` once the connection has ended. 183 :raises PamojaError: Once, saying why, when the connection ended on its own, 184 because the broker went away or another client connected with the same id. 185 """ 186 return await self._native.recv()
Await the next message from any subscribed topic.
Wrap it in asyncio.wait_for() to stop waiting; the receive it cancels
leaves its message queued for the next one.
:returns: The next message, or None once the connection has ended.
Raises
- PamojaError: Once, saying why, when the connection ended on its own, because the broker went away or another client connected with the same id.
188 async def is_connected(self) -> bool: 189 """Report whether the client currently holds an active connection.""" 190 return await self._native.is_connected()
Report whether the client currently holds an active connection.
192 async def disconnect(self) -> None: 193 """Close the connection and stop the background event loop.""" 194 await self._native.disconnect()
Close the connection and stop the background event loop.
196 async def messages(self) -> AsyncIterator[MqttMessage]: 197 """Yield messages from subscribed topics until the connection ends. 198 199 A connection that ends on its own raises its reason out of the loop. 200 """ 201 while True: 202 message = await self._native.recv() 203 if message is None: 204 return 205 yield message
Yield messages from subscribed topics until the connection ends.
A connection that ends on its own raises its reason out of the loop.
A message received from a subscribed topic.
The payload as text: words, or a number written out.
Raises ValueError if the payload is not UTF-8 text.
How a connection is secured with TLS, conventionally on port 8883.
A message the broker publishes on the client's behalf if its connection ends without a disconnect: the network dropped, the power failed, or the keep-alive ran out. A client that disconnects leaves no will behind.
22class Qos(str, enum.Enum): 23 """MQTT delivery guarantee, mirroring the protocol's quality-of-service levels.""" 24 25 #: Fire and forget; the broker does not acknowledge delivery. 26 AT_MOST_ONCE = "AtMostOnce" 27 #: Delivered at least once and acknowledged. 28 AT_LEAST_ONCE = "AtLeastOnce" 29 #: Delivered exactly once via a four-step handshake. 30 EXACTLY_ONCE = "ExactlyOnce"
MQTT delivery guarantee, mirroring the protocol's quality-of-service levels.