# MQTT : Clients : Paho (Python)
#### Limitations
- sessions not persisted to disk
- QoS 1-2 messages that haven't completed all stages may be lost
- if `clean_session=False`, deviates from standard:
- resends QoS 1-2 on network re-connection, which means a QoS 2 package might be received twice!
#### Imports
```python
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
import paho.mqtt.subscribe as subscribe
from paho.mqtt.enums import MQTTProtocolVersion
mqtt.Client
mqtt.CallbackAPIVersion.VERSION2
```
#### Example
```python
# Subscribing in on_connect() means subscriptions will be renewed upon reconnection.
# Other loop*() functions are available that give a threaded interface and a manual interface.
import paho.mqtt.client as mqtt
# CONNACK callback
def on_connect( client, userdata, flags, reason_code, properties ):
client.subscribe( "$SYS/#" )
# PUBLISH callback
def on_message( client, userdata, msg ):
print( msg.topic+" "+str( msg.payload ) )
mqttc = mqtt.Client( mqtt.CallbackAPIVersion.VERSION2 )
mqttc.on_connect = on_connect
mqttc.on_message = on_message
mqttc.connect( "mqtt.eclipseprojects.io", 1883, 60 )
mqttc.loop_forever()
```
#### Client API
```python
connect( "DOMAIN", PORT, ?timeout? )
...
subscribe( "TOPIC" )
publish( ... )
loop() # low-level; you have to handle re-connects
loop_start()
loop_stop()
loop_forever()
retry_first_connection = False
disconnect()
# callbacks
on_connect
on_connect_fail
on_disconnect
on_message
on_publish
on_subscribe
on_unsubscribe
on_log when the library logs a message
user_data_set( [] )
enable_logger()
```
#### Loops
There are four options for managing the network loop — these three plus using an external event loop.
> [!WARNING]
> Do not mix the different loop functions.
**loop_start/stop**
```python
mqttc.loop_start()
while True:
mqttc.publish( "paho/temperature", temperature )
mqttc.loop_stop()
```
These functions implement a threaded interface to the network loop.
Calling `loop_start()` once, before or after `connect*()`, runs a thread in the background to call `loop()` automatically. This call also handles reconnecting to the broker.
Call `loop_stop()` to stop the background thread. The loop is also stopped if you call `disconnect()`.
**loop_forever**
This is a blocking form of the network loop and will not return until the client calls `disconnect()`. It automatically handles reconnecting.
#### Callbacks
```python
on_connect( client, userdata, flags, reason_code, properties )
on_subscribe( client, userdata, mid, reason_code_list, properties )
on_unsubscribe( client, userdata, mid, reason_code_list, properties )
on_message( client, userdata, message )
on_publish( client, userdata, mid, reason_code, properties )
on_log( client, userdata, paho_log_level, messages )
```
#### Publishing
```python
msg_info = mqttc.publish( "paho/test/topic", "my message", qos=1 )
msg_info.mid
```
#### Simplified API — Subscribing
Subscribe to a set of topics and return the messages received. (This is a blocking function.)
```python
msg = subscribe.simple( "paho/test/topic", hostname="mqtt.eclipseprojects.io" )
msg.topic
msg.payload
```
Subscribe to a set of topics and process the messages received using a user provided callback.
```python
def on_message_print( client, userdata, message ):
print( "%s %s" % ( message.topic, message.payload ) )
userdata[ "message_count" ] += 1
if userdata[ "message_count" ] >= 5:
# it's possible to stop the program by disconnecting
client.disconnect()
subscribe.callback(
on_message_print,
"paho/test/topic",
hostname="mqtt.eclipseprojects.io",
userdata={ "message_count": 0 }
)
```