recon + sqlglot validator + drill_down package; guard ReAct dimension picks against candidate list
This commit is contained in:
50
api/recon/__init__.py
Normal file
50
api/recon/__init__.py
Normal file
@@ -0,0 +1,50 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user