nategodd/app.py
type-two 1be39727f8 NATEGODD: Swiss Ephemeris natal chart generator
Full-detail natal charts: 21 bodies/points, 7 house systems, 11 aspect
types with applying/separating, dignities, declination parallels,
sect/balances/moon phase, offline city search with historical IANA
time atlas, SVG wheel, and a written interpretation report.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 19:52:08 +10:00

65 lines
2.3 KiB
Python

"""NATEGODD — natal chart generator. Run: .venv/bin/python app.py → http://localhost:7799"""
from flask import Flask, jsonify, request, send_from_directory
import chart as chart_engine
import geo
import interp
app = Flask(__name__, static_folder="static", static_url_path="")
@app.get("/")
def index():
return send_from_directory("static", "index.html")
@app.get("/api/search")
def api_search():
q = request.args.get("q", "")
return jsonify(geo.search_cities(q))
@app.post("/api/chart")
def api_chart():
d = request.get_json(force=True)
try:
year, month, day = int(d["year"]), int(d["month"]), int(d["day"])
time_unknown = bool(d.get("time_unknown"))
hour = 12 if time_unknown else int(d.get("hour", 12))
minute = 0 if time_unknown else int(d.get("minute", 0))
second = int(d.get("second", 0) or 0)
lat, lon = float(d["lat"]), float(d["lon"])
house_system = d.get("house_system", "P")
if house_system not in chart_engine.HOUSE_SYSTEMS:
house_system = "P"
except (KeyError, ValueError, TypeError) as e:
return jsonify({"error": f"bad input: {e}"}), 400
if d.get("utc_offset") not in (None, ""):
offset, tzname = float(d["utc_offset"]), "manual"
else:
try:
offset, tzname = geo.resolve_offset(lat, lon, year, month, day, hour, minute,
tz_hint=d.get("tz"))
except Exception as e:
return jsonify({"error": f"could not resolve timezone: {e}"}), 400
try:
result = chart_engine.compute_chart(year, month, day, hour, minute, second,
offset, lat, lon, house_system, time_unknown)
except Exception as e:
return jsonify({"error": f"computation failed: {e}"}), 400
result["input"] = {
"name": d.get("name", ""), "place": d.get("place", ""),
"lat": lat, "lon": lon, "tz": tzname, "utc_offset": offset,
"date": f"{year:04d}-{month:02d}-{day:02d}",
"time": None if time_unknown else f"{hour:02d}:{minute:02d}",
}
result["interpretation"] = interp.build_interpretation(result)
return jsonify(result)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7799, debug=False)