Clan_lib: add filtering by tag to list API

This commit is contained in:
Johannes Kirschbauer
2025-07-04 09:48:21 +02:00
parent b0c24edd48
commit 41cafe828f
4 changed files with 42 additions and 18 deletions

View File

@@ -1,4 +1,5 @@
from dataclasses import dataclass
from typing import TypedDict
from clan_lib.api import API
from clan_lib.errors import ClanError
@@ -10,15 +11,44 @@ from clan_lib.persist.inventory_store import InventoryStore
from clan_lib.persist.util import set_value_by_path
class MachineFilter(TypedDict):
tags: list[str]
class ListOptions(TypedDict):
filter: MachineFilter
@API.register
def list_machines(flake: Flake) -> dict[str, InventoryMachine]:
def list_machines(
flake: Flake, opts: ListOptions | None = None
) -> dict[str, InventoryMachine]:
"""
List machines in the inventory for the UI.
List machines of a clan
Usage Example:
machines = list_machines(flake, {"filter": {"tags": ["foo" "bar"]}})
lists only machines that include both "foo" AND "bar"
"""
inventory_store = InventoryStore(flake=flake)
inventory = inventory_store.read()
machines = inventory.get("machines", {})
if opts and opts.get("filter"):
filtered_machines = {}
filter_tags = opts.get("filter", {}).get("tags", [])
for machine_name, machine in machines.items():
machine_tags = machine.get("tags", [])
if all(ft in machine_tags for ft in filter_tags):
filtered_machines[machine_name] = machine
return filtered_machines
return machines

View File

@@ -31,21 +31,21 @@ def list_full_machines(flake: Flake) -> dict[str, Machine]:
return res
# TODO: Add filter to list_machines -> list_machines(flake, filter={tags=...})
def query_machines_by_tags(flake: Flake, tags: list[str]) -> dict[str, Machine]:
def query_machines_by_tags(
flake: Flake, tags: list[str]
) -> dict[str, InventoryMachine]:
"""
Query machines by their respective tags, if multiple tags are specified
then only machines that have those respective tags specified will be listed.
It is an intersection of the tags and machines.
"""
machines = list_full_machines(flake)
machines = list_machines(flake)
filtered_machines = {}
for machine in machines.values():
inv_machine = get_machine(machine.flake, machine.name)
machine_tags = inv_machine.get("tags", [])
for machine_name, machine in machines.items():
machine_tags = machine.get("tags", [])
if all(tag in machine_tags for tag in tags):
filtered_machines[machine.name] = machine
filtered_machines[machine_name] = machine
return filtered_machines