"""P0 audit: live FinData catalog, bars schema, OpenAPI, timestamp conventions on real rows (secrets never printed).""" from __future__ import annotations import json import sys import time from datetime import datetime, timezone from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) from chronos_x.data.client import FinDataClient # noqa: E402 from chronos_x.data.calendar import sessions # noqa: E402 ROOT = Path(__file__).resolve().parents[1] OUT = ROOT / "results" / "metrics" / "p0_api_audit.json" def main() -> None: c = FinDataClient(log_path=ROOT / "results" / "logs" / "provenance_audit.jsonl") t0 = time.time() health = c.health() datasets = c.datasets() schema = c.bars_schema() openapi = c.openapi() report = {"audited_at": datetime.now(timezone.utc).isoformat(), "base": c.base, "health": {k: health.get(k) for k in ("status", "checked_at", "alerts")}, "lake": health.get("components", {}).get("lake"), "openapi": {"version": openapi.get("openapi"), "n_paths": len(openapi.get("paths", {})), "export_schema": openapi.get("components", {}).get("schemas", {}).get("ExportIn")}, "bars_schema": schema, "datasets": {d["id"]: {k: d.get(k) for k in ("status", "row_count", "first_session", "last_session", "license_class")} for d in datasets if d["id"].startswith(("market_bars.stock", "market_bars.etf", "corporate"))}} # timestamp conventions on real rows checks = {} for sym, day in (("AAPL", "2024-03-08"), ("AAPL", "2024-03-11"), ("AAPL", "2024-11-29"), ("SPY", "2024-07-03")): t = c.bars(sym, day, day).to_pandas() s = sessions(day, day)[0] reg = t[(t["timestamp_utc"] >= s.open_utc) & (t["timestamp_utc"] <= s.close_utc)] checks[f"{sym}_{day}"] = {"rows_total": int(len(t)), "rows_regular": int(len(reg)), "expected_regular": s.n_slots, "first_ts": str(t["timestamp_utc"].min()), "last_ts": str(t["timestamp_utc"].max()), "open_utc": str(s.open_utc), "close_utc": str(s.close_utc), "closing_print_volume": float(reg[reg["timestamp_utc"] == s.close_utc]["volume"].sum()), "median_regular_volume": float(reg["volume"].median()), "quality_flags_nonempty": int((reg["quality_flags"].map(len) > 0).sum()), "revision_ids": sorted(int(x) for x in t["revision_id"].unique())} # split consistency: raw vs server-side split on AAPL around 2020-08-31 (4:1) raw = c.bars("AAPL", "2020-08-28", "2020-08-28").to_pandas() spl = c.bars("AAPL", "2020-08-28", "2020-08-28", adjustment="split").to_pandas() ratio = float((raw["close"] / spl["close"]).median()) checks["AAPL_split_2020-08-31"] = {"raw_over_split_median": ratio, "expected": 4.0, "volume_ratio": float((spl["volume"] / raw["volume"]).median())} report["timestamp_checks"] = checks report["elapsed_s"] = round(time.time() - t0, 1) OUT.parent.mkdir(parents=True, exist_ok=True) OUT.write_text(json.dumps(report, indent=1, default=str)) print(json.dumps({k: v for k, v in report.items() if k in ("health", "lake", "timestamp_checks", "elapsed_s")}, indent=1, default=str)) if __name__ == "__main__": main()