Spaces:
Running
on
Zero
Running
on
Zero
| """Configuration helpers for the NACC node server.""" | |
| from __future__ import annotations | |
| from pathlib import Path | |
| from typing import Any | |
| import yaml | |
| from pydantic import BaseModel, Field, field_validator | |
| class NodeConfig(BaseModel): | |
| node_id: str = Field(..., description="Unique identifier for the node") | |
| root_dir: Path = Field(..., description="Root directory exposed by the node") | |
| tags: list[str] = Field(default_factory=list) | |
| description: str | None = None | |
| allowed_commands: list[str] = Field( | |
| default_factory=lambda: ["python", "ls", "cat", "echo"], | |
| description="Simple whitelist of commands allowed in ExecuteCommand", | |
| ) | |
| sync_targets: dict[str, Path] = Field( | |
| default_factory=dict, | |
| description="Mapping of sync target names to directories", | |
| ) | |
| def _expand_root(cls, value: Any) -> Path: | |
| return Path(value).expanduser().resolve() | |
| def _expand_targets(cls, value: dict[str, Any]) -> dict[str, Path]: | |
| if not value: | |
| return {} | |
| return {key: Path(path).expanduser().resolve() for key, path in value.items()} | |
| def load_node_config(path: str | Path) -> NodeConfig: | |
| config_path = Path(path).expanduser().resolve() | |
| if not config_path.exists(): | |
| raise FileNotFoundError(f"Node config not found: {config_path}") | |
| with config_path.open("r", encoding="utf-8") as handle: | |
| data = yaml.safe_load(handle) or {} | |
| return NodeConfig(**data) | |