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()
class MqttClient:
 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())
MqttClient( *, client_id: str, host: str, port: int, keep_alive_secs: Optional[int] = None, capacity: Optional[int] = None, qos: Optional[Qos] = None, max_packet_size: Optional[int] = None, username: Optional[str] = None, password: Optional[str] = None, will: Optional[MqttWill] = None, tls: Optional[MqttTls] = None)
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.
async def connect(self) -> None:
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.
async def publish( self, topic: str, payload: Union[str, bytes], *, qos: Optional[Qos] = None, retain: bool = False) -> None:
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; str payloads 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.
async def send(self, topic: str, payload: Union[str, bytes]) -> None:
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; str payloads are encoded as UTF-8.
async def publish_confirmed( self, topic: str, payload: Union[str, bytes], *, qos: Optional[Qos] = None, retain: bool = False) -> None:
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; str payloads 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.
async def subscribe(self, topic: str) -> None:
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.
async def recv(self) -> Optional[MqttMessage]:
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.
async def is_connected(self) -> bool:
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.

async def disconnect(self) -> None:
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.

async def messages(self) -> AsyncIterator[MqttMessage]:
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.

class MqttMessage:

A message received from a subscribed topic.

text

The payload as text: words, or a number written out.

Raises ValueError if the payload is not UTF-8 text.

number

The payload as a number written out as text, such as 21.5.

Raises ValueError if the payload is not text or the text is not a number.

payload

The raw payload bytes.

topic

The topic the message was published to.

class MqttTls:

How a connection is secured with TLS, conventionally on port 8883.

class MqttWill:

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.

qos

The quality of service it is published at, by name.

payload

What the will publishes.

retain

Whether the broker retains it for clients that subscribe later.

topic

The topic the broker publishes it to.

class Qos(builtins.str, enum.Enum):
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.

AT_MOST_ONCE = <Qos.AT_MOST_ONCE: 'AtMostOnce'>
AT_LEAST_ONCE = <Qos.AT_LEAST_ONCE: 'AtLeastOnce'>
EXACTLY_ONCE = <Qos.EXACTLY_ONCE: 'ExactlyOnce'>