Skip to content

Commit fcb4d7c

Browse files
committed
docs: rewrite and restructure explanation about en-/decoding payload types
1 parent 1292e62 commit fcb4d7c

File tree

6 files changed

+105
-41
lines changed

6 files changed

+105
-41
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ The documentation uses [Sphinx](https://www.sphinx-doc.org/en/master/). The sour
8282

8383
After running `git commit`, `pre-commit` will check the committed code. This check can be passed, skipped or failed.
8484

85-
If the check failed, it is possible that `pre-commit` auto-fixed the code, so you only need to re-stage and re-commit. If it did not auto-fie the code, you will need to do so manually.
85+
If the check failed, it is possible that `pre-commit` auto-fixed the code, so you only need to re-stage and re-commit. If it did not auto-fix the code, you will need to do so manually.
8686

8787
`pre-commit` will only check the code that is staged, the unstaged code will be stashed during the checks.
8888

README.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,24 @@
1515

1616
Write code like this:
1717

18-
**Subscriber**
18+
**Publisher**
1919

2020
```python
2121
async with Client("test.mosquitto.org") as client:
22-
async with client.messages() as messages:
23-
await client.subscribe("humidity/#")
24-
async for message in messages:
25-
print(message.payload)
22+
await client.publish("humidity/outside", payload=0.38)
2623
```
2724

28-
**Publisher**
25+
**Subscriber**
2926

3027
```python
3128
async with Client("test.mosquitto.org") as client:
32-
await client.publish("humidity/outside", payload=0.38)
29+
async with client.messages() as messages:
30+
await client.subscribe("humidity/#")
31+
async for message in messages:
32+
print(message.payload)
3333
```
3434

35-
_asyncio-mqtt_ combines the stability of the time-proven [paho-mqtt](https://github.com/eclipse/paho.mqtt.python) library with a modern, asyncio-based interface.
35+
asyncio-mqtt combines the stability of the time-proven [paho-mqtt](https://github.com/eclipse/paho.mqtt.python) library with a modern, asyncio-based interface.
3636

3737
- No more callbacks! 👍
3838
- No more return codes (welcome to the `MqttError`)
@@ -41,6 +41,8 @@ _asyncio-mqtt_ combines the stability of the time-proven [paho-mqtt](https://git
4141
- Fully type-hinted
4242
- Did we mention no more callbacks?
4343

44+
The whole thing is less than [900 lines of code](https://github.com/sbtinstruments/asyncio-mqtt/blob/main/asyncio_mqtt/client.py).
45+
4446
<!-- pitch end -->
4547

4648
---
@@ -53,15 +55,15 @@ _asyncio-mqtt_ combines the stability of the time-proven [paho-mqtt](https://git
5355

5456
## Installation
5557

56-
_asyncio-mqtt_ can be installed via `pip install asyncio-mqtt`. It requires Python 3.7+ to run. The only dependency is [paho-mqtt](https://github.com/eclipse/paho.mqtt.python).
58+
asyncio-mqtt can be installed via `pip install asyncio-mqtt`. It requires Python 3.7+ to run. The only dependency is [paho-mqtt](https://github.com/eclipse/paho.mqtt.python).
5759

5860
If you can't wait for the latest version and want to install directly from GitHub, use:
5961

6062
`pip install git+https://github.com/sbtinstruments/asyncio-mqtt`
6163

6264
### Note for Windows users
6365

64-
Since Python 3.8, the default asyncio event loop is the `ProactorEventLoop`. Said loop [doesn't support the `add_reader` method](https://docs.python.org/3/library/asyncio-platforms.html#windows) that is required by _asyncio-mqtt_. Please switch to an event loop that supports the `add_reader` method such as the built-in `SelectorEventLoop`:
66+
Since Python 3.8, the default asyncio event loop is the `ProactorEventLoop`. Said loop [doesn't support the `add_reader` method](https://docs.python.org/3/library/asyncio-platforms.html#windows) that is required by asyncio-mqtt. Please switch to an event loop that supports the `add_reader` method such as the built-in `SelectorEventLoop`:
6567

6668
```python
6769
# Change to the "Selector" event loop
@@ -97,11 +99,11 @@ The changelog lives in the [CHANGELOG.md](https://github.com/sbtinstruments/asyn
9799

98100
## Related projects
99101

100-
Is _asyncio-mqtt_ not what you're looking for? There are a few other clients you can try:
102+
Is asyncio-mqtt not what you're looking for? There are a few other clients you can try:
101103

102104
- [paho-mqtt](https://github.com/eclipse/paho.mqtt.python) — Own protocol implementation. Synchronous.<br>![GitHub stars](https://img.shields.io/github/stars/eclipse/paho.mqtt.python) ![license](https://img.shields.io/github/license/eclipse/paho.mqtt.python)
103105
- [gmqtt](https://github.com/wialon/gmqtt) — Own protocol implementation. Asynchronous.<br>![GitHub stars](https://img.shields.io/github/stars/wialon/gmqtt) ![license](https://img.shields.io/github/license/wialon/gmqtt)
104106
- [fastapi-mqtt](https://github.com/sabuhish/fastapi-mqtt) — Asynchronous wrapper around gmqtt. Simplifies integration in your FastAPI application.<br>![GitHub stars](https://img.shields.io/github/stars/sabuhish/fastapi-mqtt) ![license](https://img.shields.io/github/license/sabuhish/fastapi-mqtt)
105107
- [amqtt](https://github.com/Yakifo/amqtt) — Own protocol implementation. Asynchronous. Includes a broker.<br>![GitHub stars](https://img.shields.io/github/stars/Yakifo/amqtt) ![license](https://img.shields.io/github/license/Yakifo/amqtt)
106108
- [mqttools](https://github.com/eerimoq/mqttools) — Own protocol implementation. Asynchronous.<br>![GitHub stars](https://img.shields.io/github/stars/eerimoq/mqttools) ![license](https://img.shields.io/github/license/eerimoq/mqttools)
107-
- [trio-paho-mqtt](https://github.com/bkanuka/trio-paho-mqtt) — Asynchronous wrapper around paho-mqtt (similar to _asyncio-mqtt_). Based on trio instead of asyncio.<br>![GitHub stars](https://img.shields.io/github/stars/bkanuka/trio-paho-mqtt) ![license](https://img.shields.io/github/license/bkanuka/trio-paho-mqtt)
109+
- [trio-paho-mqtt](https://github.com/bkanuka/trio-paho-mqtt) — Asynchronous wrapper around paho-mqtt (similar to asyncio-mqtt). Based on trio instead of asyncio.<br>![GitHub stars](https://img.shields.io/github/stars/bkanuka/trio-paho-mqtt) ![license](https://img.shields.io/github/license/bkanuka/trio-paho-mqtt)

docs/filtering-messages.md

Lines changed: 0 additions & 26 deletions
This file was deleted.

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
:maxdepth: 2
1616
1717
configuring-the-client
18-
filtering-messages
18+
publishing-and-subscribing
1919
sharing-the-connection
2020
listening-without-blocking
2121
reconnecting

docs/publishing-and-subscribing.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Publishing and subscribing
2+
3+
Let's see a minimal working example of publishing a message:
4+
5+
```python
6+
import asyncio
7+
import asyncio_mqtt as aiomqtt
8+
9+
10+
async def main():
11+
async with aiomqtt.Client("test.mosquitto.org") as client:
12+
await client.publish("humidity/outside", payload=0.38)
13+
14+
asyncio.run(main())
15+
```
16+
17+
For subscribing and listening to messages, a minimal working example looks like this:
18+
19+
```python
20+
import asyncio
21+
import asyncio_mqtt as aiomqtt
22+
23+
24+
async def main():
25+
async with aiomqtt.Client("test.mosquitto.org") as client:
26+
async with client.messages() as messages:
27+
await client.subscribe("humidity/#")
28+
async for message in messages:
29+
print(message.payload)
30+
31+
32+
asyncio.run(main())
33+
```
34+
35+
## Payload encoding
36+
37+
Message payloads can be of types `int`, `float`, `str`, `bytes`, `bytearray`, and `None`.
38+
39+
asyncio-mqtt (or more precisely, paho-mqtt) automatically converts `int` and `float` payloads to `str`. If you want to send a true `int` or `float`, you can use [`struct.pack()`](https://docs.python.org/3/library/struct.html) to encode it as a `bytes` object.
40+
41+
If no payload is given or if it's set to `None`, a zero-length payload will be sent.
42+
43+
All other types you'll have to encode yourself. For example, if you want to send a `dict` as JSON, you can use `json.dumps()` (which returns a `str`):
44+
45+
```python
46+
import asyncio
47+
import asyncio_mqtt as aiomqtt
48+
import json
49+
50+
51+
async def main():
52+
async with aiomqtt.Client("test.mosquitto.org") as client:
53+
await client.publish("humidity/outside", payload=json.dumps({"humidity": 0.38}))
54+
55+
56+
asyncio.run(main())
57+
```
58+
59+
On the receiving end, you can then use `json.loads()` to decode the JSON string back into a `dict`.
60+
61+
## Filtering messages
62+
63+
Imagine you're measuring temperature and humidity on the outside and inside, and our topics look like this: `temperature/outside`. You want to receive all types of measurements but handle them differently.
64+
65+
asyncio-mqtt provides `Topic.matches()` to make this easy:
66+
67+
```python
68+
import asyncio
69+
import asyncio_mqtt as aiomqtt
70+
71+
72+
async def main():
73+
async with aiomqtt.Client("test.mosquitto.org") as client:
74+
async with client.messages() as messages:
75+
await client.subscribe("#")
76+
async for message in messages:
77+
if message.topic.matches("humidity/outside"):
78+
print(f"[humidity/outside] {message.payload}")
79+
if message.topic.matches("+/inside"):
80+
print(f"[+/inside] {message.payload}")
81+
if message.topic.matches("temperature/#"):
82+
print(f"[temperature/#] {message.payload}")
83+
84+
85+
asyncio.run(main())
86+
```
87+
88+
Note that in our example, messages to `temperature/inside` are handled twice!

docs/sharing-the-connection.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,4 @@ Managing a connection by calling `connect` and `disconnect` directly is a bit tr
6767

6868
Context managers take care of all connection and disconnection logic for you, in a way that makes it very difficult to shoot yourself in the foot. They are a lot easier and less error-prone to use than `connect`/`disconnect`.
6969

70-
Supporting both context managers and manual `connect`/`disconnect` would add a lot of complexity to _asyncio-mqtt_. To keep maintainer burden manageable, we focus only on the preferred option: context managers.
70+
Supporting both context managers and manual `connect`/`disconnect` would add a lot of complexity to asyncio-mqtt. To keep maintainer burden manageable, we focus only on the preferred option: context managers.

0 commit comments

Comments
 (0)