fastapi-mqtt

repository·master·Indexed 18 days ago

https://github.com/sabuhish/fastapi-mqtt

An asynchronous MQTT client for FastAPI built on top of the gmqtt module. It provides a wrapper to integrate MQTT publish/subscribe capabilities into FastAPI applications using Pydantic-based configuration (MQTTConfig) and decorators for lifecycle events such as on_connect, on_disconnect, on_subscribe, and on_message. Version 2.2.0 supports MQTT v5.0 and integrates with FastAPI's lifespan for managed startup and shutdown.

Tokens
8.1K
Snippets
30
Records
39
Agent score
62%

What's inside fastapi-mqtt

  1. What is FastApi-MQTT

    master
    FastApi-MQTT is an asynchronous MQTT client designed for use with FastAPI. It acts as a wrapper around the gmqtt Python module, providing an async implementation of the MQTT protocol. It supports the MQTT version 5.0 protocol, making it suitable for machine-to-machine (M2M) telemetry and low-bandwidth environments.
  2. Design and use MQTT topics

    master

    Topics are used by the broker to filter and distribute messages. When designing your topic structure, follow these rules:

    Topic Rules

    • Case Sensitivity: Topic names are case-sensitive.
    • Encoding: Use UTF-8.
    • Validation: A topic must consist of at least one character.
    • Structure: While topics can start with a /, it is considered bad practice. It is better to use a hierarchical structure without a leading slash (e.g., house/room1/sensor1).

    Topic Hierarchy Examples

    Valid hierarchical structures include:

    • house/room1/sensor1
    • house/room2/sensor1
    • house-room1-sensor1 (using delimiters other than /)

    Publishing Constraints

    • No Wildcards: A client can only publish to a specific, individual topic. You cannot use wildcards when publishing. To send the same message to multiple topics, you must publish the message separately for each topic.
  3. Available MQTT callback hooks in FastApi-MQTT

    master

    FastApi-MQTT provides decorator-based methods to handle specific MQTT lifecycle events and message arrivals. You can implement custom logic by defining functions and decorating them with these hooks:

    • on_connect(): Triggered when the client successfully connects to the broker.
    • on_disconnect(): Triggered when the client disconnects from the broker.
    • on_subscribe(): Triggered when a subscription is successfully established.
    • on_message(): Triggered when a new message is received on a subscribed topic.
  4. Understand MQTT core concepts and components

    master

    MQTT (Message Queuing Telemetry Transport) is a lightweight, publish/subscribe messaging protocol designed for machine-to-machine (M2M) and IoT communication. It is optimized for low bandwidth, high latency, or unreliable networks.

    Core Components

    • Broker: The central server that handles data transmission. It receives messages from publishers and distributes them to the correct subscribers based on topics.
    • Topic: A string identifier used to categorize messages. It acts as the destination for publishers and the filter for subscribers.
    • Message: The actual data payload being transmitted.
    • Publish: The action of a client sending a message to a specific topic on the broker.
    • Subscribe: The action of a client requesting to receive messages from a specific topic from the broker.

    Key Characteristics

    • Decoupled Communication: Publishers and subscribers do not connect directly; they only interact with the broker. Clients do not have addresses; they interact via topics.
    • Lightweight: Uses a minimal binary header (as small as 2 bytes) and is optimized for low power and low network usage.
    • Real-time: Designed for immediate data transmission in IoT applications.
  5. Use MQTT wildcards for topic subscriptions

    master

    When subscribing to topics, you can use wildcard characters to match multiple topics at once. Wildcards can only be used in subscriptions, not in publishing.

    Wildcard Types

    • + (Plus character): Single-level wildcard. Matches exactly one level in the hierarchy.
    • # (Hash character): Multi-level wildcard. Matches all remaining levels in the hierarchy.

    Usage Examples

    Single-level wildcard (+)

    Subscribing to house/+/main-light will match:

    • house/room1/main-light
    • house/room2/main-light
    • house/garage/main-light

    It will not match:

    • house/room1/side-light (because the last level does not match main-light)
    • house/room1/sub/main-light (because + only covers one level)

    Multi-level wildcard (#)

    Subscribing to house/# will match every topic that starts with house/, regardless of how many levels follow (e.g., house/room1, house/room1/sensor/temp, etc.).

    Invalid Wildcard Usage

    You cannot use wildcards at the end of a partial level without a separator. The following are invalid:

    • house+ (No topic level defined)
    • house# (No topic level defined)
    house/+/main-light
    house/#
  6. Configure MQTT settings with Pydantic

    master

    MQTT settings and configurations are managed using pydantic classes. This allows for structured configuration of:

    • Authentication: Providing credentials to authenticate with the MQTT broker.
    • Topic Management: Capabilities to unsubscribe from specific topics and publish messages to specific topics.
  7. Run example apps against a local broker

    master

    When running example applications or tests against a local broker (e.g., the Docker container mentioned above), set the TEST_BROKER_HOST environment variable to localhost.

    # Run the example app with uvicorn
    TEST_BROKER_HOST=localhost uvicorn examples.app:app --port 8000 --reload
    
    # Run the websocket example app
    TEST_BROKER_HOST=localhost uvicorn examples.ws_app.app:application --port 8000 --reload
    
    # Run pytest against local broker
    TEST_BROKER_HOST=localhost pytest
  8. Setup fastapi-mqtt in a FastAPI application

    master

    To use fastapi-mqtt, you need to instantiate an MQTTConfig object for your connection settings and pass it to the FastMQTT client. This client is then integrated with your FastAPI application instance.

    from fastapi import FastAPI
    from fastapi_mqtt import FastMQTT, MQTTConfig
    
    app = FastAPI()
    
    mqtt_config = MQTTConfig()
    
    mqtt = FastMQTT(
        config=mqtt_config
    )
  9. Install the development environment for fastapi-mqtt

    master

    To contribute to the project, you need to set up the development environment using poetry and pre-commit. This includes installing dependencies, activating the virtual environment, and setting up the linting hooks to ensure code quality.

    git clone https://github.com/sabuhish/fastapi-mqtt.git
    cd fastapi-mqtt
    poetry install
    # activate the poetry virtualenv
    poetry shell
    # to make changes and validate them
    pre-commit install
    pre-commit install-hooks
    pre-commit run --all-files
    # to run the test suite
    pytest
  10. Run a local Mosquitto broker with Docker for testing

    master

    To test your implementation locally, you can run a Mosquitto MQTT broker using Docker with the following command:

    docker run -d --name mosquitto -p 9001:9001 -p 1883:1883 eclipse-mosquitto:1.6.15
  11. Integrate FastMQTT with FastAPI lifespan

    master

    To ensure the MQTT client starts and shuts down correctly with your FastAPI application, use an asynccontextmanager within the FastAPI lifespan parameter. Call fast_mqtt.mqtt_startup() during startup and fast_mqtt.mqtt_shutdown() during shutdown.

    from contextlib import asynccontextmanager
    from fastapi import FastAPI
    from fastapi_mqtt import FastMQTT, MQTTConfig
    
    mqtt_config = MQTTConfig()
    fast_mqtt = FastMQTT(config=mqtt_config)
    
    @asynccontextmanager
    async def _lifespan(_app: FastAPI):
        await fast_mqtt.mqtt_startup()
        yield
        await fast_mqtt.mqtt_shutdown()
    
    app = FastAPI(lifespan=_lifespan)