Skip to content

Migrate paho-mqtt client to CallbackAPIVersion.VERSION2 - #78

Merged
stackia merged 5 commits into
mainfrom
cursor/paho-mqtt-callback-api-v2-f689
Sep 2, 2026
Merged

Migrate paho-mqtt client to CallbackAPIVersion.VERSION2#78
stackia merged 5 commits into
mainfrom
cursor/paho-mqtt-callback-api-v2-f689

Conversation

@stackia

@stackia stackia commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

Migrate the MQTT client off paho-mqtt's deprecated Callback API v1.

mqtt.Client() without a callback API version is deprecated in paho-mqtt 2.x (Callback API version 1 is deprecated, update to latest version). This change constructs the client with mqtt.CallbackAPIVersion.VERSION2 and updates on_connect / on_disconnect to the v2 signatures from the paho-mqtt migration guide.

on_message is unchanged (same signature in v1 and v2).

The project already requires paho-mqtt>=2.1.0,<3, so no 1.6 compatibility shim or dependency bump is needed.

Changes

  • src/libdeye/mqtt_client.py: mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
  • on_connect(client, userdata, connect_flags, reason_code, properties)
  • on_disconnect(client, userdata, disconnect_flags, reason_code, properties) — still treats reason_code == 0 as a user-initiated disconnect
  • tests/test_mqtt_client.py: callback tests use the VERSION2 arity with ConnectFlags / DisconnectFlags / ReasonCode
  • Changelog note under Unreleased

Test plan

  • uv run pytest — 163 passed (Python 3.14.7, paho-mqtt 2.1.0)
  • uv run pytest tests/test_mqtt_client.py — 46 passed, including v2 on_connect / on_disconnect arities
  • uv run mypy src/libdeye/mqtt_client.py tests/test_mqtt_client.py
  • uv run pylint src/libdeye/mqtt_client.py tests/test_mqtt_client.py
  • uv run pre-commit run --files on the touched files
  • Confirmed mqtt.Client() emits the v1 DeprecationWarning and mqtt.Client(CallbackAPIVersion.VERSION2) does not

Test evidence

mqtt.Client() (Callback API v1, deprecated):
  DeprecationWarning: Callback API version 1 is deprecated, update to latest version

mqtt.Client(mqtt.CallbackAPIVersion.VERSION2):
  no DeprecationWarning

constructed client callback_api_version=<CallbackAPIVersion.VERSION2: 2>
  • Full suite: /opt/cursor/artifacts/pytest_full.log — 163 passed
  • MQTT tests: /opt/cursor/artifacts/pytest_mqtt_client.log — 46 passed
  • Deprecation check: /opt/cursor/artifacts/paho_callback_api_version.log

Note

Low Risk
API-signature migration with preserved disconnect/reconnect semantics; no dependency or protocol changes beyond silencing paho-mqtt v1 callback deprecation.

Overview
Moves the Deye MQTT stack onto paho-mqtt 2.x Callback API v2, removing the deprecated default mqtt.Client() construction and the associated runtime deprecation warning.

BaseDeyeMqttClient now builds the client with mqtt.CallbackAPIVersion.VERSION2 and rewrites _mqtt_on_connect and _mqtt_on_disconnect to the v2 arity (connect_flags / disconnect_flags, ReasonCode, optional Properties). Reconnect behavior is unchanged: reason_code == 0 still skips the MQTT info refresh on a user-initiated disconnect; unexpected disconnects still schedule _set_mqtt_info before paho’s default reconnect. _mqtt_on_message only loosens userdata typing to Any.

Unit tests invoke the callbacks with ConnectFlags, DisconnectFlags, and ReasonCode; the unreleased changelog documents the migration.

Reviewed by Cursor Bugbot for commit 18a8641. Configure here.

Construct mqtt.Client with the non-deprecated v2 callback API and update
on_connect / on_disconnect to the VERSION2 signatures. Tests now invoke
those callbacks with the v2 arity.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.83%. Comparing base (712cdc8) to head (18a8641).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #78   +/-   ##
=======================================
  Coverage   95.83%   95.83%           
=======================================
  Files           8        8           
  Lines        1081     1081           
  Branches      153      153           
=======================================
  Hits         1036     1036           
  Misses         21       21           
  Partials       24       24           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

ConnectFlags/DisconnectFlags require their namedtuple fields, and mypy
expects ReasonCode rather than a bare int for the v2 callback arity.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
@stackia
stackia marked this pull request as ready for review September 2, 2026 10:52
@stackia
stackia requested a lite review from Copilot September 2, 2026 10:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The migration is mechanical, matches the stated paho-mqtt v2 signatures, and is covered by updated unit tests, with only minor typing-nit adjustments suggested.

Pull request overview

This PR migrates libdeye’s MQTT client lifecycle callbacks to paho-mqtt Callback API v2 to avoid the deprecated default callback API v1 behavior in paho-mqtt 2.x.

Changes:

  • Construct the MQTT client with CallbackAPIVersion.VERSION2.
  • Update _mqtt_on_connect / _mqtt_on_disconnect to the v2 callback signatures and adjust disconnect logic to use reason_code.
  • Update unit tests to call the callbacks with the v2 arity/types; add an Unreleased changelog entry.
File summaries
File Description
src/libdeye/mqtt_client.py Switch client construction to Callback API v2 and update connect/disconnect callback signatures.
tests/test_mqtt_client.py Update callback tests to use v2 argument shapes (ConnectFlags/DisconnectFlags/ReasonCode).
CHANGELOG.rst Document the Callback API v2 migration under Unreleased.
Review details

Suppressed comments (1)

src/libdeye/mqtt_client.py:440

  • Same as _mqtt_on_connect: userdata in paho-mqtt callbacks is not necessarily None (it can be any object supplied via user_data_set()), so the None annotation is too restrictive here.
        _userdata: None,
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/libdeye/mqtt_client.py Outdated
cursoragent and others added 3 commits September 2, 2026 11:04
paho-mqtt v2 callbacks receive arbitrary userdata. The JSONDecodeError
handler used invalid Python 2 except syntax and could not import.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
Co-authored-by: Stackie Jia <jsq2627@gmail.com>
Python 3.14 (required by this package) allows except E1, E2 without
parentheses. ruff-format with target-version py314 rewrites the
parenthesized form, which failed CI.

Co-authored-by: Stackie Jia <jsq2627@gmail.com>
@stackia
stackia requested a lite review from Copilot September 2, 2026 11:09
@stackia

stackia commented Sep 2, 2026

Copy link
Copy Markdown
Owner Author

cursor review

@cursor

cursor Bot commented Sep 2, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_aafee526-c121-4460-bf19-d8e3d7d568d8)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

A small regression-test gap remains: tests don’t currently assert that the client is constructed with Callback API v2, which is critical to ensuring runtime callback arity matches the new handlers.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/libdeye/mqtt_client.py:394

  • The runtime safety of the v2 callback signatures depends on constructing the client with Callback API v2. Current tests invoke _mqtt_on_connect / _mqtt_on_disconnect directly, so they would still pass even if the constructor accidentally regressed to the v1 default (which would then cause paho-mqtt to call these callbacks with the wrong arity at runtime). Consider adding a unit test assertion that mqtt.Client is constructed with mqtt.CallbackAPIVersion.VERSION2 to prevent silent regression.
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@stackia
stackia merged commit 508c1c9 into main Sep 2, 2026
6 checks passed
@stackia
stackia deleted the cursor/paho-mqtt-callback-api-v2-f689 branch September 2, 2026 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants