Skip to content

Commit 4d7c799

Browse files
authored
feat: Add host CLI option as alternative to config (#1395)
1 parent 6cb55c1 commit 4d7c799

2 files changed

Lines changed: 61 additions & 2 deletions

File tree

src/blueapi/cli/cli.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,19 @@ def is_str_dict(val: Any) -> TypeGuard[TaskParameters]:
8181
invoke_without_command=True, context_settings={"auto_envvar_prefix": "BLUEAPI"}
8282
)
8383
@click.version_option(version=__version__, prog_name="blueapi")
84+
@click.option(
85+
"-h",
86+
"--host",
87+
type=str,
88+
help=textwrap.dedent(
89+
"""
90+
Hostname for the blueapi instance to use
91+
92+
Value should be the full URL including scheme (and port if non-default),
93+
eg `--host http://localhost:8000`
94+
"""
95+
),
96+
)
8497
@click.option(
8598
"-c", "--config", type=Path, help="Path to configuration YAML file", multiple=True
8699
)
@@ -100,7 +113,10 @@ def is_str_dict(val: Any) -> TypeGuard[TaskParameters]:
100113
)
101114
@click.pass_context
102115
def main(
103-
ctx: click.Context, config: tuple[Path, ...], log_level: str | None = None
116+
ctx: click.Context,
117+
config: tuple[Path, ...],
118+
host: str | None = None,
119+
log_level: str | None = None,
104120
) -> None:
105121
# if no command is supplied, run with the options passed
106122

@@ -112,7 +128,8 @@ def main(
112128
config_loader.use_values_from_yaml(*config)
113129
except FileNotFoundError as fnfe:
114130
raise ClickException(f"Config file not found: {fnfe.filename}") from fnfe
115-
131+
if host:
132+
config_loader.use_values({"api": {"url": host}})
116133
if log_level:
117134
config_loader.use_values({"logging": {"level": log_level}})
118135

tests/unit_tests/cli/test_cli.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,3 +1430,45 @@ def test_log_level_override(flag: str, level: str, runner: CliRunner):
14301430
runner.invoke(main, [flag])
14311431
mock_log.getLogger().setLevel.assert_called_once_with(level)
14321432
mock_log.StreamHandler().setLevel.assert_called_once_with(level)
1433+
1434+
1435+
@responses.activate
1436+
def test_host_option(runner: CliRunner):
1437+
response = responses.add(
1438+
responses.GET,
1439+
"http://override.example.com:5678/plans",
1440+
json={"plans": []},
1441+
status=200,
1442+
)
1443+
1444+
res = runner.invoke(
1445+
main,
1446+
["--host", "http://override.example.com:5678", "controller", "plans"],
1447+
)
1448+
assert response.call_count == 1
1449+
assert res.exit_code == 0
1450+
1451+
1452+
@responses.activate
1453+
def test_host_overrides_config(runner: CliRunner):
1454+
config_path = "tests/unit_tests/example_yaml/rest_config.yaml"
1455+
response = responses.add(
1456+
responses.GET,
1457+
"http://override.example.com:5678/plans",
1458+
json={"plans": []},
1459+
status=200,
1460+
)
1461+
1462+
res = runner.invoke(
1463+
main,
1464+
[
1465+
"--host",
1466+
"http://override.example.com:5678",
1467+
"--config",
1468+
config_path,
1469+
"controller",
1470+
"plans",
1471+
],
1472+
)
1473+
assert response.call_count == 1
1474+
assert res.exit_code == 0

0 commit comments

Comments
 (0)