Of course! Setting up an MQTT server (also known as an MQTT broker) in Python is a great way to learn the protocol or create a lightweight, custom messaging solution.

While there are many excellent, production-ready MQTT brokers written in other languages (like Mosquitto, EMQX, or HiveMQ), you can also create one directly in Python using libraries.
This guide will cover two main approaches:
- The Easy Way: Using a pre-existing Python library to create a simple, self-contained broker. This is perfect for learning, testing, and small projects.
- The Production-Ready Way: Using a robust, standalone broker like Mosquitto and writing a Python client to interact with it. This is the recommended approach for any real-world application.
Approach 1: Creating a Simple MQTT Broker in Python
We'll use the paho-mqtt library, which is the de-facto standard for MQTT in Python. Interestingly, while it's famous for its client, it also includes a basic broker implementation.
Step 1: Install the Library
First, you need to install paho-mqtt. Open your terminal or command prompt and run:

pip install paho-mqtt
Step 2: Write the Broker Code
Create a new Python file, for example, simple_broker.py, and paste the following code. This code will start a broker that listens on port 1883 (the default MQTT port).
# simple_broker.py
import paho.mqtt.client as mqtt
import time
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Broker Connected Successfully!")
else:
print(f"Failed to connect, return code {rc}\n")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
# --- Broker Configuration ---
broker_address = "localhost" # Or "0.0.0.0" to listen on all available interfaces
broker_port = 1883
# Create a new instance of the Client
# We are using the broker functionality of the paho-mqtt library
broker = mqtt.Client("python_broker", clean_session=False, userdata=None)
# Assign callback functions
broker.on_connect = on_connect
broker.on_message = on_message
# Set username and password for authentication (optional)
# broker.username_pw_set("your_username", "your_password")
# Start the broker
# The `start_loop()` method starts a new thread to handle network traffic
print(f"Starting MQTT Broker on {broker_address}:{broker_port}...")
try:
broker.connect(broker_address, broker_port, 60)
broker.loop_start() # Start the network loop in a separate thread
# Keep the main thread alive
while True:
time.sleep(1)
except KeyboardInterrupt:
print("Broker stopped by user.")
broker.loop_stop() # Stop the network loop
broker.disconnect() # Disconnect the broker
Step 3: Run the Broker
Open your terminal, navigate to the directory where you saved the file, and run it:
python simple_broker.py
You should see the output: Starting MQTT Broker on localhost:1883... and then Broker Connected Successfully!. The broker is now running and waiting for clients to connect. It will keep running until you press Ctrl+C.
Approach 2: The Production-Ready Way (Using Mosquitto)
For any serious application, you should use a dedicated, high-performance broker like Eclipse Mosquitto. It's lightweight, open-source, and extremely stable. Your Python application will then act as a client to this broker.
Step 1: Install the Mosquitto Broker
The installation process depends on your operating system.
On Ubuntu/Debian:
sudo apt-get update sudo apt-get install mosquitto mosquitto-clients
On macOS (using Homebrew):
brew install mosquitto
On Windows: Download the installer from the official Mosquitto website.
Step 2: Start the Mosquitto Broker
After installation, you can start the broker. It will typically run as a system service (daemon).
To start it manually for testing:
mosquitto -v
The -v flag gives you verbose output, so you can see all the messages being passed. You can stop it by pressing Ctrl+C.
Step 3: Write a Python Publisher and Subscriber
Now, let's create two Python scripts: one to publish messages (a publisher) and one to subscribe to them (a subscriber).
The Publisher (publisher.py)
# publisher.py
import paho.mqtt.client as mqtt
import time
# MQTT Broker Configuration
broker_address = "localhost"
broker_port = 1883
topic = "test/python"
# The callback for when the client connects to the broker
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Publisher Connected to Broker!")
else:
print(f"Failed to connect, return code {rc}\n")
# Create a new client instance
client = mqtt.Client("python_publisher")
# Assign the callback function
client.on_connect = on_connect
# Connect to the broker
print(f"Connecting to broker {broker_address}:{broker_port}...")
client.connect(broker_address, broker_port)
# Loop once to establish the connection and call on_connect
client.loop_start()
try:
# Publish messages every 2 seconds
while True:
message = f"Message from Python Publisher at {time.time()}"
print(f"Publishing message: '{message}' to topic '{topic}'")
client.publish(topic, message)
time.sleep(2)
except KeyboardInterrupt:
print("Publisher stopped.")
client.loop_stop()
client.disconnect()
The Subscriber (subscriber.py)
# subscriber.py
import paho.mqtt.client as mqtt
# MQTT Broker Configuration
broker_address = "localhost"
broker_port = 1883
topic = "test/python"
# The callback for when a message is received from the broker
def on_message(client, userdata, msg):
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
# The callback for when the client connects to the broker
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Subscriber Connected to Broker!")
# Subscribe to the topic when connected
print(f"Subscribing to topic: {topic}")
client.subscribe(topic)
else:
print(f"Failed to connect, return code {rc}\n")
# Create a new client instance
client = mqtt.Client("python_subscriber")
# Assign the callback functions
client.on_connect = on_connect
client.on_message = on_message
# Connect to the broker
print(f"Connecting to broker {broker_address}:{broker_port}...")
client.connect(broker_address, broker_port)
# Start the network loop in a separate thread to process incoming messages
# This will block the main thread, so it's perfect for a subscriber
client.loop_forever()
Step 4: Run the Scripts
-
Start the Mosquitto broker in one terminal window:
mosquitto -v
-
Run the subscriber in a second terminal window:
python subscriber.py
You should see it connect and subscribe to the topic.
-
Run the publisher in a third terminal window:
python publisher.py
You will see the publisher sending messages every 2 seconds, and the subscriber will instantly print them out as they arrive. This demonstrates the core publish/subscribe model of MQTT.
Summary: Which Approach to Choose?
| Feature | Python Library Broker (Approach 1) | Dedicated Broker (Approach 2) |
|---|---|---|
| Ease of Use | Very Easy. One dependency, one script. | Easy to install, but requires a separate service. |
| Performance | Low. Not designed for high throughput or many clients. | High. Optimized for performance and scalability. |
| Reliability | Low. A simple Python script can crash. | High. Robust, battle-tested, and designed for 24/7 operation. |
| Features | Basic. Lacks many advanced features. | Extensive. Supports persistent sessions, ACLs, WebSockets, etc. |
| Best For | Learning, simple prototypes, quick tests, small IoT projects. | All production applications, large-scale IoT, systems requiring high availability. |
Recommendation: Always use a dedicated broker like Mosquitto for anything beyond a simple learning exercise. The Python library's broker is a fantastic tool for understanding the protocol's mechanics but lacks the stability and features needed for a real-world system.
