Remove the V5 scoring pipeline, dynamic rectification, minute-rectification evaluations and the research scripts built on them, plus their API routes. Keep the upstream skill layer (gate, questionnaire, active events), the varga-segments scan and the consult range reading (moved to scripts/birth_window_range_reading.py). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DbBXozbkyFNqbu8pVEtZ7W
88 lines
3.3 KiB
Python
88 lines
3.3 KiB
Python
"""Stable vs minute-sensitive reading themes across a declared birth window.
|
|
|
|
Serves `/api/rectification/v5/range_reading` for consultation (a person whose
|
|
birth time is a range). Moved out of the retired rectification V5 API service
|
|
on 2026-11-06; behaviour unchanged.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Mapping
|
|
|
|
|
|
def range_reading(request: Mapping[str, Any]) -> dict[str, Any]:
|
|
"""Stable vs minute-sensitive themes for one unresolved clock window."""
|
|
from types import SimpleNamespace
|
|
|
|
from scripts.jyotish_engine import _build_birth_time_sensitivity
|
|
|
|
body = dict(request or {})
|
|
birth_date = str(body.get("birth_date") or "").strip()
|
|
if birth_date:
|
|
year_text, month_text, day_text = birth_date.split("-", 2)
|
|
year, month, day = int(year_text), int(month_text), int(day_text)
|
|
else:
|
|
year, month, day = int(body["year"]), int(body["month"]), int(body["day"])
|
|
representative = str(body.get("representative_time") or "")[:5]
|
|
if len(representative) == 5 and representative[2] == ":":
|
|
hour, minute = int(representative[:2]), int(representative[3:])
|
|
else:
|
|
hour = int(body.get("hour") or 12)
|
|
minute = int(body.get("minute") or 0)
|
|
representative = f"{hour:02d}:{minute:02d}"
|
|
raw_range = body.get("candidate_range")
|
|
if isinstance(raw_range, Mapping):
|
|
start_time = str(raw_range.get("start_time") or "")[:5]
|
|
end_time = str(raw_range.get("end_time") or "")[:5]
|
|
representative = str(raw_range.get("representative_time") or representative)[:5]
|
|
else:
|
|
start_time = str(body.get("start_time") or "")[:5]
|
|
end_time = str(body.get("end_time") or "")[:5]
|
|
hour, minute = int(representative[:2]), int(representative[3:])
|
|
accuracy = str(body.get("birth_time_accuracy") or "provisional")
|
|
args = SimpleNamespace(
|
|
year=year,
|
|
month=month,
|
|
day=day,
|
|
hour=hour,
|
|
minute=minute,
|
|
second=0,
|
|
lat=float(body["lat"]),
|
|
lon=float(body["lon"]),
|
|
tz=float(body["tz"]),
|
|
ayanamsa=body.get("ayanamsa") or "raman",
|
|
node_mode=body.get("node_mode") or "mean",
|
|
birth_time_accuracy=accuracy,
|
|
candidate_range={
|
|
"start_time": start_time,
|
|
"end_time": end_time,
|
|
"representative_time": representative,
|
|
},
|
|
representative_time=representative,
|
|
declared_window_start=None,
|
|
declared_window_end=None,
|
|
uncertainty_before_minutes=None,
|
|
uncertainty_after_minutes=None,
|
|
)
|
|
sensitivity = _build_birth_time_sensitivity(args)
|
|
themes = sensitivity.get("theme_sensitivity")
|
|
themes = themes if isinstance(themes, dict) else {}
|
|
stable = [
|
|
key for key, row in themes.items()
|
|
if isinstance(row, dict) and row.get("status") == "stable"
|
|
]
|
|
sensitive = [
|
|
key for key, row in themes.items()
|
|
if isinstance(row, dict) and row.get("status") == "sensitive"
|
|
]
|
|
return {
|
|
"window": sensitivity.get("window"),
|
|
"stable_themes": stable,
|
|
"sensitive_themes": sensitive,
|
|
"claim_boundary": sensitivity.get("claim_boundary"),
|
|
"theme_sensitivity": themes,
|
|
"accuracy": sensitivity.get("accuracy"),
|
|
"status": sensitivity.get("status"),
|
|
}
|
|
|
|
|