51 lines
1.5 KiB
Python
51 lines
1.5 KiB
Python
"""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/<active_dataset>/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)
|