wuenlp_tools.ssc_config

SSC checkpoint and repo paths (user / project config, or environment variables).

 1"""SSC checkpoint and repo paths (user / project config, or environment variables)."""
 2
 3from __future__ import annotations
 4
 5import json
 6import os
 7from typing import Any
 8
 9SSC_CONFIG_PATH = os.path.expanduser("~/.local/share/wuenlp-tools/ssc_config.json")
10PROJECT_SSC_CONFIG_CANDIDATES = (
11    ".wuenlp_ssc_config.json",
12    "wuenlp_ssc_config.json",
13)
14
15# JSON keys in ssc_config.json / project config (values are absolute paths).
16SSC_REPO_ROOT_KEY = "ssc_repo_root"
17SSC_SCENE_MODEL_PATH_KEY = "scene_model_path"
18SSC_SUSPENSE_MODEL_ROOT_KEY = "suspense_model_root"
19
20_ENV_BY_KEY = {
21    SSC_REPO_ROOT_KEY: "SSC_REPO_ROOT",
22    SSC_SCENE_MODEL_PATH_KEY: "SSC_SCENE_MODEL_PATH",
23    SSC_SUSPENSE_MODEL_ROOT_KEY: "SSC_SUSPENSE_MODEL_ROOT",
24}
25
26__all__ = [
27    "SSC_CONFIG_PATH",
28    "PROJECT_SSC_CONFIG_CANDIDATES",
29    "read_ssc_config",
30    "write_ssc_config",
31    "get_ssc_repo_root",
32    "get_ssc_scene_model_path",
33    "get_ssc_suspense_model_root",
34]
35
36
37def read_ssc_config() -> dict[str, Any]:
38    """Read merged SSC config: user file, then project file in cwd (project wins)."""
39    merged: dict[str, Any] = {}
40    if os.path.isfile(SSC_CONFIG_PATH):
41        try:
42            with open(SSC_CONFIG_PATH, encoding="utf-8") as f:
43                merged.update(json.load(f))
44        except json.JSONDecodeError:
45            pass
46    for filename in PROJECT_SSC_CONFIG_CANDIDATES:
47        candidate = os.path.join(os.getcwd(), filename)
48        if os.path.isfile(candidate):
49            try:
50                with open(candidate, encoding="utf-8") as f:
51                    merged.update(json.load(f))
52            except json.JSONDecodeError:
53                pass
54            break
55    return merged
56
57
58def write_ssc_config(config: dict[str, Any]) -> None:
59    os.makedirs(os.path.dirname(SSC_CONFIG_PATH), exist_ok=True)
60    with open(SSC_CONFIG_PATH, "w", encoding="utf-8") as f:
61        json.dump(config, f, indent=2)
62
63
64def _require_ssc_path(key: str) -> str:
65    env_name = _ENV_BY_KEY[key]
66    if env_name in os.environ and os.environ[env_name].strip():
67        return os.environ[env_name].strip()
68    value = read_ssc_config().get(key)
69    if value and str(value).strip():
70        return str(value).strip()
71    raise RuntimeError(
72        f"SSC path {key!r} is not configured. "
73        f"Set environment variable {env_name} or add {key!r} to "
74        f"{SSC_CONFIG_PATH} (or a project {PROJECT_SSC_CONFIG_CANDIDATES[0]} file)."
75    )
76
77
78def get_ssc_repo_root() -> str:
79    return _require_ssc_path(SSC_REPO_ROOT_KEY)
80
81
82def get_ssc_scene_model_path() -> str:
83    return _require_ssc_path(SSC_SCENE_MODEL_PATH_KEY)
84
85
86def get_ssc_suspense_model_root() -> str:
87    return _require_ssc_path(SSC_SUSPENSE_MODEL_ROOT_KEY)
SSC_CONFIG_PATH = '/Users/zehe/.local/share/wuenlp-tools/ssc_config.json'

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.

PROJECT_SSC_CONFIG_CANDIDATES = ('.wuenlp_ssc_config.json', 'wuenlp_ssc_config.json')

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

def read_ssc_config() -> dict[str, typing.Any]:
38def read_ssc_config() -> dict[str, Any]:
39    """Read merged SSC config: user file, then project file in cwd (project wins)."""
40    merged: dict[str, Any] = {}
41    if os.path.isfile(SSC_CONFIG_PATH):
42        try:
43            with open(SSC_CONFIG_PATH, encoding="utf-8") as f:
44                merged.update(json.load(f))
45        except json.JSONDecodeError:
46            pass
47    for filename in PROJECT_SSC_CONFIG_CANDIDATES:
48        candidate = os.path.join(os.getcwd(), filename)
49        if os.path.isfile(candidate):
50            try:
51                with open(candidate, encoding="utf-8") as f:
52                    merged.update(json.load(f))
53            except json.JSONDecodeError:
54                pass
55            break
56    return merged

Read merged SSC config: user file, then project file in cwd (project wins).

def write_ssc_config(config: dict[str, typing.Any]) -> None:
59def write_ssc_config(config: dict[str, Any]) -> None:
60    os.makedirs(os.path.dirname(SSC_CONFIG_PATH), exist_ok=True)
61    with open(SSC_CONFIG_PATH, "w", encoding="utf-8") as f:
62        json.dump(config, f, indent=2)
def get_ssc_repo_root() -> str:
79def get_ssc_repo_root() -> str:
80    return _require_ssc_path(SSC_REPO_ROOT_KEY)
def get_ssc_scene_model_path() -> str:
83def get_ssc_scene_model_path() -> str:
84    return _require_ssc_path(SSC_SCENE_MODEL_PATH_KEY)
def get_ssc_suspense_model_root() -> str:
87def get_ssc_suspense_model_root() -> str:
88    return _require_ssc_path(SSC_SUSPENSE_MODEL_ROOT_KEY)