Files
Jyotisha/scripts/jyotishganit_shadbala_surface_probe.py
T

99 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""Extract jyotishganit Shadbala object surface raw/hash."""
from __future__ import annotations
import argparse
import hashlib
import json
import sys
from datetime import datetime
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
SRC = ROOT / "references/open_source_sources/jyotishganit"
PUBLIC_CASE_LATITUDE = 37.7749
PUBLIC_CASE_LONGITUDE = -122.4194
def clean(v: Any) -> Any:
if isinstance(v, dict):
return {k: clean(val) for k, val in v.items()}
if isinstance(v, list):
return [clean(x) for x in v]
if hasattr(v, "item"):
try:
return v.item()
except Exception:
pass
return v
def stable(data: Any) -> str:
return json.dumps(clean(data), ensure_ascii=False, sort_keys=True, separators=(",", ":"), default=str)
def build(args: argparse.Namespace) -> dict[str, Any]:
sys.path.insert(0, str(SRC))
from jyotishganit.main import calculate_birth_chart # type: ignore
chart = calculate_birth_chart(
datetime.fromisoformat(args.datetime),
args.latitude,
args.longitude,
args.timezone,
args.location,
args.name,
)
rows = {
p.celestial_body: clean(p.shadbala)
for p in chart.d1_chart.planets
if p.shadbala
}
required = ["Sthanabala", "Digbala", "Kaalabala", "Cheshtabala", "Naisargikabala", "Drikbala", "Shadbala"]
coverage = {
body: {key: key in values for key in required}
for body, values in rows.items()
}
raw = {"request": vars(args), "shadbala": rows}
return {
"scope": "jyotishganit_shadbala_surface_probe",
"created_at": "2026-07-19",
"status": "complete" if rows else "missing",
"claim_status": "observation_only",
"production_tuning_allowed": False,
"truth_matrix_allowed": False,
"source_path": "references/open_source_sources/jyotishganit/jyotishganit/components/strengths.py",
"api_surface": {
"calculate_all_strengths": True,
"compute_shadbala": True,
"six_strengths": required[:6],
},
"coverage": coverage,
"raw_hash": hashlib.sha256(stable(raw).encode("utf-8")).hexdigest(),
"raw": raw,
"boundary": "jyotishganit exposes Shadbala via object surface, not top-level to_dict. Observation-only until component units and external worked examples are compared.",
}
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("--datetime", default="1955-02-24T19:15:00")
ap.add_argument("--latitude", type=float, default=PUBLIC_CASE_LATITUDE)
ap.add_argument("--longitude", type=float, default=PUBLIC_CASE_LONGITUDE)
ap.add_argument("--timezone", type=float, default=-8.0)
ap.add_argument("--location", default="San Francisco, CA")
ap.add_argument("--name", default="Steve Jobs public")
ap.add_argument("--output")
args = ap.parse_args()
payload = build(args)
text = json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True)
if args.output:
Path(args.output).write_text(text + "\n", encoding="utf-8")
print(text)
return 0
if __name__ == "__main__":
raise SystemExit(main())