#!/usr/bin/env python3 """Generate a natal chart PNG for Donald Trump.""" import asyncio import sys import os import traceback sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src")) from astro_mcp.ephemeris_client import call_sky_state, extract_bodies, extract_houses, extract_angles from astro_mcp import astrology from astro_mcp.chart_renderer import render_natal_wheel # Trump's birth data BIRTH_DATETIME = "1946-06-14T10:54:00-04:00" LATITUDE = 40.6501 LONGITUDE = -73.7936 ELEVATION = 10.0 HOUSE_SYSTEM = "placidus" async def main(): print("Calling ephemeris for Trump's birth data...") sys.stdout.flush() try: sky = await call_sky_state( datetime=BIRTH_DATETIME, lat=LATITUDE, lon=LONGITUDE, elevation=ELEVATION, geocentric=True, house_system=HOUSE_SYSTEM, ) except Exception as e: traceback.print_exc() sys.exit(1) if "error" in sky: print(f"ERROR: {sky['error']}") sys.exit(1) raw_bodies = extract_bodies(sky) houses = extract_houses(sky) angles = extract_angles(sky) print(f"Got {len(raw_bodies)} bodies, {len(houses)} houses") sys.stdout.flush() # Build planet list planets = [] for body in raw_bodies: ecl_lon = body.get("ecliptic_lon", 0.0) ecl_lat = body.get("ecliptic_lat", 0.0) speed_lon = body.get("speed_lon") zodiac = astrology.ecliptic_to_zodiac(ecl_lon) house = astrology.get_house_placement(ecl_lon, houses) planets.append({ "body": body["body"], "sign": zodiac["sign"], "sign_abbreviation": zodiac["abbreviation"], "degree_within_sign": zodiac["degree"], "absolute_lon": zodiac["absolute_lon"], "ecliptic_lat": ecl_lat, "distance_au": body.get("distance_au", 0.0), "house": house, "retrograde": astrology.is_retrograde(speed_lon), }) # Calculate aspects speed_lookup = {b["body"]: b.get("speed_lon") for b in raw_bodies} aspect_bodies = [ {"name": p["body"], "lon": p["absolute_lon"], "speed_lon": speed_lookup.get(p["body"])} for p in planets ] aspects = astrology.compute_aspects(aspect_bodies, None) formatted_aspects = [] for asp in aspects: formatted_aspects.append({ "body1": asp["body1"], "body2": asp["body2"], "aspect": asp["aspect"], "orb": asp["orb"], "applying": asp["applying"], "exactness": asp["exactness"], }) chart_data = { "input": { "birth_datetime": BIRTH_DATETIME, "latitude": LATITUDE, "longitude": LONGITUDE, "elevation": ELEVATION, "house_system": HOUSE_SYSTEM, "name": "Donald Trump", "birthplace": "New York, NY", }, "chart_type": "natal", "planets": planets, "houses": houses, "aspects": formatted_aspects, "angles": angles, } print("Rendering natal wheel (bw, size=700)...") sys.stdout.flush() svg = render_natal_wheel( chart_data, style="modern", color_mode="bw", size=700, table_position="none", include_planets=False, include_houses=False, title="Donald Trump", ) # Write SVG svg_path = "/home/shared/trump_natal_bw.svg" with open(svg_path, "w") as f: f.write(svg) print(f"SVG written to {svg_path}") # Convert to PNG import cairosvg png_path = "/home/shared/trump_natal_bw.png" cairosvg.svg2png(url=svg_path, write_to=png_path, scale=2) print(f"PNG written to {png_path}") # Print chart info asc = angles.get("ascendant", {}) mc = angles.get("midheaven", {}) print(f"\nASC: {asc.get('sign')} {asc.get('degree', 0):.2f}°") print(f"MC: {mc.get('sign')} {mc.get('degree', 0):.2f}°") print(f"\nPlanets:") for p in planets: retro = " Rx" if p["retrograde"] else "" print(f" {p['body']:12s} {p['sign']:12s} {p['degree_within_sign']:6.2f}° H{p['house']}{retro}") print(f"\nAspects ({len(formatted_aspects)}):") for a in formatted_aspects[:20]: print(f" {a['body1']:10s} {a['aspect']:12s} {a['body2']:10s} orb={a['orb']:.2f}°") asyncio.run(main())