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 asyncio
|
||||||
|
import sys
|
||||||
import click
|
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.config import get_settings
|
||||||
from mqtt_home.database import init_db, get_session_factory
|
from mqtt_home.database import init_db, get_session_factory
|
||||||
from mqtt_home.emqx_api import EmqxApiClient
|
from mqtt_home.emqx_api import EmqxApiClient
|
||||||
|
|||||||
@@ -18,12 +18,25 @@ class EmqxApiClient:
|
|||||||
async def get_broker_status(self) -> dict[str, Any]:
|
async def get_broker_status(self) -> dict[str, Any]:
|
||||||
resp = await self._client.get("/status")
|
resp = await self._client.get("/status")
|
||||||
resp.raise_for_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]:
|
async def get_metrics(self) -> dict[str, Any]:
|
||||||
resp = await self._client.get("/metrics")
|
resp = await self._client.get("/metrics")
|
||||||
resp.raise_for_status()
|
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]]:
|
async def get_clients(self, limit: int = 100) -> list[dict[str, Any]]:
|
||||||
resp = await self._client.get("/clients", params={"limit": limit})
|
resp = await self._client.get("/clients", params={"limit": limit})
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
from contextlib import asynccontextmanager
|
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 import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from mqtt_home.config import Settings
|
|||||||
|
|
||||||
|
|
||||||
def test_default_settings():
|
def test_default_settings():
|
||||||
s = Settings()
|
s = Settings(_env_file=None)
|
||||||
assert s.mqtt_host == "localhost"
|
assert s.mqtt_host == "localhost"
|
||||||
assert s.mqtt_port == 1883
|
assert s.mqtt_port == 1883
|
||||||
assert s.web_port == 8000
|
assert s.web_port == 8000
|
||||||
|
|||||||
Reference in New Issue
Block a user