fix: Windows event loop compatibility, EMQX API response handling, and test fix
- Add WindowsSelectorEventLoopPolicy for paho-mqtt on Windows - Handle EMQX /status plain text and /metrics list responses - Fix test_default_settings to ignore .env file - Add __main__.py for python -m mqtt_home support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
3
src/mqtt_home/__main__.py
Normal file
3
src/mqtt_home/__main__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from mqtt_home.cli import cli
|
||||
|
||||
cli()
|
||||
@@ -1,6 +1,11 @@
|
||||
import asyncio
|
||||
import sys
|
||||
import click
|
||||
|
||||
# Windows compatibility: use SelectorEventLoop for paho-mqtt
|
||||
if sys.platform == "win32":
|
||||
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||
|
||||
from mqtt_home.config import get_settings
|
||||
from mqtt_home.database import init_db, get_session_factory
|
||||
from mqtt_home.emqx_api import EmqxApiClient
|
||||
|
||||
@@ -18,12 +18,25 @@ class EmqxApiClient:
|
||||
async def get_broker_status(self) -> dict[str, Any]:
|
||||
resp = await self._client.get("/status")
|
||||
resp.raise_for_status()
|
||||
return resp.json().get("data", {})
|
||||
# /status may return plain text, try JSON first
|
||||
try:
|
||||
data = resp.json()
|
||||
if isinstance(data, dict) and "data" in data:
|
||||
return data["data"]
|
||||
return data if isinstance(data, dict) else {"raw": resp.text}
|
||||
except Exception:
|
||||
return {"raw": resp.text}
|
||||
|
||||
async def get_metrics(self) -> dict[str, Any]:
|
||||
resp = await self._client.get("/metrics")
|
||||
resp.raise_for_status()
|
||||
return resp.json().get("data", {})
|
||||
data = resp.json()
|
||||
# /metrics returns a list in some EMQX versions
|
||||
if isinstance(data, list) and data:
|
||||
return data[0] if isinstance(data[0], dict) else {}
|
||||
if isinstance(data, dict) and "data" in data:
|
||||
return data["data"] if isinstance(data["data"], dict) else {}
|
||||
return data if isinstance(data, dict) else {}
|
||||
|
||||
async def get_clients(self, limit: int = 100) -> list[dict[str, Any]]:
|
||||
resp = await self._client.get("/clients", params={"limit": limit})
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import sys
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
# Windows compatibility: use SelectorEventLoop for paho-mqtt (add_reader/add_writer)
|
||||
if sys.platform == "win32":
|
||||
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ from mqtt_home.config import Settings
|
||||
|
||||
|
||||
def test_default_settings():
|
||||
s = Settings()
|
||||
s = Settings(_env_file=None)
|
||||
assert s.mqtt_host == "localhost"
|
||||
assert s.mqtt_port == 1883
|
||||
assert s.web_port == 8000
|
||||
|
||||
Reference in New Issue
Block a user