8000 Allow enabling experimental devices from environment variable (#1194) · python-kasa/python-kasa@4aec9d3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4aec9d3

Browse files
authored
Allow enabling experimental devices from environment variable (#1194)
1 parent d30d116 commit 4aec9d3

File tree

6 files changed

+75
-22
lines changed

6 files changed

+75
-22
lines changed

devtools/dump_devinfo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,9 @@ async def cli(
309309
if debug:
310310
logging.basicConfig(level=logging.DEBUG)
311311

312-
from kasa.experimental.enabled import Enabled
312+
from kasa.experimental import Experimental
313313

314-
Enabled.set(True)
314+
Experimental.set_enabled(True)
315315

316316
credentials = Credentials(username=username, password=password)
317317
if host is not None:

kasa/cli/main.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from kasa import Device
1717

1818
from kasa.deviceconfig import DeviceEncryptionType
19+
from kasa.experimental import Experimental
1920

2021
from .common import (
2122
SKIP_UPDATE_COMMANDS,
@@ -220,11 +221,11 @@ def _legacy_type_to_class(_type):
220221
help="Hashed credentials used to authenticate to the device.",
221222
)
222223
@click.option(
223-
"--experimental",
224-
default=False,
224+
"--experimental/--no-experimental",
225+
default=None,
225226
is_flag=True,
226227
type=bool,
227-
envvar="KASA_EXPERIMENTAL",
228+
envvar=Experimental.ENV_VAR,
228229
help="Enable experimental mode for devices not yet fully supported.",
229230
)
230231
@click.version_option(package_name="python-kasa")
@@ -260,10 +261,11 @@ async def cli(
260261
if target != DEFAULT_TARGET and host:
261262
error("--target is not a valid option for single host discovery")
262263

263-
if experimental:
264-
from kasa.experimental.enabled import Enabled
264+
if experimental is not None:
265+
Experimental.set_enabled(experimental)
265266

266-
Enabled.set(True)
267+
if Experimental.enabled():
268+
echo("Experimental support is enabled")
267269

268270
logging_config: dict[str, Any] = {
269271
"level": logging.DEBUG if debug > 0 else logging.INFO

kasa/device_factory.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,9 @@ def get_protocol(
214214
"SMART.KLAP": (SmartProtocol, KlapTransportV2),
215215
}
216216
if not (prot_tran_cls := supported_device_protocols.get(protocol_transport_key)):
217-
from .experimental.enabled import Enabled
217+
from .experimental import Experimental
218218

219-
if Enabled.value and protocol_transport_key == "SMART.AES.HTTPS":
219+
if Experimental.enabled() and protocol_transport_key == "SMART.AES.HTTPS":
220220
prot_tran_cls = (SmartCameraProtocol, SslAesTransport)
221221
else:
222222
return None

kasa/experimental/__init__.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,28 @@
11
"""Package for experimental."""
2+
3+
from __future__ import annotations
4+
5+
import os
6+
7+
8+
class Experimental:
9+
"""Class for enabling experimental functionality."""
10+
11+
_enabled: bool | None = None
12+
ENV_VAR = "KASA_EXPERIMENTAL"
13+
14+
@classmethod
15+
def set_enabled(cls, enabled):
16+
"""Set the enabled value."""
17+
cls._enabled = enabled
18+
19+
@classmethod
20+
def enabled(cls):
21+
"""Get the enabled value."""
22+
if cls._enabled is not None:
23+
return cls._enabled
24+
25+
if env_var := os.getenv(cls.ENV_VAR):
26+
return env_var.lower() in {"true", "1", "t", "on"}
27+
28+
return False

kasa/experimental/enabled.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

kasa/tests/test_cli.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,3 +1232,39 @@ async def test_discover_config_invalid(mocker, runner):
12321232
)
12331233
assert res.exit_code == 1
12341234
assert "--target is not a valid option for single host discovery" in res.output
1235+
1236+
1237+
@pytest.mark.parametrize(
1238+
("option", "env_var_value", "expectation"),
1239+
[
1240+
pytest.param("--experimental", None, True),
1241+
pytest.param("--experimental", "false", True),
1242+
pytest.param(None, None, False),
1243+
pytest.param(None, "true", True),
1244+
pytest.param(None, "false", False),
1245+
pytest.param("--no-experimental", "true", False),
1246+
],
1247+
)
1248+
async def test_experimental_flags(mocker, option, env_var_value, expectation):
1249+
"""Test the experimental flag is set correctly."""
1250+
mocker.patch("kasa.discover.Discover.try_connect_all", return_value=None)
1251+
1252+
# reset the class internal variable
1253+
from kasa.experimental import Experimental
1254+
1255+
Experimental._enabled = None
1256+
1257+
KASA_VARS = {k: None for k, v in os.environ.items() if k.startswith("KASA_")}
1258+
if env_var_value:
1259+
KASA_VARS["KASA_EXPERIMENTAL"] = env_var_value
1260+
args = [
1261+
"--host",
1262+
"127.0.0.2",
1263+
"discover",
1264+
"config",
1265+
]
1266+
if option:
1267+
args.insert(0, option)
1268+
runner = CliRunner(env=KASA_VARS)
1269+
res = await runner.invoke(cli, args)
1270+
assert ("Experimental support is enabled" in res.output) is expectation

0 commit comments

Comments
 (0)
0