mqttwrapper
===========
A little glue package to make it simple to quickly put together scripts that
bridge MQTT and other libraries. See examples below.
Installation
------------
Install from PyPI::
$ pip install mqttwrapper
By default ``paho-mqtt`` will be used as the MQTT library, but you can use
``hbmqtt`` if you wish, though support for this is deprecated and will be
removed in the future. To install, use::
$ pip install mqttwrapper[hbmqtt]
Usage
-----
``mqttwrapper.run_script`` handles the setup/maintenance of the MQTT connection
and subscriptions to topics, and calls a callback function when messages are
received. It can run in blocking mode where it will take care of the MQTT
client handling or in non blocking mode where a new thread takes care this
leaving your main thread free for other things.
The simplest script looks something like this::
from mqttwrapper import run_script
def callback(topic, payload):
print("Received payload {} on topic {}".format(payload, topic))
def main():
run_script(callback, broker="mqtt://127.0.0.1", topics=["my/awesome/topic1", "another/awesome/topic2"])
or in non blocking mode::
def main():
run_script(callback, broker="mqtt://127.0.0.1", topics=["my/awesome/topic1", "another/awesome/topic2"], blocking=False)
while True:
echo "Alive and kicking"
time.sleep(1)
Any extra keyword arguments passed to ``run_script`` are passed back to the
callback function when it's called::
from mqttwrapper import run_script
def callback(topic, payload, context, foo):
assert context == "hello"
assert foo == "bar"
print("Received payload {} on topic {}".format(payload, topic))
def main():
run_script(callback, broker="mqtt://127.0.0.1", topics=["my/awesome/topic1", "another/awesome/topic2"], context="hello", foo="bar")
If you don't need any context passed to your callback, just the topic and
payload of messages, you can run in 'importless' mode by creating a `callback`
module which has a `callback` function defined, then execute the
`mqttwrapper.run` module::
$ cat callback.py
def callback(topic, payload):
print(topic, payload)
$ python -m mqttwrapper.run
Retained messages
-----------------
You can ignore MQTT retained messages by passing ``ignore_retained=True`` when
calling ``run_script``. NB this is currently not supported by the hbmqtt
backend.
Publishing messages from the callback
-------------------------------------
Sometimes your callback function might want to publish its own MQTT messages,
perhaps in reply to or an acknowledgement of a received message. This is
possible by returning an iterable of ``(topic, payload)`` tuples from the callback,
e.g.::
def callback(topic, payload):
print("Received payload {} on topic {}".format(payload, topic))
return [
("{}/ack".format(topic), payload)
]
``mqttwrapper`` will take care of publishing these messages to the broker.
These tuples can optionally take the form ``(topic, payload, True)`` if you want
the published message to be marked as retained.
Configuration
-------------
``broker`` and ``topics`` can be omitted from the ``run_script`` call and
environment variables used instead:
- ``MQTT_BROKER``: MQTT broker to connect to, e.g. ``mqtt://127.0.0.1/``
- ``MQTT_TOPICS``: Comma-separated list of topics to subscribe to, e.g. ``my/topic1,my/topic2``
asyncio/hbmqtt
--------------
NB This feature is deprecated and will be removed in the future.
The asyncio-powered ``hbmqtt`` MQTT library can be used instead, if you like::
from mqttwrapper.hbmqtt_backend import run_script
async def callback(topic, payload):
print("Received payload {} on topic {}".format(payload, topic))
Note that your callback must be an awaitable in this case.
Your callback may require context arguments which themselves are async objects
or awaitables which poses a challenge: how to set these up outside of an asyncio
event loop before calling ``run_script``? In this case, you can pass a
``context_callback`` awaitable as a kwarg to ``run_script``. This is run at the
start of the MQTT loop, and should return a dict which will be merged into the
kwargs which are passed to your callback. For example::
from mqttwrapper.hbmqtt_backend import run_script
async def setup_db():
return {
"query_db": query_db
}
async def query_db(value):
# pretend this is some slow DB query, for example.
await asyncio.sleep(3)
return value * 2
async def callback(topic, payload, query_db):
db_result = await query_db(int(payload))
print("Received payload {} on topic {}, db result: {}".format(payload, topic, db_result))
def main():
run_script(callback, context_callback=setup_db)
NB hbmqtt's reconnection handling does not resubscribe to topics upon
reconnection, and ``mqttwrapper`` does not yet work around this.
Examples
--------
- rxv2mqtt_
- tradfri-mqtt_ (uses asyncio)
.. _rxv2mqtt: https://github.com/davea/rxv2mqtt/blob/master/main.py
.. _tradfri-mqtt: https://github.com/davea/tradfri-mqtt/blob/master/main.py
Raw data
{
"_id": null,
"home_page": "https://github.com/davea/mqttwrapper",
"name": "mqttwrapper",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "mqtt",
"author": "Dave Arter",
"author_email": "pypi@davea.me",
"download_url": "https://files.pythonhosted.org/packages/11/33/d4116b38bf38b939880b3408e74e41467d5c4dfb25f8ab480090bf2dc192/mqttwrapper-0.1.0.tar.gz",
"platform": null,
"description": "mqttwrapper\n===========\n\nA little glue package to make it simple to quickly put together scripts that\nbridge MQTT and other libraries. See examples below.\n\nInstallation\n------------\n\nInstall from PyPI::\n\n $ pip install mqttwrapper\n\nBy default ``paho-mqtt`` will be used as the MQTT library, but you can use\n``hbmqtt`` if you wish, though support for this is deprecated and will be\nremoved in the future. To install, use::\n\n $ pip install mqttwrapper[hbmqtt]\n\nUsage\n-----\n\n``mqttwrapper.run_script`` handles the setup/maintenance of the MQTT connection\nand subscriptions to topics, and calls a callback function when messages are\nreceived. It can run in blocking mode where it will take care of the MQTT\nclient handling or in non blocking mode where a new thread takes care this\nleaving your main thread free for other things.\n\nThe simplest script looks something like this::\n\n from mqttwrapper import run_script\n\n def callback(topic, payload):\n print(\"Received payload {} on topic {}\".format(payload, topic))\n\n def main():\n run_script(callback, broker=\"mqtt://127.0.0.1\", topics=[\"my/awesome/topic1\", \"another/awesome/topic2\"])\n\nor in non blocking mode::\n\n def main():\n run_script(callback, broker=\"mqtt://127.0.0.1\", topics=[\"my/awesome/topic1\", \"another/awesome/topic2\"], blocking=False)\n while True:\n echo \"Alive and kicking\"\n time.sleep(1)\n\nAny extra keyword arguments passed to ``run_script`` are passed back to the\ncallback function when it's called::\n\n from mqttwrapper import run_script\n\n def callback(topic, payload, context, foo):\n assert context == \"hello\"\n assert foo == \"bar\"\n print(\"Received payload {} on topic {}\".format(payload, topic))\n\n def main():\n run_script(callback, broker=\"mqtt://127.0.0.1\", topics=[\"my/awesome/topic1\", \"another/awesome/topic2\"], context=\"hello\", foo=\"bar\")\n\n\nIf you don't need any context passed to your callback, just the topic and\npayload of messages, you can run in 'importless' mode by creating a `callback`\nmodule which has a `callback` function defined, then execute the\n`mqttwrapper.run` module::\n\n $ cat callback.py\n def callback(topic, payload):\n print(topic, payload)\n \n $ python -m mqttwrapper.run\n\nRetained messages\n-----------------\n\nYou can ignore MQTT retained messages by passing ``ignore_retained=True`` when\ncalling ``run_script``. NB this is currently not supported by the hbmqtt\nbackend.\n\nPublishing messages from the callback\n-------------------------------------\n\nSometimes your callback function might want to publish its own MQTT messages,\nperhaps in reply to or an acknowledgement of a received message. This is\npossible by returning an iterable of ``(topic, payload)`` tuples from the callback,\ne.g.::\n\n def callback(topic, payload):\n print(\"Received payload {} on topic {}\".format(payload, topic))\n return [\n (\"{}/ack\".format(topic), payload)\n ]\n\n\n``mqttwrapper`` will take care of publishing these messages to the broker.\n\nThese tuples can optionally take the form ``(topic, payload, True)`` if you want\nthe published message to be marked as retained.\n\nConfiguration\n-------------\n\n``broker`` and ``topics`` can be omitted from the ``run_script`` call and\nenvironment variables used instead:\n\n- ``MQTT_BROKER``: MQTT broker to connect to, e.g. ``mqtt://127.0.0.1/``\n- ``MQTT_TOPICS``: Comma-separated list of topics to subscribe to, e.g. ``my/topic1,my/topic2``\n\nasyncio/hbmqtt\n--------------\n\nNB This feature is deprecated and will be removed in the future.\n\nThe asyncio-powered ``hbmqtt`` MQTT library can be used instead, if you like::\n\n from mqttwrapper.hbmqtt_backend import run_script\n\n async def callback(topic, payload):\n print(\"Received payload {} on topic {}\".format(payload, topic))\n\n\nNote that your callback must be an awaitable in this case.\n\nYour callback may require context arguments which themselves are async objects\nor awaitables which poses a challenge: how to set these up outside of an asyncio\nevent loop before calling ``run_script``? In this case, you can pass a\n``context_callback`` awaitable as a kwarg to ``run_script``. This is run at the\nstart of the MQTT loop, and should return a dict which will be merged into the\nkwargs which are passed to your callback. For example::\n\n from mqttwrapper.hbmqtt_backend import run_script\n\n async def setup_db():\n return {\n \"query_db\": query_db\n }\n\n async def query_db(value):\n # pretend this is some slow DB query, for example.\n await asyncio.sleep(3)\n return value * 2\n\n async def callback(topic, payload, query_db):\n db_result = await query_db(int(payload))\n print(\"Received payload {} on topic {}, db result: {}\".format(payload, topic, db_result))\n\n def main():\n run_script(callback, context_callback=setup_db)\n\n\nNB hbmqtt's reconnection handling does not resubscribe to topics upon\nreconnection, and ``mqttwrapper`` does not yet work around this.\n\nExamples\n--------\n\n- rxv2mqtt_\n- tradfri-mqtt_ (uses asyncio)\n\n.. _rxv2mqtt: https://github.com/davea/rxv2mqtt/blob/master/main.py\n.. _tradfri-mqtt: https://github.com/davea/tradfri-mqtt/blob/master/main.py\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "MQTT utility scripts made easy",
"version": "0.1.0",
"project_urls": {
"Homepage": "https://github.com/davea/mqttwrapper"
},
"split_keywords": [
"mqtt"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e93828fc1bf6a42123d177ffe3290a352842dc1b676abdb92e9d900bc860fddf",
"md5": "215fb11c35dd09dd1c15548fdf8cf8c4",
"sha256": "5960f48e820cc5ef8153fc4b1f72164d2ef75d561efbde0ddafae59968f3fd16"
},
"downloads": -1,
"filename": "mqttwrapper-0.1.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "215fb11c35dd09dd1c15548fdf8cf8c4",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 8346,
"upload_time": "2024-03-02T15:04:19",
"upload_time_iso_8601": "2024-03-02T15:04:19.552121Z",
"url": "https://files.pythonhosted.org/packages/e9/38/28fc1bf6a42123d177ffe3290a352842dc1b676abdb92e9d900bc860fddf/mqttwrapper-0.1.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1133d4116b38bf38b939880b3408e74e41467d5c4dfb25f8ab480090bf2dc192",
"md5": "50cfb90794db9b06e1eb44d98b63db78",
"sha256": "3290dd20b7dbac1ede78089ce3d7db4d34a94b37e86a372992ceef59952e4677"
},
"downloads": -1,
"filename": "mqttwrapper-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "50cfb90794db9b06e1eb44d98b63db78",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 5558,
"upload_time": "2024-03-02T15:04:21",
"upload_time_iso_8601": "2024-03-02T15:04:21.277277Z",
"url": "https://files.pythonhosted.org/packages/11/33/d4116b38bf38b939880b3408e74e41467d5c4dfb25f8ab480090bf2dc192/mqttwrapper-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-03-02 15:04:21",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "davea",
"github_project": "mqttwrapper",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "mqttwrapper"
}