#!/usr/bin/env python3 """ Render test charts for two celebrities and save to /home/shared/. Usage: python3 render_test_charts.py [--format svg|png|jpg] [--size N] """ import argparse import asyncio import json import sys import os # Ensure src is on the path sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src")) from astro_mcp.tools import calculate_natal_chart, render_natal_chart # ── Birth data ─────────────────────────────────────────────────────── PEOPLE = { "donald_trump": { "birth_datetime": "1946-06-14T11:00:00-04:00", "latitude": 40.70, "longitude": -73.80, "elevation": 10, }, "chaka_khan": { "birth_datetime": "1953-03-23T11:00:00-06:00", "latitude": 41.88, "longitude": -87.63, "elevation": 180, }, } async def render_person(name: str, birth_data: dict, fmt: str, size: int) -> dict: """Calculate and render a natal chart for one person. Returns a summary dict with moon info and output path. """ # 1. Calculate chart data chart_data = await calculate_natal_chart( birth_datetime=birth_data["birth_datetime"], latitude=birth_data["latitude"], longitude=birth_data["longitude"], elevation=birth_data["elevation"], ) if "error" in chart_data: print(f" ERROR calculating {name}: {chart_data['error']}") return None # 2. Render result = await render_natal_chart( birth_datetime=birth_data["birth_datetime"], latitude=birth_data["latitude"], longitude=birth_data["longitude"], elevation=birth_data["elevation"], color_mode="color", size=size, format=fmt, title=f"Natal Chart: {name.replace('_', ' ').title()}", ) if "error" in result: print(f" ERROR rendering {name}: {result['error']}") return None # 3. Save ext = fmt filename = f"{name}_natal.{ext}" outdir = "/home/shared" os.makedirs(outdir, exist_ok=True) outpath = os.path.join(outdir, filename) content = result["content"] mode = "w" if isinstance(content, str) else "wb" with open(outpath, mode) as f: f.write(content) # 4. Extract moon info moon_info = None for p in chart_data.get("planets", []): if p.get("body") == "moon": moon_info = { "absolute_lon": p.get("absolute_lon"), "degree_within_sign": p.get("degree_within_sign"), "sign": p.get("sign"), "house": p.get("house"), "retrograde": p.get("retrograde"), } break return { "name": name, "output": outpath, "format": result["format"], "content_type": result["content_type"], "size_bytes": len(content) if isinstance(content, bytes) else len(content.encode("utf-8")), "moon": moon_info, "all_planets": [ {"body": p.get("body"), "absolute_lon": p.get("absolute_lon"), "degree_within_sign": p.get("degree_within_sign"), "sign": p.get("sign"), "house": p.get("house"), "retrograde": p.get("retrograde")} for p in chart_data.get("planets", []) ], "houses_count": len(chart_data.get("houses", [])), "aspects_count": len(chart_data.get("aspects", [])), } async def main(): parser = argparse.ArgumentParser(description="Render test natal charts") parser.add_argument("--format", default="svg", choices=["svg", "png", "jpg"], help="Output format (default: svg)") parser.add_argument("--size", type=int, default=600, help="Canvas size in pixels (default: 600)") parser.add_argument("--color-mode", default="color", choices=["color", "bw", "dark"], help="Color theme (default: color)") args = parser.parse_args() print(f"Rendering test charts — format={args.format}, size={args.size}px, theme={args.color_mode}") print(f"Output directory: /home/shared/") print() results = [] for name, birth_data in PEOPLE.items(): print(f"Processing {name.replace('_', ' ').title()}...") print(f" Birth: {birth_data['birth_datetime']} @ {birth_data['latitude']}, {birth_data['longitude']}") result = await render_person(name, birth_data, args.format, args.size) if result: results.append(result) print(f" Saved: {result['output']} ({result['size_bytes']:,} bytes)") if result["moon"]: m = result["moon"] print(f" MOON: {m['sign']} {m['degree_within_sign']:.1f}° (lon={m['absolute_lon']:.2f}°, house {m['house']})") else: print(f" MOON: not found in data!") print(f" Planets: {len(result['all_planets'])}, Houses: {result['houses_count']}, Aspects: {result['aspects_count']}") else: print(f" FAILED") print() # Summary comparison print("=" * 60) print("MOON COMPARISON") print("=" * 60) for r in results: m = r.get("moon", {}) if m: print(f" {r['name']:20s} | Moon in {m.get('sign','?'):12s} {m.get('degree_within_sign',0):5.1f}° | House {m.get('house','?')} | Retrograde: {m.get('retrograde',False)}") else: print(f" {r['name']:20s} | Moon data MISSING") print() # Save JSON summary summary_path = "/home/shared/test_charts_summary.json" with open(summary_path, "w") as f: json.dump(results, f, indent=2, default=str) print(f"Summary saved to: {summary_path}") if __name__ == "__main__": asyncio.run(main())