Skip to content

How to Use the Paho MQTT Client in Python - MQTT Client Library Encyclopedia

by Roger Light
17 min read

What is Paho MQTT Python Client?

The Paho Python library came about because there were no Python libraries for MQTT at the time and this was a big deficiency. It was started out in 2010 as a wrapper around the mosquito C client library, but has long since been pure Python, supporting Python 2.7 and 3.x.

The library implements a client class that can be used to add MQTT support to your Python program either by creating instances of the client or through inheriting with your own class. It also provides some helper functions to make publishing one shot messages extremely easy.

Why Use Paho MQTT Python Client?

Here’re a few reasons:

  • Open Source

  • Language Compatibility

  • Support for MQTT Features

  • Asynchronous and Synchronous APIs

  • Network Resilience

Quick Overview of Paho MQTT Python Client

Arduino PubSubClient
Language Python
License EDL / EPL
API-Style Asynchronous Callbacks, Blocking
Website http://eclipse.org/paho/clients/python/

Features Supported by Paho MQTT Python Client

Feature
MQTT 3.1 Yes
MQTT 3.1.1 Yes
LWT Yes
SSL/TLS Yes
Automatic Reconnect Yes

Advanced Features: Paho MQTT Python Client

Feature
QoS 0 Yes
QoS 1 Yes
QoS 2 Yes
Authentication Yes
Throttling No

Usage of Paho MQTT Python Client

How to Install Paho MQTT Python Client?

Use the standard “pip” tool for installation, either

pip install paho-mqtt

Or

pip3 install paho-mqtt

depending on whether you are installing on Python 2 or Python 3.

How to Connect Paho MQTT Python Client with an MQTT Broker?

This section shows the API usage how to connect with the library to a MQTT broker.

There are a number of ways to connect to a broker, a simple but incomplete example is given below:

import paho.mqtt.client as paho

def on_connect(client, userdata, flags, rc):
    print('CONNACK received with code %d.' % (rc))

client = paho.Client()
client.on_connect = on_connect
client.connect('broker.mqttdashboard.com', 1883)

This creates a client instance using the default parameters, assigns a callback to be called once a successful connection has occurred, and starts the connection.

The Client() constructor has some optional parameters:

paho.Client(client_id='', clean_session=True, userdata=None, protocol=paho.MQTTv31)

If you do not specify a client_id, a random id will be generated for you (and clean_session must be set to True). The userdata parameter can be any value or datatype that you wish and the data will be passed to all callbacks as the userdata variable.

The connect() function has some optional parameters as well:

client.connect(host='localhost', port=1883, keepalive=60, bind_address=' ')

Hopefully these are all obvious with the exception of bind_address, which allows the socket to be bound to a specific address at the local side of the connection, useful if you have more than one outgoing interface.

The connect() call blocks until the socket connection is made with the broker, but is asynchronous afterwards, so once it returns you cannot be sure that the broker has accepted the connection – the on_connect() callback should be used for this purpose. A successful connection will result in the rc variable being set to 0, as in the MQTT protocol specification.

The other functions for connecting are:

connect_async(host, port=1883, keepalive=60, bind_address=' ')
connect__srv(self, domain=None, keepalive=60, bind_address=' ')

connect_async() does not block when connecting. connect_srv() attempts to use DNS SRV records for a domain to determine the broker address to connect to.

How to Connect Paho MQTT Python Client with MQTT 3.1 or MQTT 3.1.1?

To choose which protocol version to connect with, use the protocol parameter to connect():

client.connect(…, protocol=paho.MQTTv31)
client.connect(…, protocol=paho.MQTTv311)

MQTT v3.1 will be used by default, but this will change at some point in the future.

How to Connect a Paho MQTT Python Client with MQTT Broker with Last Will and Testament (LWT)?

To connect with a will, you must call will_set() before connecting to the broker:

client = paho.Client()
client.will_set(topic, payload=None, qos=0, retain=False)
client.connect('broker.mqttdashboard.com')

