Source code for molsysviewer.config.user_presets
from __future__ import annotations
from pathlib import Path
import json
from typing import Any, Dict
try:
import yaml # type: ignore
except Exception: # pragma: no cover - optional dependency
yaml = None
# Registry of user-defined presets. Shape:
# {
# "name": {
# "base": "auto",
# "options": {...},
# "rules": [
# {"selection": "...", "representation": "...", "params": {...}},
# {"atom_indices": [0,1,2], "representation": "..."},
# ],
# },
# }
user_presets: Dict[str, Dict[str, Any]] = {}
[docs]
def load_user_presets(path: str | Path) -> Dict[str, Dict[str, Any]]:
"""Load user presets from a JSON or YAML file into ``user_presets``.
The file must contain a top-level mapping: preset_name -> {base, options, rules}.
YAML support requires ``pyyaml``; falls back to JSON otherwise.
"""
file_path = Path(path)
if not file_path.exists():
raise FileNotFoundError(f"Preset file not found: {file_path}")
text = file_path.read_text()
data: Dict[str, Any]
if file_path.suffix.lower() in {".yaml", ".yml"}:
if yaml is None:
raise ImportError("pyyaml is required to load YAML presets; install pyyaml or use JSON.")
data = yaml.safe_load(text) or {}
else:
data = json.loads(text)
if not isinstance(data, dict):
raise ValueError("Preset file must define a top-level mapping (dict).")
# Shallow validation: ensure each entry is a mapping
for name, cfg in data.items():
if not isinstance(cfg, dict):
raise ValueError(f"Preset '{name}' must be a mapping (found {type(cfg)})")
user_presets.update(data)
return user_presets
__all__ = ["user_presets", "load_user_presets"]