aiomqtt

raw JSON →
2.5.1 verified Tue Apr 14 auth: no python

aiomqtt is an idiomatic asyncio MQTT client for Python, providing a modern asynchronous API built on top of the paho-mqtt library. The current stable version is 2.5.1. It maintains a regular release cadence, with minor and patch releases occurring every few weeks to months, and a major version (3.0.0) currently in alpha with significant breaking changes.

pip install aiomqtt
error ModuleNotFoundError: No module named 'aiomqtt'
cause The 'aiomqtt' package is not installed in the Python environment.
fix
Install the package using pip: 'pip install aiomqtt'.
error ImportError: cannot import name 'Client' from 'aiomqtt'
cause The import statement is incorrect or the 'Client' class has been moved or renamed in the 'aiomqtt' package.
fix
Ensure the correct import statement by referring to the latest 'aiomqtt' documentation.
error AttributeError: module 'aiomqtt' has no attribute 'Client'
cause The 'Client' class does not exist in the 'aiomqtt' module, possibly due to changes in the package's API.
fix
Check the 'aiomqtt' documentation for the correct usage and available classes.
error TypeError: __init__() missing 1 required positional argument: 'loop'
cause The 'Client' class constructor requires an event loop argument that was not provided.
fix
Pass the event loop to the 'Client' constructor: 'client = aiomqtt.Client(loop=asyncio.get_event_loop())'.
error RuntimeError: This event loop is already running
cause An attempt was made to run the event loop while it is already running, which is not allowed.
fix
Use 'asyncio.create_task()' or 'await' to schedule coroutines instead of calling 'loop.run_until_complete()' within an already running loop.
breaking aiomqtt v3.0.0 introduces extensive breaking changes. It replaces the `paho-mqtt` dependency with `mqtt5`, drops support for MQTTv3.1/3.1.1, makes all `Client` parameters keyword-only, changes message types from `aiomqtt.Message` to `mqtt5.PublishPacket`, alters the `publish` payload argument from `payload=` keyword to a positional `bytes` argument, and makes `client.messages` a method (`client.messages()`).
fix Review the migration guide for v3.0.0 when upgrading. Code written for v2.x will not be compatible without significant changes.
gotcha The `client.messages` asynchronous iterator was not reusable prior to version 2.2.0. If you tried to iterate over it multiple times or in different contexts, it would only yield messages during the first iteration.
fix Upgrade to aiomqtt v2.2.0 or newer. If stuck on an older version, ensure `client.messages` is only consumed once per subscription or connection lifecycle.
deprecated Internal usage of `asyncio.get_event_loop()` was replaced with `asyncio.get_running_loop()` to align with modern asyncio best practices. While this primarily affects internal library behavior, users relying on specific event loop interactions with older Python versions or less common asyncio setups might observe subtle differences.
fix Upgrade to aiomqtt v2.3.1 or newer. For custom asyncio integrations, ensure your environment is compatible with `get_running_loop()` (Python 3.7+).
gotcha Combining `tls_params` with `tls_insecure=True` could lead to connection failures in versions prior to 2.5.1.
fix Upgrade to aiomqtt v2.5.1 or newer. If you must use `tls_insecure=True`, ensure `tls_params` are correctly configured for insecure connections, or avoid using both simultaneously if possible.

This quickstart demonstrates how to connect to an MQTT broker, subscribe to a topic, and asynchronously receive messages. It uses environment variables for host, port, and topic, falling back to defaults. Replace `MQTT_HOST` with your broker's address (e.g., `mqtt.eclipseprojects.io`).

import asyncio
import os
from aiomqtt import Client, Topic

async def main():
    mqtt_host = os.environ.get("MQTT_HOST", "localhost")
    mqtt_port = int(os.environ.get("MQTT_PORT", 1883))
    mqtt_topic = os.environ.get("MQTT_TOPIC", "test/topic")

    print(f"Connecting to mqtt://{mqtt_host}:{mqtt_port}...")
    async with Client(hostname=mqtt_host, port=mqtt_port) as client:
        await client.subscribe(Topic(mqtt_topic, qos=1))
        print(f"Subscribed to '{mqtt_topic}'. Waiting for messages...")

        async for message in client.messages:
            # For aiomqtt v2.x, message is an aiomqtt.Message object.
            # For aiomqtt v3.x+, message will be an mqtt5.PublishPacket object.
            print(f"Received message on topic '{message.topic}': {message.payload.decode()}")
            if message.payload.decode() == "exit":
                print("Received 'exit' message, shutting down.")
                break

if __name__ == "__main__":
    asyncio.run(main())