The payload here can be a str or bytearray.

How to Connect a Paho MQTT Python Client with MQTT Broker with Username / Password?

To connect with a username and password, call username_pw_set() before connecting:

client = paho.Client()
client.username_pw_set('username', 'password')
client.connect('broker.mqttdashboard.com')

The password is optional.

How to Stay Connected While Using Paho MQTT Python Client?

Once the client is connected, the network traffic between the client and the broker must be processed. This can be done in one of two ways, either a blocking method or with a background thread.

client.loop_forever() will block, processing the network traffic and reconnecting automatically as necessary. This function is most useful if you are only subscribing to the broker and acting on the messages you receive.

client.loop_start() starts a background thread to handle the network traffic and will return immediately. This is better suited to the situation where you wish to do other tasks in your program. It is complemented by the client.loop_stop() function, which stops the background thread.

Finally, you may also use the raw client.loop() function to process the network traffic manually. If you do this you will need to handle reconnecting yourself, it is recommended to use one of the previous two methods instead.

How to Publish Messages Using Paho MQTT Python Client?

import paho.mqtt.client as paho
import time

def on_publish(client, userdata, mid):
    print("mid: "+str(mid))
 
client = paho.Client()
client.on_publish = on_publish
client.connect('broker.mqttdashboard.com', 1883)
client.loop_start()

while True:
    temperature = read_from_imaginary_thermometer()
    (rc, mid) = client.publish('encyclopedia/temperature', str(temperature), qos=1)
    time.sleep(30)

This example shows how you might interface to a sensor and publish the data. The client is created, it sets a publish callback, connects to the broker and starts the background network thread. It then sits in a loop reading from an imaginary thermometer every 30 seconds and publishing the value to the “encyclopedia/temperature” topic. The QoS of the message can be controlled with the qos parameter. The payload in this example is “str(temperature)”, but is entirely optional. If not given, a zero length payload will be sent.

The publish() call returns a tuple of the function return code and the message id of the message being published. The message id can be used with the on_publish callback to determine when a particular message has been published. The client assigns a message id to all messages internally, even if they are QoS 0.

The version of the client currently in development offers a different (but still backwards compatible) return value from publish() which provides a better means of determining if a message has been published, as well as a way of blocking until the message has been published:

msg_info = client.publish(…)

if msg_info.is_published() == False:
    print('Message is not yet published.')

# This call will block until the message is published.

msg_info.wait_for_publish()

The next version of the client will also have the ability to specify per-message callbacks that will be called once that individual message is published, with a function call of the form:

client.publish(…, callback=on_publish_msg)

How to Publish a Retained Message While Using Paho MQTT Python Client?

To publish a retained message, simply set retain=True in the call to publish:

client.publish(…, retain=True)

How to Publish Messages Using the Utility Functions?

import paho.mqtt.publish as publish

publish.single(topic, payload=None, qos=0, retain=False, hostname="localhost",
           port=1883, client_id="", keepalive=60, will=None, auth=None,
           tls=None, protocol=mqtt.MQTTv31)

This function creates an MQTT client, connects to a broker and publishes a single message. Once the message has been delivered, it disconnects cleanly from the broker. It exposes all of the connection options present in the client, but most of them are not needed. A simple example would be:

publish.single('encyclopedia/temperature', payload='hot')

There is a full description of the the will, auth and tls parameters in the client documentation.

publish.multiple(msgs, hostname="localhost", port=1883, client_id="", keepalive=60,
             will=None, auth=None, tls=None, protocol=mqtt.MQTTv31)

This function is identical to publish.single, except that multiple messages can be published at once. The “msgs” parameter is a list of messages to publish. Each message should be a dict of the format

msg = {'topic':"<topic>", 'payload':"<payload>", 'qos':<qos>, 'retain':<retain>}

How to Subscribe to a Topic While Using Paho MQTT Python Client?

To subscribe to a topic use something like the example below:

import paho.mqtt.client as paho

