"""Recon package — load the dataset's knowledge graph. Typical use: from api.recon import load_recon recon = load_recon() tables = recon.owning_tables("A2") # ["district"] path = recon.join_path("loan", "district") # ["loan", "account", "district"] The Recon is read from `api/datasets//recon.json`. If the file is missing on first call, it's built on demand (with a log line) so local dev doesn't require remembering `make recon`. For deploys, run `python -m api.recon.build` (or `make recon`) to pre-bake. """ from __future__ import annotations import json import logging from functools import lru_cache from pathlib import Path from api.config import get_settings from api.datasets import DATASETS_DIR from api.recon.types import ( Column, Metric, Recon, Relationship, Table, ) logger = logging.getLogger("nvi.recon") __all__ = [ "load_recon", "recon_path", "Recon", "Column", "Table", "Metric", "Relationship", ] def recon_path(dataset: str | None = None) -> Path: dataset = dataset or get_settings().dataset return DATASETS_DIR / dataset / "recon.json" @lru_cache(maxsize=1) def load_recon() -> Recon: dataset = get_settings().dataset path = recon_path(dataset) if not path.exists(): logger.info("recon.json missing for %s; building on demand", dataset) from api.recon.build import build_recon, write_recon write_recon(dataset, build_recon(dataset)) data = json.loads(path.read_text()) return Recon.from_dict(data)