diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index d9140a55..afb4fd9b 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,10 +1,17 @@ # Frequenz Dispatch Client Library Release Notes +## Summary -## Bug Fixes - -* Fix cli client trying to use a invalid default URL when none is given. + ## Upgrading -* You now must always provide the URL to the dispatch client. + + +## New Features + +* `dispatch-cli` supports now the parameter `--type` and `--running` to filter the list of running services by type and status, respectively. + +## Bug Fixes + + diff --git a/src/frequenz/client/dispatch/__main__.py b/src/frequenz/client/dispatch/__main__.py index 4b4c7f9e..7ea36ea9 100644 --- a/src/frequenz/client/dispatch/__main__.py +++ b/src/frequenz/client/dispatch/__main__.py @@ -218,6 +218,8 @@ async def cli(ctx: click.Context, url: str, key: str, raw: bool) -> None: @click.option("--active", type=bool) @click.option("--dry-run", type=bool) @click.option("--page-size", type=int) +@click.option("--running", type=bool) +@click.option("--type", "-T", type=str) async def list_(ctx: click.Context, /, **filters: Any) -> None: """List dispatches. @@ -225,21 +227,33 @@ async def list_(ctx: click.Context, /, **filters: Any) -> None: The target option can be given multiple times. """ + filter_running: bool = filters.pop("running", False) + filter_type: str | None = filters.pop("type", None) + if "target" in filters: target = filters.pop("target") # Name of the parameter in client.list() filters["target_components"] = target num_dispatches = 0 + num_filtered = 0 async for page in ctx.obj["client"].list(**filters): for dispatch in page: + if filter_running and not dispatch.started: + num_filtered += 1 + continue + + if filter_type and dispatch.type != filter_type: + num_filtered += 1 + continue + if ctx.obj["raw"]: click.echo(pformat(dispatch, compact=True)) else: print_dispatch(dispatch) num_dispatches += 1 - click.echo(f"{num_dispatches} dispatches total.") + click.echo(f"{num_dispatches} dispatches, {num_filtered} filtered out.") @cli.command("stream") diff --git a/tests/test_cli.py b/tests/test_cli.py index 597afe94..6be30d08 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -79,10 +79,10 @@ def mock_client(fake_client: FakeClient) -> Generator[None, None, None]: ] }, 1, - "1 dispatches total.", + "1 dispatches, 0 filtered out", 0, ), - ({}, 1, "0 dispatches total.", 0), + ({}, 1, "0 dispatches, 0 filtered out", 0), ( { 2: [ @@ -102,7 +102,7 @@ def mock_client(fake_client: FakeClient) -> Generator[None, None, None]: ] }, 1, - "0 dispatches total.", + "0 dispatches, 0 filtered out", 0, ), ( @@ -139,7 +139,7 @@ def mock_client(fake_client: FakeClient) -> Generator[None, None, None]: ], }, 1, - "1 dispatches total.", + "1 dispatches, 0 filtered out", 0, ), ( @@ -148,6 +148,41 @@ def mock_client(fake_client: FakeClient) -> Generator[None, None, None]: "Error: Invalid value for 'MICROGRID_ID': 'x' is not a valid integer.", 2, ), + ( + { + 1: [ + Dispatch( + id=1, + type="test", + start_time=datetime(2023, 1, 1, 0, 0, 0), + duration=timedelta(seconds=3600), + target=[1, 2, 3], + active=True, + dry_run=False, + payload={}, + recurrence=RecurrenceRule(), + create_time=datetime(2023, 1, 1, 0, 0, 0), + update_time=datetime(2023, 1, 1, 0, 0, 0), + ), + Dispatch( + id=2, + type="filtered", + start_time=datetime(2023, 1, 1, 0, 0, 0), + duration=timedelta(seconds=1800), + target=[3], + active=True, + dry_run=False, + payload={}, + recurrence=RecurrenceRule(), + create_time=datetime(2023, 1, 1, 0, 0, 0), + update_time=datetime(2023, 1, 1, 0, 0, 0), + ), + ], + }, + 1, + "1 dispatches, 1 filtered out", + 0, + ), ], ) async def test_list_command( @@ -163,7 +198,9 @@ async def test_list_command( fake_client.set_dispatches(microgrid_id_, dispatch_list) result = await runner.invoke( - cli, ["--raw", "list", str(microgrid_id)], env=ENVIRONMENT_VARIABLES + cli, + ["--raw", "list", str(microgrid_id), "--type", "test"], + env=ENVIRONMENT_VARIABLES, ) assert expected_output in result.output assert result.exit_code == expected_return_code