def on_subscribe(client, userdata, mid, granted_qos):
    print("Subscribed: "+str(mid)+" "+str(granted_qos))

def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))    

client = paho.Client()
client.on_subscribe = on_subscribe
client.on_message = on_message
client.connect('broker.mqttdashboard.com', 1883)
client.subscribe('encyclopedia/#', qos=1)

client.loop_forever()

In this example, the on_subscribe and on_message callbacks are demonstrated. on_subscribe is called once the broker has responded to a subscription request. The granted_qos parameter contains a list of the granted QoS (or failure) codes sent by the broker. The on_message callback is called for each message received and the msg variable is an MQTTMessage class, which has members topic, payload, qos, retain and mid. The call to loop_forever() is blocking, which means the client will continue to print out incoming message information until the program is killed.

In this example, the call to client.subscribe() comes immediately after the call to client.connect(). Whilst this is valid, with a non-durable client the subscription will not be renewed if the connection to the broker drops and is renewed. It is suggested that for simple programs like this, putting the call to subscribe() in the on_connect callback will ensure that the subscription is renewed for each reconnection.

The subscribe function may be called in one of three ways:

1. Simple String and Integer

subscribe("my/topic", qos=2)

topic: A string specifying the subscription topic to subscribe to. qos: The desired quality of service level for the subscription. Defaults to 0.

2. String and integer tuple

subscribe(("my/topic", 1))

topic: A tuple of (topic, qos). Both topic and qos must be present in the tuple.

3. List of string and integer tuples

subscribe([("my/topic", 0), ("another/topic", 2)])

This allows multiple topic subscriptions in a single SUBSCRIPTION command, which is more efficient than using multiple calls to subscribe().

topic: A list of tuple of format (topic, qos). Both topic and qos must be present in all of the tuples.

Per Topic Message Callbacks

It is possible to add callbacks that respond only to messages published within a particular topic pattern. For example, you could subscribe to the topic “encyclopedia/#”, but have a message callback that would fire only for messages on the topic “encyclopedia/+/value”. This would be achieved with the following code:

client.subscribe('encyclopedia/#')
client.message_callback_add('encyclopedia/+/value', on_message_value)

where on_message_value has the same format as the message callbacks already mentioned.

How to Unsubscribe While Using Paho MQTT Python Client?

To unsubscribe, call:

client.unsubscribe(topic)

Topic is a single string, or list of strings that are the subscription topics to unsubscribe from.

The on_unsubscribe callback looks like:

on_unsubscribe(client, userdata, mid)

How to Disconnect While Using Paho MQTT Python Client?

To unsubscribe, call:

client.unsubscribe(topic)

Topic is a single string, or list of strings that are the subscription topics to unsubscribe from.

The on_unsubscribe callback looks like:

on_unsubscribe(client, userdata, mid)

Disconnect

To disconnect:

client.disconnect()

The on_disconnect callback looks like:

on_disconnect(client, userdata, rc)

The rc parameter indicates whether this disconnection was intentional (rc=0, after a call disconnect()) or for some other reason (rc=1).

Using SSL/TLS

The client supports certificate based TLS. You should call the tls_set() function to enable TLS mode and to specify the CA certificates that you trust.

client.tls_set('/path/to/ca.crt')

It is also possible to set a client certificate, the certificate verification requirements, the version of TLS to use and the allowable ciphers: tls_set(self, ca_certs, certfile=None, keyfile=None, cert_reqs=cert_reqs, tls_version=tls_version, ciphers=None)

Full details of these parameters is given in the client documentation.

Full Example Application of Paho MQTT Python Client

A complete example demonstrating both publish and subscribe, is available in the project git repository.

This example is a utility that can clear retained messages from a broker based on a subscription pattern.

Explore Other MQTT Client Libraries

Roger Light

Roger is a lecturer in the Electrical and Electronic Engineering Department at the University of Nottingham, UK. As well as developing the Paho Python client, he is also the lead and main developer of the mosquitto MQTT broker.

HiveMQ logo
Review HiveMQ on G2