From c61f318baad175b672324b514caf953a8d2916aa Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Tue, 20 May 2025 13:31:47 +0200 Subject: [PATCH 1/4] Classgen: export field type definitions --- pkgs/classgen/main.py | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/pkgs/classgen/main.py b/pkgs/classgen/main.py index 76bb115f0..856b1c545 100644 --- a/pkgs/classgen/main.py +++ b/pkgs/classgen/main.py @@ -65,8 +65,8 @@ def field_def_from_default_type( field_name: str, field_types: set[str], class_name: str, - finalize_field: Callable[..., str], -) -> str | None: + finalize_field: Callable[..., tuple[str, str]], +) -> tuple[str, str] | None: if "dict" in str(field_types): return finalize_field( field_types=field_types, @@ -127,8 +127,8 @@ def field_def_from_default_value( field_name: str, field_types: set[str], nested_class_name: str, - finalize_field: Callable[..., str], -) -> str | None: + finalize_field: Callable[..., tuple[str, str]], +) -> tuple[str, str] | None: # default_value = prop_info.get("default") if default_value is None: return finalize_field( @@ -184,7 +184,7 @@ def get_field_def( default: str | None = None, default_factory: str | None = None, type_appendix: str = "", -) -> str: +) -> tuple[str, str]: if "None" in field_types or default or default_factory: if "None" in field_types: field_types.remove("None") @@ -193,7 +193,7 @@ def get_field_def( else: serialised_types = " | ".join(field_types) + type_appendix - return f"{field_name}: {serialised_types}" + return (field_name, serialised_types) # Recursive function to generate dataclasses from JSON schema @@ -204,8 +204,8 @@ def generate_dataclass( ) -> str: properties = schema.get("properties", {}) - required_fields = [] - fields_with_default = [] + required_fields: list[tuple[str, str]] = [] + fields_with_default: list[tuple[str, str]] = [] nested_classes: list[str] = [] # if We are at the top level, and the attribute name is in shallow @@ -218,7 +218,7 @@ def generate_dataclass( field_name = prop.replace("-", "_") if len(attr_path) == 0 and prop not in attrs: - field_def = f"{field_name}: NotRequired[dict[str, Any]]" + field_def = field_name, "NotRequired[dict[str, Any]]" fields_with_default.append(field_def) # breakpoint() continue @@ -345,9 +345,18 @@ def generate_dataclass( ) required_fields.append(field_def) - # breakpoint() - - fields_str = "\n ".join(required_fields + fields_with_default) + # Join field name with type to form a complete field declaration + # e.g. "name: str" + all_field_declarations = [ + f"{n}: {t}" for n, t in (required_fields + fields_with_default) + ] + hoisted_types: str = "\n".join( + [ + f"{class_name}{n.capitalize()}Type = {x}" + for n, x in (required_fields + fields_with_default) + ] + ) + fields_str = "\n ".join(all_field_declarations) nested_classes_str = "\n\n".join(nested_classes) class_def = f"\nclass {class_name}(TypedDict):\n" @@ -356,6 +365,8 @@ def generate_dataclass( else: class_def += f" {fields_str}" + class_def += f"\n\n{hoisted_types}\n" + return f"{nested_classes_str}\n\n{class_def}" if nested_classes_str else class_def From 38de1d1022c5f3f399994fdc51c972d1ae9aea0c Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Tue, 20 May 2025 13:32:13 +0200 Subject: [PATCH 2/4] UI: remove unused inventory.ts file --- pkgs/clan-app/ui/src/api/inventory.ts | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 pkgs/clan-app/ui/src/api/inventory.ts diff --git a/pkgs/clan-app/ui/src/api/inventory.ts b/pkgs/clan-app/ui/src/api/inventory.ts deleted file mode 100644 index 36d218490..000000000 --- a/pkgs/clan-app/ui/src/api/inventory.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { QueryClient } from "@tanstack/solid-query"; -import { ApiEnvelope, callApi } from "."; -import { Schema as Inventory } from "@/api/Inventory"; - -export async function get_inventory(client: QueryClient, base_path: string) { - const data = await client.ensureQueryData({ - queryKey: [base_path, "inventory"], - queryFn: () => { - console.log("Refreshing inventory"); - return callApi("get_inventory", { - flake: { identifier: base_path }, - }) as Promise>; - }, - revalidateIfStale: true, - staleTime: 60 * 1000, - }); - - return data; -} From 5727386691eed17b372da8049b573d1e9a0073ae Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Tue, 20 May 2025 13:34:14 +0200 Subject: [PATCH 3/4] Chore: re-generate nix models --- .../clan-cli/clan_lib/nix_models/inventory.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pkgs/clan-cli/clan_lib/nix_models/inventory.py b/pkgs/clan-cli/clan_lib/nix_models/inventory.py index 77218498b..69814941c 100644 --- a/pkgs/clan-cli/clan_lib/nix_models/inventory.py +++ b/pkgs/clan-cli/clan_lib/nix_models/inventory.py @@ -11,6 +11,9 @@ from typing import Any, Literal, NotRequired, TypedDict class MachineDeploy(TypedDict): targetHost: NotRequired[str] +MachineDeployTargethostType = NotRequired[str] + + class Machine(TypedDict): deploy: NotRequired[MachineDeploy] @@ -20,12 +23,25 @@ class Machine(TypedDict): name: NotRequired[str] tags: NotRequired[list[str]] +MachineDeployType = NotRequired[MachineDeploy] +MachineDescriptionType = NotRequired[str] +MachineIconType = NotRequired[str] +MachineMachineclassType = NotRequired[Literal["nixos", "darwin"]] +MachineNameType = NotRequired[str] +MachineTagsType = NotRequired[list[str]] + + class Meta(TypedDict): name: str description: NotRequired[str] icon: NotRequired[str] +MetaNameType = str +MetaDescriptionType = NotRequired[str] +MetaIconType = NotRequired[str] + + Service = dict[str, Any] @@ -35,3 +51,10 @@ class Inventory(TypedDict): modules: NotRequired[dict[str, Any]] services: NotRequired[dict[str, Service]] tags: NotRequired[dict[str, Any]] + +InventoryMachinesType = NotRequired[dict[str, Machine]] +InventoryMetaType = NotRequired[Meta] +InventoryModulesType = NotRequired[dict[str, Any]] +InventoryServicesType = NotRequired[dict[str, Service]] +InventoryTagsType = NotRequired[dict[str, Any]] + From f721f4fa9fe1a0ebb71e79e0c3e0130ae8b5010e Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Tue, 20 May 2025 13:42:18 +0200 Subject: [PATCH 4/4] Chore(formatter): exclude generated classes file --- formatter.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/formatter.nix b/formatter.nix index 60caffe0c..9b9237943 100644 --- a/formatter.nix +++ b/formatter.nix @@ -67,6 +67,9 @@ "*/bin/clan-app" "*/bin/clan-config" ]; + treefmt.settings.formatter.ruff-format.excludes = [ + "*/clan_lib/nix_models/*" + ]; treefmt.settings.formatter.shellcheck.includes = [ "scripts/pre-commit" ];