Coverage for /builds/svesch/cikit/src/cikit/data/common.py: 100%
17 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-10-09 14:17 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-10-09 14:17 +0000
1# SPDX-License-Identifier: GPL-3.0-or-later
2"""Common helpers for the cikit data package.
4This module provides small utility functions for working with local run data
5files and resolving values from cached run data.
7Author:
8 Sven Schlender
9Date:
10 2026-01-29
11"""
13from pathlib import Path
14from typing import Any
16from cikit.json_utils import load_json_file, save_json_file
19def get_run_filename(directory: Path, run_name: str) -> Path:
20 """Return the cache file path for a run.
22 Args:
23 directory: Base cache directory.
24 run_name: Logical run name.
26 Returns:
27 Full path to the run JSON file.
28 """
29 return directory / f"{run_name}.json"
32def load_run_data(filepath: Path) -> Any:
33 """Load JSON data from a file.
35 Missing files are treated as empty run data and return an empty dict.
37 Args:
38 filepath: Path to the JSON file.
40 Returns:
41 Parsed JSON content, or an empty dict if the file does not exist.
43 Raises:
44 CiToolsError: If the file cannot be read or parsed as JSON.
45 """
46 return load_json_file(filepath, description="run data")
49def save_run_data(filepath: Path, data: Any) -> None:
50 """Write JSON data to a file.
52 Parent directories are created automatically if needed.
54 Args:
55 filepath: Path to the JSON file.
56 data: JSON-serializable data to store.
58 Raises:
59 CiToolsError: If the file cannot be written or the data cannot be
60 serialized as JSON.
61 """
62 save_json_file(filepath, data, description="run data")
65def lookup_key(data: dict, dotted_key: str) -> Any:
66 """Resolve a dotted key path inside a nested dictionary.
68 The key is split on dots and resolved step by step. If any path segment
69 is missing, or if traversal reaches a non-dict value before the final
70 segment, the function returns None.
72 Args:
73 data: Nested dictionary to search in.
74 dotted_key: Dot-separated key path, for example ``"a.b.c"``.
76 Returns:
77 Resolved value, or None if the path cannot be resolved.
78 """
79 parts = dotted_key.split(".")
80 cur = data
82 for part in parts:
83 if not isinstance(cur, dict) or part not in cur:
84 return None
85 cur = cur[part]
87 return cur