kerykeion 5.0.0a9__py3-none-any.whl → 5.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kerykeion might be problematic. Click here for more details.
- kerykeion/__init__.py +50 -9
- kerykeion/aspects/__init__.py +5 -2
- kerykeion/aspects/aspects_factory.py +568 -0
- kerykeion/aspects/aspects_utils.py +78 -11
- kerykeion/astrological_subject_factory.py +1032 -275
- kerykeion/backword.py +820 -0
- kerykeion/chart_data_factory.py +552 -0
- kerykeion/charts/chart_drawer.py +2661 -0
- kerykeion/charts/charts_utils.py +652 -399
- kerykeion/charts/draw_planets.py +603 -353
- kerykeion/charts/templates/aspect_grid_only.xml +326 -198
- kerykeion/charts/templates/chart.xml +306 -256
- kerykeion/charts/templates/wheel_only.xml +330 -200
- kerykeion/charts/themes/black-and-white.css +148 -0
- kerykeion/charts/themes/classic.css +11 -0
- kerykeion/charts/themes/dark-high-contrast.css +11 -0
- kerykeion/charts/themes/dark.css +11 -0
- kerykeion/charts/themes/light.css +11 -0
- kerykeion/charts/themes/strawberry.css +10 -0
- kerykeion/composite_subject_factory.py +232 -13
- kerykeion/ephemeris_data_factory.py +443 -0
- kerykeion/fetch_geonames.py +78 -21
- kerykeion/house_comparison/__init__.py +4 -1
- kerykeion/house_comparison/house_comparison_factory.py +52 -19
- kerykeion/house_comparison/house_comparison_utils.py +37 -9
- kerykeion/kr_types/__init__.py +66 -6
- kerykeion/kr_types/chart_template_model.py +20 -0
- kerykeion/kr_types/kerykeion_exception.py +15 -9
- kerykeion/kr_types/kr_literals.py +14 -160
- kerykeion/kr_types/kr_models.py +14 -291
- kerykeion/kr_types/settings_models.py +15 -167
- kerykeion/planetary_return_factory.py +545 -40
- kerykeion/relationship_score_factory.py +137 -63
- kerykeion/report.py +749 -64
- kerykeion/schemas/__init__.py +106 -0
- kerykeion/schemas/chart_template_model.py +367 -0
- kerykeion/schemas/kerykeion_exception.py +20 -0
- kerykeion/schemas/kr_literals.py +181 -0
- kerykeion/schemas/kr_models.py +603 -0
- kerykeion/schemas/settings_models.py +188 -0
- kerykeion/settings/__init__.py +20 -1
- kerykeion/settings/chart_defaults.py +444 -0
- kerykeion/settings/config_constants.py +88 -12
- kerykeion/settings/kerykeion_settings.py +32 -75
- kerykeion/settings/translation_strings.py +1499 -0
- kerykeion/settings/translations.py +74 -0
- kerykeion/sweph/ast136/s136108s.se1 +0 -0
- kerykeion/sweph/ast136/s136199s.se1 +0 -0
- kerykeion/sweph/ast136/s136472s.se1 +0 -0
- kerykeion/sweph/ast28/se28978s.se1 +0 -0
- kerykeion/sweph/ast50/se50000s.se1 +0 -0
- kerykeion/sweph/ast90/se90377s.se1 +0 -0
- kerykeion/sweph/ast90/se90482s.se1 +0 -0
- kerykeion/sweph/sefstars.txt +1602 -0
- kerykeion/transits_time_range_factory.py +302 -0
- kerykeion/utilities.py +289 -204
- kerykeion-5.1.8.dist-info/METADATA +1793 -0
- kerykeion-5.1.8.dist-info/RECORD +63 -0
- kerykeion/aspects/natal_aspects.py +0 -181
- kerykeion/aspects/synastry_aspects.py +0 -141
- kerykeion/aspects/transits_time_range.py +0 -41
- kerykeion/charts/draw_planets_v2.py +0 -649
- kerykeion/charts/draw_planets_v3.py +0 -679
- kerykeion/charts/kerykeion_chart_svg.py +0 -2038
- kerykeion/enums.py +0 -57
- kerykeion/ephemeris_data.py +0 -238
- kerykeion/house_comparison/house_comparison_models.py +0 -38
- kerykeion/kr_types/chart_types.py +0 -106
- kerykeion/settings/kr.config.json +0 -1304
- kerykeion/settings/legacy/__init__.py +0 -0
- kerykeion/settings/legacy/legacy_celestial_points_settings.py +0 -299
- kerykeion/settings/legacy/legacy_chart_aspects_settings.py +0 -71
- kerykeion/settings/legacy/legacy_color_settings.py +0 -42
- kerykeion/transits_time_range.py +0 -128
- kerykeion-5.0.0a9.dist-info/METADATA +0 -636
- kerykeion-5.0.0a9.dist-info/RECORD +0 -55
- kerykeion-5.0.0a9.dist-info/entry_points.txt +0 -2
- {kerykeion-5.0.0a9.dist-info → kerykeion-5.1.8.dist-info}/WHEEL +0 -0
- {kerykeion-5.0.0a9.dist-info → kerykeion-5.1.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,1793 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kerykeion
|
|
3
|
+
Version: 5.1.8
|
|
4
|
+
Summary: A Python library for astrological calculations, including natal charts, houses, planetary aspects, and SVG chart generation.
|
|
5
|
+
Project-URL: Homepage, https://www.kerykeion.net/
|
|
6
|
+
Project-URL: Repository, https://github.com/g-battaglia/kerykeion
|
|
7
|
+
Author-email: Giacomo Battaglia <kerykeion.astrology@gmail.com>
|
|
8
|
+
License: AGPL-3.0
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: astrology,astrology calculations,astrology calculator,astrology library,astrology transits,astronomical algorithms,birth chart,ephemeris,houses of astrology,natal chart,planetary aspects,svg charts,synastry,zodiac,zodiac signs
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Religion
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
26
|
+
Classifier: Topic :: Software Development
|
|
27
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
28
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
29
|
+
Classifier: Typing :: Typed
|
|
30
|
+
Requires-Python: >=3.9
|
|
31
|
+
Requires-Dist: pydantic>=2.5
|
|
32
|
+
Requires-Dist: pyswisseph>=2.10.3.1
|
|
33
|
+
Requires-Dist: pytz>=2024.2
|
|
34
|
+
Requires-Dist: requests-cache>=1.2.1
|
|
35
|
+
Requires-Dist: requests>=2.32.3
|
|
36
|
+
Requires-Dist: scour>=0.38.2
|
|
37
|
+
Requires-Dist: simple-ascii-tables>=1.0.0
|
|
38
|
+
Requires-Dist: typing-extensions>=4.12.2
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
<h1 align="center">Kerykeion</h1>
|
|
42
|
+
|
|
43
|
+
<div align="center">
|
|
44
|
+
<img src="https://img.shields.io/github/stars/g-battaglia/kerykeion.svg?logo=github" alt="stars">
|
|
45
|
+
<img src="https://img.shields.io/github/forks/g-battaglia/kerykeion.svg?logo=github" alt="forks">
|
|
46
|
+
</div>
|
|
47
|
+
<div align="center">
|
|
48
|
+
<img src="https://static.pepy.tech/badge/kerykeion/month" alt="PyPI Downloads">
|
|
49
|
+
<img src="https://static.pepy.tech/badge/kerykeion/week" alt="PyPI Downloads">
|
|
50
|
+
<img src="https://static.pepy.tech/personalized-badge/kerykeion?period=total&units=INTERNATIONAL_SYSTEM&left_color=GREY&right_color=BLUE&left_text=downloads/total" alt="PyPI Downloads">
|
|
51
|
+
</div>
|
|
52
|
+
<div align="center">
|
|
53
|
+
<img src="https://img.shields.io/pypi/v/kerykeion?label=pypi%20package" alt="Package version">
|
|
54
|
+
<img src="https://img.shields.io/pypi/pyversions/kerykeion.svg" alt="Supported Python versions">
|
|
55
|
+
</div>
|
|
56
|
+
<p align="center">⭐ Like this project? Star it on GitHub and help it grow! ⭐</p>
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
Kerykeion is a Python library for astrology. It computes planetary and house positions, detects aspects, and generates SVG charts—including birth, synastry, transit, and composite charts. You can also customize which planets to include in your calculations.
|
|
60
|
+
|
|
61
|
+
The main goal of this project is to offer a clean, data-driven approach to astrology, making it accessible and programmable.
|
|
62
|
+
|
|
63
|
+
Kerykeion also integrates seamlessly with LLM and AI applications.
|
|
64
|
+
|
|
65
|
+
Here is an example of a birthchart:
|
|
66
|
+
|
|
67
|
+

|
|
68
|
+
|
|
69
|
+
## **Web API**
|
|
70
|
+
|
|
71
|
+
If you want to use Kerykeion in a web application or for commercial or *closed-source* purposes, you can try the dedicated web API:
|
|
72
|
+
|
|
73
|
+
**[AstrologerAPI](https://rapidapi.com/gbattaglia/api/astrologer/pricing)**
|
|
74
|
+
|
|
75
|
+
It is [open source](https://github.com/g-battaglia/Astrologer-API) and directly supports this project.
|
|
76
|
+
|
|
77
|
+
## **Donate**
|
|
78
|
+
|
|
79
|
+
Maintaining this project requires substantial time and effort. The Astrologer API alone cannot cover the costs of full-time development. If you find Kerykeion valuable and would like to support further development, please consider donating:
|
|
80
|
+
|
|
81
|
+
[](https://ko-fi.com/kerykeion)
|
|
82
|
+
|
|
83
|
+
## Table of Contents
|
|
84
|
+
|
|
85
|
+
- [**Web API**](#web-api)
|
|
86
|
+
- [**Donate**](#donate)
|
|
87
|
+
- [Table of Contents](#table-of-contents)
|
|
88
|
+
- [Installation](#installation)
|
|
89
|
+
- [Quick Start](#quick-start)
|
|
90
|
+
- [Documentation Map](#documentation-map)
|
|
91
|
+
- [Basic Usage](#basic-usage)
|
|
92
|
+
- [Generate a SVG Chart](#generate-a-svg-chart)
|
|
93
|
+
- [Birth Chart](#birth-chart)
|
|
94
|
+
- [External Birth Chart](#external-birth-chart)
|
|
95
|
+
- [Synastry Chart](#synastry-chart)
|
|
96
|
+
- [Transit Chart](#transit-chart)
|
|
97
|
+
- [Solar Return Chart (Dual Wheel)](#solar-return-chart-dual-wheel)
|
|
98
|
+
- [Solar Return Chart (Single Wheel)](#solar-return-chart-single-wheel)
|
|
99
|
+
- [Lunar Return Chart](#lunar-return-chart)
|
|
100
|
+
- [Composite Chart](#composite-chart)
|
|
101
|
+
- [Wheel Only Charts](#wheel-only-charts)
|
|
102
|
+
- [Birth Chart](#birth-chart-1)
|
|
103
|
+
- [Wheel Only Birth Chart (External)](#wheel-only-birth-chart-external)
|
|
104
|
+
- [Synastry Chart](#synastry-chart-1)
|
|
105
|
+
- [Change the Output Directory](#change-the-output-directory)
|
|
106
|
+
- [Change Language](#change-language)
|
|
107
|
+
- [Minified SVG](#minified-svg)
|
|
108
|
+
- [SVG without CSS Variables](#svg-without-css-variables)
|
|
109
|
+
- [Grid Only SVG](#grid-only-svg)
|
|
110
|
+
- [Report Generator](#report-generator)
|
|
111
|
+
- [Quick Examples](#quick-examples)
|
|
112
|
+
- [Section Access](#section-access)
|
|
113
|
+
- [Example: Retrieving Aspects](#example-retrieving-aspects)
|
|
114
|
+
- [Element \& Quality Distribution Strategies](#element--quality-distribution-strategies)
|
|
115
|
+
- [Ayanamsa (Sidereal Modes)](#ayanamsa-sidereal-modes)
|
|
116
|
+
- [House Systems](#house-systems)
|
|
117
|
+
- [Perspective Type](#perspective-type)
|
|
118
|
+
- [Themes](#themes)
|
|
119
|
+
- [Alternative Initialization](#alternative-initialization)
|
|
120
|
+
- [Lunar Nodes (Rahu \& Ketu)](#lunar-nodes-rahu--ketu)
|
|
121
|
+
- [JSON Support](#json-support)
|
|
122
|
+
- [Auto Generated Documentation](#auto-generated-documentation)
|
|
123
|
+
- [Development](#development)
|
|
124
|
+
- [Kerykeion v5.0 – What's New](#kerykeion-v50--whats-new)
|
|
125
|
+
- [🎯 Key Highlights](#-key-highlights)
|
|
126
|
+
- [Factory-Centered Architecture](#factory-centered-architecture)
|
|
127
|
+
- [Pydantic 2 Models \& Type Safety](#pydantic-2-models--type-safety)
|
|
128
|
+
- [Enhanced Features](#enhanced-features)
|
|
129
|
+
- [🚨 Breaking Changes](#-breaking-changes)
|
|
130
|
+
- [1. Removed Legacy Classes](#1-removed-legacy-classes)
|
|
131
|
+
- [2. Import Changes](#2-import-changes)
|
|
132
|
+
- [3. Type Aliases Unified](#3-type-aliases-unified)
|
|
133
|
+
- [4. Lunar Nodes Naming](#4-lunar-nodes-naming)
|
|
134
|
+
- [5. Axis Orb Filtering](#5-axis-orb-filtering)
|
|
135
|
+
- [6. Chart Generation Changes](#6-chart-generation-changes)
|
|
136
|
+
- [7. Aspects API Changes](#7-aspects-api-changes)
|
|
137
|
+
- [🔄 Migration Guide](#-migration-guide)
|
|
138
|
+
- [Using the Backward Compatibility Layer](#using-the-backward-compatibility-layer)
|
|
139
|
+
- [Step-by-Step Migration](#step-by-step-migration)
|
|
140
|
+
- [Automated Migration Script](#automated-migration-script)
|
|
141
|
+
- [📦 Other Notable Changes](#-other-notable-changes)
|
|
142
|
+
- [🎨 New Themes](#-new-themes)
|
|
143
|
+
- [📚 Resources](#-resources)
|
|
144
|
+
- [Integrating Kerykeion into Your Project](#integrating-kerykeion-into-your-project)
|
|
145
|
+
- [License](#license)
|
|
146
|
+
- [Contributing](#contributing)
|
|
147
|
+
- [Citations](#citations)
|
|
148
|
+
|
|
149
|
+
## Installation
|
|
150
|
+
|
|
151
|
+
Kerykeion requires **Python 3.9** or higher.
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pip3 install kerykeion
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Quick Start
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from pathlib import Path
|
|
161
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
162
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
163
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
164
|
+
|
|
165
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
166
|
+
name="Example Person",
|
|
167
|
+
year=1990, month=7, day=15,
|
|
168
|
+
hour=10, minute=30,
|
|
169
|
+
lng=12.4964,
|
|
170
|
+
lat=41.9028,
|
|
171
|
+
tz_str="Europe/Rome",
|
|
172
|
+
online=False,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
chart_data = ChartDataFactory.create_natal_chart_data(subject)
|
|
176
|
+
chart_drawer = ChartDrawer(chart_data=chart_data)
|
|
177
|
+
|
|
178
|
+
output_dir = Path("charts_output")
|
|
179
|
+
output_dir.mkdir(exist_ok=True)
|
|
180
|
+
|
|
181
|
+
chart_drawer.save_svg(output_path=output_dir, filename="example-natal")
|
|
182
|
+
print("Chart saved to", (output_dir / "example-natal.svg").resolve())
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
This script shows the recommended workflow:
|
|
186
|
+
1. Create an `AstrologicalSubject` with explicit coordinates and timezone (offline mode).
|
|
187
|
+
2. Build a `ChartDataModel` through `ChartDataFactory`.
|
|
188
|
+
3. Render the SVG via `ChartDrawer`, saving it to a controlled folder (`charts_output`).
|
|
189
|
+
|
|
190
|
+
Use the same pattern for synastry, composite, transit, or return charts by swapping the factory method.
|
|
191
|
+
|
|
192
|
+
## Documentation Map
|
|
193
|
+
|
|
194
|
+
- **README (this file):** Quick start, common recipes, and v5 migration notes.
|
|
195
|
+
- **`site-docs/` (offline Markdown guides):** Deep dives for each factory (`chart_data_factory.md`, `charts.md`, `planetary_return_factory.md`, etc.) with runnable snippets. Run `python scripts/test_markdown_snippets.py site-docs` to validate them locally.
|
|
196
|
+
- **[Auto-generated API Reference](https://www.kerykeion.net/pydocs/kerykeion.html):** Detailed model and function signatures straight from the codebase.
|
|
197
|
+
- **[Kerykeion website](https://www.kerykeion.net/docs/):** Rendered documentation with additional context, tutorials, and showcase material.
|
|
198
|
+
|
|
199
|
+
## Basic Usage
|
|
200
|
+
|
|
201
|
+
Below is a simple example illustrating the creation of an astrological subject and retrieving astrological details:
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
205
|
+
|
|
206
|
+
# Create an instance of the AstrologicalSubjectFactory class.
|
|
207
|
+
# Arguments: Name, year, month, day, hour, minutes, city, nation
|
|
208
|
+
john = AstrologicalSubjectFactory.from_birth_data(
|
|
209
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
210
|
+
lng=-2.9833,
|
|
211
|
+
lat=53.4,
|
|
212
|
+
tz_str="Europe/London",
|
|
213
|
+
online=False,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
# Retrieve information about the Sun:
|
|
217
|
+
print(john.sun.model_dump_json())
|
|
218
|
+
# > {"name":"Sun","quality":"Cardinal","element":"Air","sign":"Lib","sign_num":6,"position":16.26789199474399,"abs_pos":196.267891994744,"emoji":"♎️","point_type":"AstrologicalPoint","house":"Sixth_House","retrograde":false}
|
|
219
|
+
|
|
220
|
+
# Retrieve information about the first house:
|
|
221
|
+
print(john.first_house.model_dump_json())
|
|
222
|
+
# > {"name":"First_House","quality":"Cardinal","element":"Fire","sign":"Ari","sign_num":0,"position":19.74676624176799,"abs_pos":19.74676624176799,"emoji":"♈️","point_type":"House","house":null,"retrograde":null}
|
|
223
|
+
|
|
224
|
+
# Retrieve the element of the Moon sign:
|
|
225
|
+
print(john.moon.element)
|
|
226
|
+
# > 'Air'
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
> **Working offline:** pass `online=False` and specify `lng`, `lat`, and `tz_str` as shown above.
|
|
230
|
+
> **Working online:** set `online=True` and provide `city`, `nation`, and a valid GeoNames username (see `AstrologicalSubjectFactory.from_birth_data()` for details).
|
|
231
|
+
|
|
232
|
+
**To avoid using GeoNames online, specify longitude, latitude, and timezone instead of city and nation:**
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
john = AstrologicalSubjectFactory.from_birth_data(
|
|
236
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
237
|
+
lng=-2.9833, # Longitude for Liverpool
|
|
238
|
+
lat=53.4000, # Latitude for Liverpool
|
|
239
|
+
tz_str="Europe/London", # Timezone for Liverpool
|
|
240
|
+
city="Liverpool",
|
|
241
|
+
)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Generate a SVG Chart
|
|
245
|
+
|
|
246
|
+
All chart-rendering examples below create a local `charts_output/` folder so the tests can write without touching your home directory. Feel free to change the path when integrating into your own projects.
|
|
247
|
+
|
|
248
|
+
To generate a chart, use the `ChartDataFactory` to pre-compute chart data, then `ChartDrawer` to create the visualization. This two-step process ensures clean separation between astrological calculations and chart rendering.
|
|
249
|
+
|
|
250
|
+
**Tip:**
|
|
251
|
+
The optimized way to open the generated SVG files is with a web browser (e.g., Chrome, Firefox).
|
|
252
|
+
To improve compatibility across different applications, you can use the `remove_css_variables` parameter when generating the SVG. This will inline all styles and eliminate CSS variables, resulting in an SVG that is more broadly supported.
|
|
253
|
+
|
|
254
|
+
### Birth Chart
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
from pathlib import Path
|
|
258
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
259
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
260
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
261
|
+
|
|
262
|
+
# Step 1: Create subject
|
|
263
|
+
john = AstrologicalSubjectFactory.from_birth_data(
|
|
264
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
265
|
+
lng=-2.9833,
|
|
266
|
+
lat=53.4,
|
|
267
|
+
tz_str="Europe/London",
|
|
268
|
+
online=False,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
# Step 2: Pre-compute chart data
|
|
272
|
+
chart_data = ChartDataFactory.create_natal_chart_data(john)
|
|
273
|
+
|
|
274
|
+
# Step 3: Create visualization
|
|
275
|
+
birth_chart_svg = ChartDrawer(chart_data=chart_data)
|
|
276
|
+
|
|
277
|
+
output_dir = Path("charts_output")
|
|
278
|
+
output_dir.mkdir(exist_ok=True)
|
|
279
|
+
birth_chart_svg.save_svg(output_path=output_dir, filename="john-lennon-natal")
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
The SVG file is saved under `charts_output/john-lennon-natal.svg`.
|
|
283
|
+

|
|
284
|
+
|
|
285
|
+
### External Birth Chart
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
from pathlib import Path
|
|
289
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
290
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
291
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
292
|
+
|
|
293
|
+
# Step 1: Create subject
|
|
294
|
+
birth_chart = AstrologicalSubjectFactory.from_birth_data(
|
|
295
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
296
|
+
lng=-2.9833,
|
|
297
|
+
lat=53.4,
|
|
298
|
+
tz_str="Europe/London",
|
|
299
|
+
online=False,
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
# Step 2: Pre-compute chart data for external natal chart
|
|
303
|
+
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
|
|
304
|
+
|
|
305
|
+
# Step 3: Create visualization
|
|
306
|
+
birth_chart_svg = ChartDrawer(chart_data=chart_data)
|
|
307
|
+
|
|
308
|
+
output_dir = Path("charts_output")
|
|
309
|
+
output_dir.mkdir(exist_ok=True)
|
|
310
|
+
birth_chart_svg.save_svg(output_path=output_dir, filename="john-lennon-natal-external")
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+

|
|
314
|
+
|
|
315
|
+
### Synastry Chart
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
from pathlib import Path
|
|
319
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
320
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
321
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
322
|
+
|
|
323
|
+
# Step 1: Create subjects
|
|
324
|
+
first = AstrologicalSubjectFactory.from_birth_data(
|
|
325
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
326
|
+
lng=-2.9833,
|
|
327
|
+
lat=53.4,
|
|
328
|
+
tz_str="Europe/London",
|
|
329
|
+
online=False,
|
|
330
|
+
)
|
|
331
|
+
second = AstrologicalSubjectFactory.from_birth_data(
|
|
332
|
+
"Paul McCartney", 1942, 6, 18, 15, 30,
|
|
333
|
+
lng=-2.9833,
|
|
334
|
+
lat=53.4,
|
|
335
|
+
tz_str="Europe/London",
|
|
336
|
+
online=False,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
# Step 2: Pre-compute synastry chart data
|
|
340
|
+
chart_data = ChartDataFactory.create_synastry_chart_data(first, second)
|
|
341
|
+
|
|
342
|
+
# Step 3: Create visualization
|
|
343
|
+
synastry_chart = ChartDrawer(chart_data=chart_data)
|
|
344
|
+
|
|
345
|
+
output_dir = Path("charts_output")
|
|
346
|
+
output_dir.mkdir(exist_ok=True)
|
|
347
|
+
synastry_chart.save_svg(output_path=output_dir, filename="lennon-mccartney-synastry")
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+

|
|
351
|
+
|
|
352
|
+
### Transit Chart
|
|
353
|
+
|
|
354
|
+
```python
|
|
355
|
+
from pathlib import Path
|
|
356
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
357
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
358
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
359
|
+
|
|
360
|
+
# Step 1: Create subjects
|
|
361
|
+
transit = AstrologicalSubjectFactory.from_birth_data(
|
|
362
|
+
"Transit", 2025, 6, 8, 8, 45,
|
|
363
|
+
lng=-84.3880,
|
|
364
|
+
lat=33.7490,
|
|
365
|
+
tz_str="America/New_York",
|
|
366
|
+
online=False,
|
|
367
|
+
)
|
|
368
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
369
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
370
|
+
lng=-2.9833,
|
|
371
|
+
lat=53.4,
|
|
372
|
+
tz_str="Europe/London",
|
|
373
|
+
online=False,
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
# Step 2: Pre-compute transit chart data
|
|
377
|
+
chart_data = ChartDataFactory.create_transit_chart_data(subject, transit)
|
|
378
|
+
|
|
379
|
+
# Step 3: Create visualization
|
|
380
|
+
transit_chart = ChartDrawer(chart_data=chart_data)
|
|
381
|
+
|
|
382
|
+
output_dir = Path("charts_output")
|
|
383
|
+
output_dir.mkdir(exist_ok=True)
|
|
384
|
+
transit_chart.save_svg(output_path=output_dir, filename="john-lennon-transit")
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+

|
|
388
|
+
|
|
389
|
+
### Solar Return Chart (Dual Wheel)
|
|
390
|
+
|
|
391
|
+
```python
|
|
392
|
+
from pathlib import Path
|
|
393
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
394
|
+
from kerykeion.planetary_return_factory import PlanetaryReturnFactory
|
|
395
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
396
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
397
|
+
|
|
398
|
+
# Step 1: Create natal subject
|
|
399
|
+
john = AstrologicalSubjectFactory.from_birth_data(
|
|
400
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
401
|
+
lng=-2.9833,
|
|
402
|
+
lat=53.4,
|
|
403
|
+
tz_str="Europe/London",
|
|
404
|
+
online=False,
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
# Step 2: Calculate Solar Return subject (offline example with manual coordinates)
|
|
408
|
+
return_factory = PlanetaryReturnFactory(
|
|
409
|
+
john,
|
|
410
|
+
lng=-2.9833,
|
|
411
|
+
lat=53.4000,
|
|
412
|
+
tz_str="Europe/London",
|
|
413
|
+
online=False
|
|
414
|
+
)
|
|
415
|
+
solar_return_subject = return_factory.next_return_from_year(1964, "Solar")
|
|
416
|
+
|
|
417
|
+
# Step 3: Pre-compute return chart data (dual wheel: natal + solar return)
|
|
418
|
+
chart_data = ChartDataFactory.create_return_chart_data(john, solar_return_subject)
|
|
419
|
+
|
|
420
|
+
# Step 4: Create visualization
|
|
421
|
+
solar_return_chart = ChartDrawer(chart_data=chart_data)
|
|
422
|
+
|
|
423
|
+
output_dir = Path("charts_output")
|
|
424
|
+
output_dir.mkdir(exist_ok=True)
|
|
425
|
+
solar_return_chart.save_svg(output_path=output_dir, filename="john-lennon-solar-return-dual")
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+

|
|
429
|
+
|
|
430
|
+
### Solar Return Chart (Single Wheel)
|
|
431
|
+
|
|
432
|
+
```python
|
|
433
|
+
from pathlib import Path
|
|
434
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
435
|
+
from kerykeion.planetary_return_factory import PlanetaryReturnFactory
|
|
436
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
437
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
438
|
+
|
|
439
|
+
# Step 1: Create natal subject
|
|
440
|
+
john = AstrologicalSubjectFactory.from_birth_data(
|
|
441
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
442
|
+
lng=-2.9833,
|
|
443
|
+
lat=53.4,
|
|
444
|
+
tz_str="Europe/London",
|
|
445
|
+
online=False,
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
# Step 2: Calculate Solar Return subject (offline example with manual coordinates)
|
|
449
|
+
return_factory = PlanetaryReturnFactory(
|
|
450
|
+
john,
|
|
451
|
+
lng=-2.9833,
|
|
452
|
+
lat=53.4000,
|
|
453
|
+
tz_str="Europe/London",
|
|
454
|
+
online=False
|
|
455
|
+
)
|
|
456
|
+
solar_return_subject = return_factory.next_return_from_year(1964, "Solar")
|
|
457
|
+
|
|
458
|
+
# Step 3: Build a single-wheel return chart
|
|
459
|
+
chart_data = ChartDataFactory.create_single_wheel_return_chart_data(solar_return_subject)
|
|
460
|
+
|
|
461
|
+
# Step 4: Create visualization
|
|
462
|
+
single_wheel_chart = ChartDrawer(chart_data=chart_data)
|
|
463
|
+
|
|
464
|
+
output_dir = Path("charts_output")
|
|
465
|
+
output_dir.mkdir(exist_ok=True)
|
|
466
|
+
single_wheel_chart.save_svg(output_path=output_dir, filename="john-lennon-solar-return-single")
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+

|
|
470
|
+
|
|
471
|
+
### Lunar Return Chart
|
|
472
|
+
|
|
473
|
+
```python
|
|
474
|
+
from pathlib import Path
|
|
475
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
476
|
+
from kerykeion.planetary_return_factory import PlanetaryReturnFactory
|
|
477
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
478
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
479
|
+
|
|
480
|
+
# Step 1: Create natal subject
|
|
481
|
+
john = AstrologicalSubjectFactory.from_birth_data(
|
|
482
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
483
|
+
lng=-2.9833,
|
|
484
|
+
lat=53.4,
|
|
485
|
+
tz_str="Europe/London",
|
|
486
|
+
online=False,
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
# Step 2: Calculate Lunar Return subject
|
|
490
|
+
return_factory = PlanetaryReturnFactory(
|
|
491
|
+
john,
|
|
492
|
+
lng=-2.9833,
|
|
493
|
+
lat=53.4000,
|
|
494
|
+
tz_str="Europe/London",
|
|
495
|
+
online=False
|
|
496
|
+
)
|
|
497
|
+
lunar_return_subject = return_factory.next_return_from_year(1964, "Lunar")
|
|
498
|
+
|
|
499
|
+
# Step 3: Build a dual wheel (natal + lunar return)
|
|
500
|
+
lunar_return_chart_data = ChartDataFactory.create_return_chart_data(john, lunar_return_subject)
|
|
501
|
+
dual_wheel_chart = ChartDrawer(chart_data=lunar_return_chart_data)
|
|
502
|
+
|
|
503
|
+
output_dir = Path("charts_output")
|
|
504
|
+
output_dir.mkdir(exist_ok=True)
|
|
505
|
+
dual_wheel_chart.save_svg(output_path=output_dir, filename="john-lennon-lunar-return-dual")
|
|
506
|
+
|
|
507
|
+
# Optional: create a single-wheel lunar return
|
|
508
|
+
single_wheel_data = ChartDataFactory.create_single_wheel_return_chart_data(lunar_return_subject)
|
|
509
|
+
single_wheel_chart = ChartDrawer(chart_data=single_wheel_data)
|
|
510
|
+
single_wheel_chart.save_svg(output_path=output_dir, filename="john-lennon-lunar-return-single")
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+

|
|
514
|
+
|
|
515
|
+

|
|
516
|
+
|
|
517
|
+
### Composite Chart
|
|
518
|
+
|
|
519
|
+
```python
|
|
520
|
+
from pathlib import Path
|
|
521
|
+
from kerykeion import CompositeSubjectFactory, AstrologicalSubjectFactory
|
|
522
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
523
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
524
|
+
|
|
525
|
+
# Step 1: Create subjects (offline configuration)
|
|
526
|
+
angelina = AstrologicalSubjectFactory.from_birth_data(
|
|
527
|
+
"Angelina Jolie", 1975, 6, 4, 9, 9,
|
|
528
|
+
lng=-118.2437,
|
|
529
|
+
lat=34.0522,
|
|
530
|
+
tz_str="America/Los_Angeles",
|
|
531
|
+
online=False,
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
brad = AstrologicalSubjectFactory.from_birth_data(
|
|
535
|
+
"Brad Pitt", 1963, 12, 18, 6, 31,
|
|
536
|
+
lng=-96.7069,
|
|
537
|
+
lat=35.3273,
|
|
538
|
+
tz_str="America/Chicago",
|
|
539
|
+
online=False,
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
# Step 2: Create composite subject
|
|
543
|
+
factory = CompositeSubjectFactory(angelina, brad)
|
|
544
|
+
composite_model = factory.get_midpoint_composite_subject_model()
|
|
545
|
+
|
|
546
|
+
# Step 3: Pre-compute composite chart data
|
|
547
|
+
chart_data = ChartDataFactory.create_composite_chart_data(composite_model)
|
|
548
|
+
|
|
549
|
+
# Step 4: Create visualization
|
|
550
|
+
composite_chart = ChartDrawer(chart_data=chart_data)
|
|
551
|
+
|
|
552
|
+
output_dir = Path("charts_output")
|
|
553
|
+
output_dir.mkdir(exist_ok=True)
|
|
554
|
+
composite_chart.save_svg(output_path=output_dir, filename="jolie-pitt-composite")
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+

|
|
558
|
+
|
|
559
|
+
## Wheel Only Charts
|
|
560
|
+
|
|
561
|
+
For _all_ the charts, you can generate a wheel-only chart by using the method `makeWheelOnlySVG()`:
|
|
562
|
+
|
|
563
|
+
### Birth Chart
|
|
564
|
+
|
|
565
|
+
```python
|
|
566
|
+
from pathlib import Path
|
|
567
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
568
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
569
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
570
|
+
|
|
571
|
+
# Step 1: Create subject
|
|
572
|
+
birth_chart = AstrologicalSubjectFactory.from_birth_data(
|
|
573
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
574
|
+
lng=-2.9833,
|
|
575
|
+
lat=53.4,
|
|
576
|
+
tz_str="Europe/London",
|
|
577
|
+
online=False,
|
|
578
|
+
)
|
|
579
|
+
|
|
580
|
+
# Step 2: Pre-compute chart data
|
|
581
|
+
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
|
|
582
|
+
|
|
583
|
+
# Step 3: Create visualization
|
|
584
|
+
birth_chart_svg = ChartDrawer(chart_data=chart_data)
|
|
585
|
+
|
|
586
|
+
output_dir = Path("charts_output")
|
|
587
|
+
output_dir.mkdir(exist_ok=True)
|
|
588
|
+
birth_chart_svg.save_wheel_only_svg_file(output_path=output_dir, filename="john-lennon-natal-wheel")
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+

|
|
592
|
+
|
|
593
|
+
### Wheel Only Birth Chart (External)
|
|
594
|
+
|
|
595
|
+
```python
|
|
596
|
+
from pathlib import Path
|
|
597
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
598
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
599
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
600
|
+
|
|
601
|
+
# Step 1: Create subject
|
|
602
|
+
birth_chart = AstrologicalSubjectFactory.from_birth_data(
|
|
603
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
604
|
+
lng=-2.9833,
|
|
605
|
+
lat=53.4,
|
|
606
|
+
tz_str="Europe/London",
|
|
607
|
+
online=False,
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
# Step 2: Pre-compute external natal chart data
|
|
611
|
+
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
|
|
612
|
+
|
|
613
|
+
# Step 3: Create visualization (external wheel view)
|
|
614
|
+
birth_chart_svg = ChartDrawer(chart_data=chart_data, external_view=True)
|
|
615
|
+
|
|
616
|
+
output_dir = Path("charts_output")
|
|
617
|
+
output_dir.mkdir(exist_ok=True)
|
|
618
|
+
birth_chart_svg.save_wheel_only_svg_file(output_path=output_dir, filename="john-lennon-natal-wheel-external")
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+

|
|
622
|
+
|
|
623
|
+
### Synastry Chart
|
|
624
|
+
|
|
625
|
+
```python
|
|
626
|
+
from pathlib import Path
|
|
627
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
628
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
629
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
630
|
+
|
|
631
|
+
# Step 1: Create subjects
|
|
632
|
+
first = AstrologicalSubjectFactory.from_birth_data(
|
|
633
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
634
|
+
lng=-2.9833,
|
|
635
|
+
lat=53.4,
|
|
636
|
+
tz_str="Europe/London",
|
|
637
|
+
online=False,
|
|
638
|
+
)
|
|
639
|
+
second = AstrologicalSubjectFactory.from_birth_data(
|
|
640
|
+
"Paul McCartney", 1942, 6, 18, 15, 30,
|
|
641
|
+
lng=-2.9833,
|
|
642
|
+
lat=53.4,
|
|
643
|
+
tz_str="Europe/London",
|
|
644
|
+
online=False,
|
|
645
|
+
)
|
|
646
|
+
|
|
647
|
+
# Step 2: Pre-compute synastry chart data
|
|
648
|
+
chart_data = ChartDataFactory.create_synastry_chart_data(first, second)
|
|
649
|
+
|
|
650
|
+
# Step 3: Create visualization
|
|
651
|
+
synastry_chart = ChartDrawer(chart_data=chart_data)
|
|
652
|
+
|
|
653
|
+
output_dir = Path("charts_output")
|
|
654
|
+
output_dir.mkdir(exist_ok=True)
|
|
655
|
+
synastry_chart.save_wheel_only_svg_file(output_path=output_dir, filename="lennon-mccartney-synastry-wheel")
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+

|
|
659
|
+
|
|
660
|
+
### Change the Output Directory
|
|
661
|
+
|
|
662
|
+
To save the SVG file in a custom location, specify the `output_path` parameter in `save_svg()`:
|
|
663
|
+
|
|
664
|
+
```python
|
|
665
|
+
from pathlib import Path
|
|
666
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
667
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
668
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
669
|
+
|
|
670
|
+
# Step 1: Create subjects
|
|
671
|
+
first = AstrologicalSubjectFactory.from_birth_data(
|
|
672
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
673
|
+
lng=-2.9833,
|
|
674
|
+
lat=53.4,
|
|
675
|
+
tz_str="Europe/London",
|
|
676
|
+
online=False,
|
|
677
|
+
)
|
|
678
|
+
second = AstrologicalSubjectFactory.from_birth_data(
|
|
679
|
+
"Paul McCartney", 1942, 6, 18, 15, 30,
|
|
680
|
+
lng=-2.9833,
|
|
681
|
+
lat=53.4,
|
|
682
|
+
tz_str="Europe/London",
|
|
683
|
+
online=False,
|
|
684
|
+
)
|
|
685
|
+
|
|
686
|
+
# Step 2: Pre-compute synastry chart data
|
|
687
|
+
chart_data = ChartDataFactory.create_synastry_chart_data(first, second)
|
|
688
|
+
|
|
689
|
+
# Step 3: Create visualization with custom output directory
|
|
690
|
+
synastry_chart = ChartDrawer(chart_data=chart_data)
|
|
691
|
+
|
|
692
|
+
output_dir = Path("my_charts")
|
|
693
|
+
output_dir.mkdir(exist_ok=True)
|
|
694
|
+
synastry_chart.save_svg(output_path=output_dir)
|
|
695
|
+
print("Saved to", (output_dir / f"{synastry_chart.first_obj.name} - Synastry Chart.svg").resolve())
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
### Change Language
|
|
699
|
+
|
|
700
|
+
You can switch chart language by passing `chart_language` to the `ChartDrawer` class:
|
|
701
|
+
|
|
702
|
+
```python
|
|
703
|
+
from pathlib import Path
|
|
704
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
705
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
706
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
707
|
+
|
|
708
|
+
# Step 1: Create subject
|
|
709
|
+
birth_chart = AstrologicalSubjectFactory.from_birth_data(
|
|
710
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
711
|
+
lng=-2.9833,
|
|
712
|
+
lat=53.4,
|
|
713
|
+
tz_str="Europe/London",
|
|
714
|
+
online=False,
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
# Step 2: Pre-compute chart data
|
|
718
|
+
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
|
|
719
|
+
|
|
720
|
+
# Step 3: Create visualization with Italian language
|
|
721
|
+
birth_chart_svg = ChartDrawer(
|
|
722
|
+
chart_data=chart_data,
|
|
723
|
+
chart_language="IT" # Change to Italian
|
|
724
|
+
)
|
|
725
|
+
|
|
726
|
+
output_dir = Path("charts_output")
|
|
727
|
+
output_dir.mkdir(exist_ok=True)
|
|
728
|
+
birth_chart_svg.save_svg(output_path=output_dir, filename="john-lennon-natal-it")
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
You can also provide custom labels (or introduce a brand-new language) by passing
|
|
732
|
+
a dictionary to `language_pack`. Only the keys you supply are merged on top of the
|
|
733
|
+
built-in strings:
|
|
734
|
+
|
|
735
|
+
```python
|
|
736
|
+
from pathlib import Path
|
|
737
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
738
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
739
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
740
|
+
|
|
741
|
+
birth_chart = AstrologicalSubjectFactory.from_birth_data(
|
|
742
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
743
|
+
lng=-2.9833,
|
|
744
|
+
lat=53.4,
|
|
745
|
+
tz_str="Europe/London",
|
|
746
|
+
online=False,
|
|
747
|
+
)
|
|
748
|
+
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
|
|
749
|
+
|
|
750
|
+
custom_labels = {
|
|
751
|
+
"PT": {
|
|
752
|
+
"info": "Informações",
|
|
753
|
+
"celestial_points": {"Sun": "Sol", "Moon": "Lua"},
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
custom_chart = ChartDrawer(
|
|
758
|
+
chart_data=chart_data,
|
|
759
|
+
chart_language="PT",
|
|
760
|
+
language_pack=custom_labels["PT"],
|
|
761
|
+
)
|
|
762
|
+
|
|
763
|
+
output_dir = Path("charts_output")
|
|
764
|
+
output_dir.mkdir(exist_ok=True)
|
|
765
|
+
custom_chart.save_svg(output_path=output_dir, filename="john-lennon-natal-pt")
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
More details [here](https://www.kerykeion.net/docs/chart-language).
|
|
769
|
+
|
|
770
|
+
The available languages are:
|
|
771
|
+
|
|
772
|
+
- EN (English)
|
|
773
|
+
- FR (French)
|
|
774
|
+
- PT (Portuguese)
|
|
775
|
+
- ES (Spanish)
|
|
776
|
+
- TR (Turkish)
|
|
777
|
+
- RU (Russian)
|
|
778
|
+
- IT (Italian)
|
|
779
|
+
- CN (Chinese)
|
|
780
|
+
- DE (German)
|
|
781
|
+
|
|
782
|
+
### Minified SVG
|
|
783
|
+
|
|
784
|
+
To generate a minified SVG, set `minify_svg=True` in the `makeSVG()` method:
|
|
785
|
+
|
|
786
|
+
```python
|
|
787
|
+
from pathlib import Path
|
|
788
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
789
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
790
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
791
|
+
|
|
792
|
+
# Step 1: Create subject
|
|
793
|
+
birth_chart = AstrologicalSubjectFactory.from_birth_data(
|
|
794
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
795
|
+
lng=-2.9833,
|
|
796
|
+
lat=53.4,
|
|
797
|
+
tz_str="Europe/London",
|
|
798
|
+
online=False,
|
|
799
|
+
)
|
|
800
|
+
|
|
801
|
+
# Step 2: Pre-compute chart data
|
|
802
|
+
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
|
|
803
|
+
|
|
804
|
+
# Step 3: Create visualization
|
|
805
|
+
birth_chart_svg = ChartDrawer(chart_data=chart_data)
|
|
806
|
+
|
|
807
|
+
output_dir = Path("charts_output")
|
|
808
|
+
output_dir.mkdir(exist_ok=True)
|
|
809
|
+
birth_chart_svg.save_svg(
|
|
810
|
+
output_path=output_dir,
|
|
811
|
+
filename="john-lennon-natal-minified",
|
|
812
|
+
minify=True,
|
|
813
|
+
)
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
### SVG without CSS Variables
|
|
817
|
+
|
|
818
|
+
To generate an SVG without CSS variables, set `remove_css_variables=True` in the `makeSVG()` method:
|
|
819
|
+
|
|
820
|
+
```python
|
|
821
|
+
from pathlib import Path
|
|
822
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
823
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
824
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
825
|
+
|
|
826
|
+
# Step 1: Create subject
|
|
827
|
+
birth_chart = AstrologicalSubjectFactory.from_birth_data(
|
|
828
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
829
|
+
lng=-2.9833,
|
|
830
|
+
lat=53.4,
|
|
831
|
+
tz_str="Europe/London",
|
|
832
|
+
online=False,
|
|
833
|
+
)
|
|
834
|
+
|
|
835
|
+
# Step 2: Pre-compute chart data
|
|
836
|
+
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
|
|
837
|
+
|
|
838
|
+
# Step 3: Create visualization
|
|
839
|
+
birth_chart_svg = ChartDrawer(chart_data=chart_data)
|
|
840
|
+
|
|
841
|
+
output_dir = Path("charts_output")
|
|
842
|
+
output_dir.mkdir(exist_ok=True)
|
|
843
|
+
birth_chart_svg.save_svg(
|
|
844
|
+
output_path=output_dir,
|
|
845
|
+
filename="john-lennon-natal-no-css-variables",
|
|
846
|
+
remove_css_variables=True,
|
|
847
|
+
)
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
This will inline all styles and eliminate CSS variables, resulting in an SVG that is more broadly supported.
|
|
851
|
+
|
|
852
|
+
### Grid Only SVG
|
|
853
|
+
|
|
854
|
+
It's possible to generate a grid-only SVG, useful for creating a custom layout. To do this, use the `save_aspect_grid_only_svg_file()` method:
|
|
855
|
+
|
|
856
|
+
```python
|
|
857
|
+
from pathlib import Path
|
|
858
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
859
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
860
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
861
|
+
|
|
862
|
+
# Step 1: Create subjects
|
|
863
|
+
birth_chart = AstrologicalSubjectFactory.from_birth_data(
|
|
864
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
865
|
+
lng=-2.9833,
|
|
866
|
+
lat=53.4,
|
|
867
|
+
tz_str="Europe/London",
|
|
868
|
+
online=False,
|
|
869
|
+
)
|
|
870
|
+
second = AstrologicalSubjectFactory.from_birth_data(
|
|
871
|
+
"Paul McCartney", 1942, 6, 18, 15, 30,
|
|
872
|
+
lng=-2.9833,
|
|
873
|
+
lat=53.4,
|
|
874
|
+
tz_str="Europe/London",
|
|
875
|
+
online=False,
|
|
876
|
+
)
|
|
877
|
+
|
|
878
|
+
# Step 2: Pre-compute synastry chart data
|
|
879
|
+
chart_data = ChartDataFactory.create_synastry_chart_data(birth_chart, second)
|
|
880
|
+
|
|
881
|
+
# Step 3: Create visualization with dark theme
|
|
882
|
+
aspect_grid_chart = ChartDrawer(chart_data=chart_data, theme="dark")
|
|
883
|
+
|
|
884
|
+
output_dir = Path("charts_output")
|
|
885
|
+
output_dir.mkdir(exist_ok=True)
|
|
886
|
+
aspect_grid_chart.save_aspect_grid_only_svg_file(output_path=output_dir, filename="lennon-mccartney-aspect-grid")
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+

|
|
890
|
+
|
|
891
|
+
## Report Generator
|
|
892
|
+
|
|
893
|
+
`ReportGenerator` mirrors the chart-type dispatch of `ChartDrawer`. It accepts raw `AstrologicalSubjectModel` instances as well as any `ChartDataModel` produced by `ChartDataFactory`—including natal, composite, synastry, transit, and planetary return charts—and renders the appropriate textual report automatically.
|
|
894
|
+
|
|
895
|
+
### Quick Examples
|
|
896
|
+
|
|
897
|
+
```python
|
|
898
|
+
from kerykeion import ReportGenerator, AstrologicalSubjectFactory, ChartDataFactory
|
|
899
|
+
|
|
900
|
+
# Subject-only report
|
|
901
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
902
|
+
"Sample Natal", 1990, 7, 21, 14, 45,
|
|
903
|
+
lng=12.4964,
|
|
904
|
+
lat=41.9028,
|
|
905
|
+
tz_str="Europe/Rome",
|
|
906
|
+
online=False,
|
|
907
|
+
)
|
|
908
|
+
ReportGenerator(subject).print_report(include_aspects=False)
|
|
909
|
+
|
|
910
|
+
# Single-chart data (elements, qualities, aspects enabled)
|
|
911
|
+
natal_data = ChartDataFactory.create_natal_chart_data(subject)
|
|
912
|
+
ReportGenerator(natal_data).print_report(max_aspects=10)
|
|
913
|
+
|
|
914
|
+
# Dual-chart data (synastry, transit, dual return, …)
|
|
915
|
+
partner = AstrologicalSubjectFactory.from_birth_data(
|
|
916
|
+
"Sample Partner", 1992, 11, 5, 9, 30,
|
|
917
|
+
lng=12.4964,
|
|
918
|
+
lat=41.9028,
|
|
919
|
+
tz_str="Europe/Rome",
|
|
920
|
+
online=False,
|
|
921
|
+
)
|
|
922
|
+
synastry_data = ChartDataFactory.create_synastry_chart_data(subject, partner)
|
|
923
|
+
ReportGenerator(synastry_data).print_report(max_aspects=12)
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
Each report contains:
|
|
927
|
+
|
|
928
|
+
- A chart-aware title summarising the subject(s) and chart type
|
|
929
|
+
- Birth/event metadata and configuration settings
|
|
930
|
+
- Celestial points with sign, position, **daily motion**, **declination**, retrograde flag, and house
|
|
931
|
+
- House cusp tables for every subject involved
|
|
932
|
+
- Lunar phase details when available
|
|
933
|
+
- Element/quality distributions and active configuration summaries (for chart data)
|
|
934
|
+
- Aspect listings tailored for single or dual charts, with symbols for type and movement
|
|
935
|
+
- Dual-chart extras such as house comparisons and relationship scores (when provided by the data)
|
|
936
|
+
|
|
937
|
+
### Section Access
|
|
938
|
+
|
|
939
|
+
All section helpers remain available for targeted output:
|
|
940
|
+
|
|
941
|
+
```python
|
|
942
|
+
from kerykeion import ReportGenerator, AstrologicalSubjectFactory, ChartDataFactory
|
|
943
|
+
|
|
944
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
945
|
+
"Sample Natal", 1990, 7, 21, 14, 45,
|
|
946
|
+
lng=12.4964,
|
|
947
|
+
lat=41.9028,
|
|
948
|
+
tz_str="Europe/Rome",
|
|
949
|
+
online=False,
|
|
950
|
+
)
|
|
951
|
+
natal_data = ChartDataFactory.create_natal_chart_data(subject)
|
|
952
|
+
|
|
953
|
+
report = ReportGenerator(natal_data)
|
|
954
|
+
sections = report.generate_report(max_aspects=5).split("\n\n")
|
|
955
|
+
for section in sections[:3]:
|
|
956
|
+
print(section)
|
|
957
|
+
```
|
|
958
|
+
|
|
959
|
+
Refer to the refreshed [Report Documentation](https://www.kerykeion.net/report/) for end-to-end examples covering every supported chart model.
|
|
960
|
+
|
|
961
|
+
## Example: Retrieving Aspects
|
|
962
|
+
|
|
963
|
+
Kerykeion provides a unified `AspectsFactory` class for calculating astrological aspects within single charts or between two charts:
|
|
964
|
+
|
|
965
|
+
```python
|
|
966
|
+
from kerykeion import AspectsFactory, AstrologicalSubjectFactory
|
|
967
|
+
|
|
968
|
+
# Create astrological subjects
|
|
969
|
+
jack = AstrologicalSubjectFactory.from_birth_data(
|
|
970
|
+
"Jack", 1990, 6, 15, 15, 15,
|
|
971
|
+
lng=12.4964,
|
|
972
|
+
lat=41.9028,
|
|
973
|
+
tz_str="Europe/Rome",
|
|
974
|
+
online=False,
|
|
975
|
+
)
|
|
976
|
+
jane = AstrologicalSubjectFactory.from_birth_data(
|
|
977
|
+
"Jane", 1991, 10, 25, 21, 0,
|
|
978
|
+
lng=12.4964,
|
|
979
|
+
lat=41.9028,
|
|
980
|
+
tz_str="Europe/Rome",
|
|
981
|
+
online=False,
|
|
982
|
+
)
|
|
983
|
+
|
|
984
|
+
# For single chart aspects (natal, return, composite, etc.)
|
|
985
|
+
single_chart_result = AspectsFactory.single_chart_aspects(jack)
|
|
986
|
+
print(f"Found {len(single_chart_result.aspects)} aspects in Jack's chart")
|
|
987
|
+
print(single_chart_result.aspects[0])
|
|
988
|
+
|
|
989
|
+
# For dual chart aspects (synastry, transits, comparisons, etc.)
|
|
990
|
+
dual_chart_result = AspectsFactory.dual_chart_aspects(jack, jane)
|
|
991
|
+
print(f"Found {len(dual_chart_result.aspects)} aspects between Jack and Jane's charts")
|
|
992
|
+
print(dual_chart_result.aspects[0])
|
|
993
|
+
|
|
994
|
+
# Each AspectModel includes:
|
|
995
|
+
# - p1_name, p2_name: Planet/point names
|
|
996
|
+
# - aspect: Aspect type (conjunction, trine, square, etc.)
|
|
997
|
+
# - orbit: Orb tolerance in degrees
|
|
998
|
+
# - aspect_degrees: Exact degrees for the aspect (0, 60, 90, 120, 180, etc.)
|
|
999
|
+
# - color: Hex color code for visualization
|
|
1000
|
+
```
|
|
1001
|
+
|
|
1002
|
+
**Advanced Usage with Custom Settings:**
|
|
1003
|
+
|
|
1004
|
+
```python
|
|
1005
|
+
# You can also customize aspect calculations with custom orb settings
|
|
1006
|
+
from kerykeion.settings.config_constants import DEFAULT_ACTIVE_ASPECTS
|
|
1007
|
+
|
|
1008
|
+
# Modify aspect settings if needed
|
|
1009
|
+
custom_aspects = DEFAULT_ACTIVE_ASPECTS.copy()
|
|
1010
|
+
# ... modify as needed
|
|
1011
|
+
|
|
1012
|
+
# The factory automatically uses the configured settings for orb calculations
|
|
1013
|
+
# and filters aspects based on relevance and orb thresholds
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
## Element & Quality Distribution Strategies
|
|
1017
|
+
|
|
1018
|
+
`ChartDataFactory` now offers two strategies for calculating element and modality totals. The default `"weighted"` mode leans on a curated map that emphasises core factors (for example `sun`, `moon`, and `ascendant` weight 2.0, angles such as `medium_coeli` 1.5, personal planets 1.5, social planets 1.0, outers 0.5, and minor bodies 0.3–0.8). Provide `distribution_method="pure_count"` when you want every active point to contribute equally.
|
|
1019
|
+
|
|
1020
|
+
You can refine the weighting without rebuilding the dictionary: pass lowercase point names to `custom_distribution_weights` and use `"__default__"` to override the fallback value applied to entries that are not listed explicitly.
|
|
1021
|
+
|
|
1022
|
+
```python
|
|
1023
|
+
from kerykeion import AstrologicalSubjectFactory, ChartDataFactory
|
|
1024
|
+
|
|
1025
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1026
|
+
"Sample", 1986, 4, 12, 8, 45,
|
|
1027
|
+
lng=11.3426,
|
|
1028
|
+
lat=44.4949,
|
|
1029
|
+
tz_str="Europe/Rome",
|
|
1030
|
+
online=False,
|
|
1031
|
+
)
|
|
1032
|
+
|
|
1033
|
+
# Equal weighting: every active point counts once
|
|
1034
|
+
pure_data = ChartDataFactory.create_natal_chart_data(
|
|
1035
|
+
subject,
|
|
1036
|
+
distribution_method="pure_count",
|
|
1037
|
+
)
|
|
1038
|
+
|
|
1039
|
+
# Custom emphasis: boost the Sun, soften everything else
|
|
1040
|
+
weighted_data = ChartDataFactory.create_natal_chart_data(
|
|
1041
|
+
subject,
|
|
1042
|
+
distribution_method="weighted",
|
|
1043
|
+
custom_distribution_weights={
|
|
1044
|
+
"sun": 3.0,
|
|
1045
|
+
"__default__": 0.75,
|
|
1046
|
+
},
|
|
1047
|
+
)
|
|
1048
|
+
|
|
1049
|
+
print(pure_data.element_distribution.fire)
|
|
1050
|
+
print(weighted_data.element_distribution.fire)
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
All convenience helpers (`create_synastry_chart_data`, `create_transit_chart_data`, returns, and composites) forward the same keyword-only parameters, so you can keep a consistent weighting scheme across every chart type.
|
|
1054
|
+
|
|
1055
|
+
For an extended walkthrough (including category breakdowns of the default map), see `site-docs/element_quality_distribution.md`.
|
|
1056
|
+
|
|
1057
|
+
## Ayanamsa (Sidereal Modes)
|
|
1058
|
+
|
|
1059
|
+
By default, the zodiac type is **Tropical**. To use **Sidereal**, specify the sidereal mode:
|
|
1060
|
+
|
|
1061
|
+
```python
|
|
1062
|
+
johnny = AstrologicalSubjectFactory.from_birth_data(
|
|
1063
|
+
"Johnny Depp", 1963, 6, 9, 0, 0,
|
|
1064
|
+
lng=-87.1112,
|
|
1065
|
+
lat=37.7719,
|
|
1066
|
+
tz_str="America/Chicago",
|
|
1067
|
+
online=False,
|
|
1068
|
+
zodiac_type="Sidereal",
|
|
1069
|
+
sidereal_mode="LAHIRI"
|
|
1070
|
+
)
|
|
1071
|
+
```
|
|
1072
|
+
|
|
1073
|
+
More examples [here](https://www.kerykeion.net/docs//sidereal-modes/).
|
|
1074
|
+
|
|
1075
|
+
Full list of supported sidereal modes [here](https://www.kerykeion.net/pydocs/kerykeion/schemas/kr_literals.html#SiderealMode).
|
|
1076
|
+
|
|
1077
|
+
## House Systems
|
|
1078
|
+
|
|
1079
|
+
By default, houses are calculated using **Placidus**. Configure a different house system as follows:
|
|
1080
|
+
|
|
1081
|
+
```python
|
|
1082
|
+
johnny = AstrologicalSubjectFactory.from_birth_data(
|
|
1083
|
+
"Johnny Depp", 1963, 6, 9, 0, 0,
|
|
1084
|
+
lng=-87.1112,
|
|
1085
|
+
lat=37.7719,
|
|
1086
|
+
tz_str="America/Chicago",
|
|
1087
|
+
online=False,
|
|
1088
|
+
houses_system_identifier="M"
|
|
1089
|
+
)
|
|
1090
|
+
```
|
|
1091
|
+
|
|
1092
|
+
More examples [here](https://www.kerykeion.net/docs//houses-systems/).
|
|
1093
|
+
|
|
1094
|
+
Full list of supported house systems [here](https://www.kerykeion.net/pydocs/kerykeion/schemas/kr_literals.html#HousesSystem).
|
|
1095
|
+
|
|
1096
|
+
So far all the available houses system in the Swiss Ephemeris are supported but the Gauquelin Sectors.
|
|
1097
|
+
|
|
1098
|
+
## Perspective Type
|
|
1099
|
+
|
|
1100
|
+
By default, Kerykeion uses the **Apparent Geocentric** perspective (the most standard in astrology). Other perspectives (e.g., **Heliocentric**) can be set this way:
|
|
1101
|
+
|
|
1102
|
+
```python
|
|
1103
|
+
johnny = AstrologicalSubjectFactory.from_birth_data(
|
|
1104
|
+
"Johnny Depp", 1963, 6, 9, 0, 0,
|
|
1105
|
+
lng=-87.1112,
|
|
1106
|
+
lat=37.7719,
|
|
1107
|
+
tz_str="America/Chicago",
|
|
1108
|
+
online=False,
|
|
1109
|
+
perspective_type="Heliocentric"
|
|
1110
|
+
)
|
|
1111
|
+
```
|
|
1112
|
+
|
|
1113
|
+
More examples [here](https://www.kerykeion.net/docs//perspective-type/).
|
|
1114
|
+
|
|
1115
|
+
Full list of supported perspective types [here](https://www.kerykeion.net/pydocs/kerykeion/schemas/kr_literals.html#PerspectiveType).
|
|
1116
|
+
|
|
1117
|
+
## Themes
|
|
1118
|
+
|
|
1119
|
+
Kerykeion provides several chart themes:
|
|
1120
|
+
|
|
1121
|
+
- **Classic** (default)
|
|
1122
|
+
- **Dark**
|
|
1123
|
+
- **Dark High Contrast**
|
|
1124
|
+
- **Light**
|
|
1125
|
+
- **Strawberry**
|
|
1126
|
+
- **Black & White** (optimized for monochrome printing)
|
|
1127
|
+
|
|
1128
|
+
Each theme offers a distinct visual style, allowing you to choose the one that best suits your preferences or presentation needs. If you prefer more control over the appearance, you can opt not to set any theme, making it easier to customize the chart by overriding the default CSS variables. For more detailed instructions on how to apply themes, check the [documentation](https://www.kerykeion.net/docs/theming)
|
|
1129
|
+
|
|
1130
|
+
The Black & White theme renders glyphs, rings, and aspects in solid black on light backgrounds, designed for crisp B/W prints (PDF or paper) without sacrificing legibility.
|
|
1131
|
+
|
|
1132
|
+
Here's an example of how to set the theme:
|
|
1133
|
+
|
|
1134
|
+
```python
|
|
1135
|
+
from pathlib import Path
|
|
1136
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
1137
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
1138
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
1139
|
+
|
|
1140
|
+
# Step 1: Create subject
|
|
1141
|
+
dark_theme_subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1142
|
+
"John Lennon - Dark Theme", 1940, 10, 9, 18, 30,
|
|
1143
|
+
lng=-2.9833,
|
|
1144
|
+
lat=53.4,
|
|
1145
|
+
tz_str="Europe/London",
|
|
1146
|
+
online=False,
|
|
1147
|
+
)
|
|
1148
|
+
|
|
1149
|
+
# Step 2: Pre-compute chart data
|
|
1150
|
+
chart_data = ChartDataFactory.create_natal_chart_data(dark_theme_subject)
|
|
1151
|
+
|
|
1152
|
+
# Step 3: Create visualization with dark high contrast theme
|
|
1153
|
+
dark_theme_natal_chart = ChartDrawer(chart_data=chart_data, theme="dark-high-contrast")
|
|
1154
|
+
|
|
1155
|
+
output_dir = Path("charts_output")
|
|
1156
|
+
output_dir.mkdir(exist_ok=True)
|
|
1157
|
+
dark_theme_natal_chart.save_svg(output_path=output_dir, filename="john-lennon-natal-dark-high-contrast")
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+

|
|
1161
|
+
|
|
1162
|
+
## Alternative Initialization
|
|
1163
|
+
|
|
1164
|
+
Create an `AstrologicalSubjectModel` from a UTC ISO 8601 string:
|
|
1165
|
+
|
|
1166
|
+
```python
|
|
1167
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
1168
|
+
|
|
1169
|
+
subject = AstrologicalSubjectFactory.from_iso_utc_time(
|
|
1170
|
+
name="Johnny Depp",
|
|
1171
|
+
iso_utc_time="1963-06-09T05:00:00Z",
|
|
1172
|
+
city="Owensboro",
|
|
1173
|
+
nation="US",
|
|
1174
|
+
lng=-87.1112,
|
|
1175
|
+
lat=37.7719,
|
|
1176
|
+
tz_str="America/Chicago",
|
|
1177
|
+
online=False,
|
|
1178
|
+
)
|
|
1179
|
+
|
|
1180
|
+
print(subject.iso_formatted_local_datetime)
|
|
1181
|
+
```
|
|
1182
|
+
|
|
1183
|
+
If you prefer automatic geocoding, set `online=True` and provide your GeoNames credentials via `geonames_username`.
|
|
1184
|
+
|
|
1185
|
+
## Lunar Nodes (Rahu & Ketu)
|
|
1186
|
+
|
|
1187
|
+
Kerykeion supports both **True** and **Mean** Lunar Nodes:
|
|
1188
|
+
|
|
1189
|
+
- **True North Lunar Node**: `"true_node"` (name kept without "north" for backward compatibility).
|
|
1190
|
+
- **True South Lunar Node**: `"true_south_node"`.
|
|
1191
|
+
- **Mean North Lunar Node**: `"mean_node"` (name kept without "north" for backward compatibility).
|
|
1192
|
+
- **Mean South Lunar Node**: `"mean_south_node"`.
|
|
1193
|
+
|
|
1194
|
+
In instances of the classes used to generate aspects and SVG charts, only the mean nodes are active. To activate the true nodes, you need to pass the `active_points` parameter to the `ChartDataFactory` methods.
|
|
1195
|
+
|
|
1196
|
+
Example:
|
|
1197
|
+
|
|
1198
|
+
```python
|
|
1199
|
+
from pathlib import Path
|
|
1200
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
1201
|
+
from kerykeion.chart_data_factory import ChartDataFactory
|
|
1202
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
1203
|
+
|
|
1204
|
+
# Step 1: Create subject
|
|
1205
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1206
|
+
"John Lennon", 1940, 10, 9, 18, 30,
|
|
1207
|
+
lng=-2.9833,
|
|
1208
|
+
lat=53.4,
|
|
1209
|
+
tz_str="Europe/London",
|
|
1210
|
+
online=False,
|
|
1211
|
+
)
|
|
1212
|
+
|
|
1213
|
+
# Step 2: Pre-compute chart data with custom active points including true nodes
|
|
1214
|
+
chart_data = ChartDataFactory.create_natal_chart_data(
|
|
1215
|
+
subject,
|
|
1216
|
+
active_points=[
|
|
1217
|
+
"Sun",
|
|
1218
|
+
"Moon",
|
|
1219
|
+
"Mercury",
|
|
1220
|
+
"Venus",
|
|
1221
|
+
"Mars",
|
|
1222
|
+
"Jupiter",
|
|
1223
|
+
"Saturn",
|
|
1224
|
+
"Uranus",
|
|
1225
|
+
"Neptune",
|
|
1226
|
+
"Pluto",
|
|
1227
|
+
"Mean_Node",
|
|
1228
|
+
"Mean_South_Node",
|
|
1229
|
+
"True_Node", # Activates True North Node
|
|
1230
|
+
"True_South_Node", # Activates True South Node
|
|
1231
|
+
"Ascendant",
|
|
1232
|
+
"Medium_Coeli",
|
|
1233
|
+
"Descendant",
|
|
1234
|
+
"Imum_Coeli"
|
|
1235
|
+
]
|
|
1236
|
+
)
|
|
1237
|
+
|
|
1238
|
+
# Step 3: Create visualization
|
|
1239
|
+
chart = ChartDrawer(chart_data=chart_data)
|
|
1240
|
+
|
|
1241
|
+
output_dir = Path("charts_output")
|
|
1242
|
+
output_dir.mkdir(exist_ok=True)
|
|
1243
|
+
chart.save_svg(output_path=output_dir, filename="johnny-depp-custom-points")
|
|
1244
|
+
```
|
|
1245
|
+
|
|
1246
|
+
## JSON Support
|
|
1247
|
+
|
|
1248
|
+
You can serialize the astrological subject (the base data used throughout the library) to JSON:
|
|
1249
|
+
|
|
1250
|
+
```python
|
|
1251
|
+
from kerykeion import AstrologicalSubjectFactory
|
|
1252
|
+
|
|
1253
|
+
johnny = AstrologicalSubjectFactory.from_birth_data(
|
|
1254
|
+
"Johnny Depp", 1963, 6, 9, 0, 0,
|
|
1255
|
+
lng=-87.1112,
|
|
1256
|
+
lat=37.7719,
|
|
1257
|
+
tz_str="America/Chicago",
|
|
1258
|
+
online=False,
|
|
1259
|
+
)
|
|
1260
|
+
|
|
1261
|
+
print(johnny.model_dump_json(indent=2))
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
## Auto Generated Documentation
|
|
1265
|
+
|
|
1266
|
+
You can find auto-generated documentation [here](https://www.kerykeion.net/pydocs/kerykeion.html). Most classes and functions include docstrings.
|
|
1267
|
+
|
|
1268
|
+
## Development
|
|
1269
|
+
|
|
1270
|
+
Clone the repository or download the ZIP via the GitHub interface.
|
|
1271
|
+
|
|
1272
|
+
## Kerykeion v5.0 – What's New
|
|
1273
|
+
|
|
1274
|
+
Kerykeion v5 is a **complete redesign** that modernizes the library with a data-first approach, factory-based architecture, and Pydantic 2 models. This version brings significant improvements in API design, type safety, and extensibility.
|
|
1275
|
+
|
|
1276
|
+
### 🎯 Key Highlights
|
|
1277
|
+
|
|
1278
|
+
#### Factory-Centered Architecture
|
|
1279
|
+
|
|
1280
|
+
The old class-based approach has been replaced with a modern factory pattern:
|
|
1281
|
+
|
|
1282
|
+
- **`AstrologicalSubjectFactory`**: Replaces the old `AstrologicalSubject` class
|
|
1283
|
+
- **`ChartDataFactory`**: Pre-computes enriched chart data (elements, qualities, aspects)
|
|
1284
|
+
- **`ChartDrawer`**: Pure SVG rendering separated from calculations
|
|
1285
|
+
- **`AspectsFactory`**: Unified aspects calculation for natal and synastry charts
|
|
1286
|
+
- **`PlanetaryReturnFactory`**: Solar and Lunar returns computation
|
|
1287
|
+
- **`HouseComparisonFactory`**: House overlay analysis for synastry
|
|
1288
|
+
- **`RelationshipScoreFactory`**: Compatibility scoring between charts
|
|
1289
|
+
|
|
1290
|
+
**Old v4 API:**
|
|
1291
|
+
|
|
1292
|
+
```python
|
|
1293
|
+
from pathlib import Path
|
|
1294
|
+
from kerykeion import AstrologicalSubject, KerykeionChartSVG
|
|
1295
|
+
|
|
1296
|
+
# v4 - Class-based approach
|
|
1297
|
+
output_dir = Path("charts_output")
|
|
1298
|
+
output_dir.mkdir(exist_ok=True)
|
|
1299
|
+
|
|
1300
|
+
subject = AstrologicalSubject(
|
|
1301
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1302
|
+
lng=-0.1276,
|
|
1303
|
+
lat=51.5074,
|
|
1304
|
+
tz_str="Europe/London",
|
|
1305
|
+
online=False,
|
|
1306
|
+
)
|
|
1307
|
+
chart = KerykeionChartSVG(subject, new_output_directory=output_dir)
|
|
1308
|
+
chart.makeSVG()
|
|
1309
|
+
```
|
|
1310
|
+
|
|
1311
|
+
**New v5 API:**
|
|
1312
|
+
|
|
1313
|
+
```python
|
|
1314
|
+
from pathlib import Path
|
|
1315
|
+
from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
|
|
1316
|
+
|
|
1317
|
+
# v5 - Factory-based approach with separation of concerns
|
|
1318
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1319
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1320
|
+
lng=-0.1276,
|
|
1321
|
+
lat=51.5074,
|
|
1322
|
+
tz_str="Europe/London",
|
|
1323
|
+
online=False,
|
|
1324
|
+
)
|
|
1325
|
+
chart_data = ChartDataFactory.create_natal_chart_data(subject)
|
|
1326
|
+
drawer = ChartDrawer(chart_data=chart_data)
|
|
1327
|
+
|
|
1328
|
+
output_dir = Path("charts_output")
|
|
1329
|
+
output_dir.mkdir(exist_ok=True)
|
|
1330
|
+
drawer.save_svg(output_path=output_dir, filename="john-factory-demo")
|
|
1331
|
+
```
|
|
1332
|
+
|
|
1333
|
+
#### Pydantic 2 Models & Type Safety
|
|
1334
|
+
|
|
1335
|
+
All data structures are now strongly typed Pydantic models:
|
|
1336
|
+
|
|
1337
|
+
- **`AstrologicalSubjectModel`**: Subject data with full validation
|
|
1338
|
+
- **`ChartDataModel`**: Enriched chart data with elements, qualities, aspects
|
|
1339
|
+
- **`AspectModel` list**: Raw aspect entries directly on `ChartDataModel.aspects`
|
|
1340
|
+
- **`PlanetReturnModel`**: Planetary return data
|
|
1341
|
+
- **`ElementDistributionModel`**: Element statistics (fire, earth, air, water)
|
|
1342
|
+
- **`QualityDistributionModel`**: Quality statistics (cardinal, fixed, mutable)
|
|
1343
|
+
|
|
1344
|
+
All models support:
|
|
1345
|
+
|
|
1346
|
+
- JSON serialization/deserialization
|
|
1347
|
+
- Dictionary export
|
|
1348
|
+
- Subscript access
|
|
1349
|
+
- Full IDE autocomplete and type checking
|
|
1350
|
+
|
|
1351
|
+
#### Enhanced Features
|
|
1352
|
+
|
|
1353
|
+
- **Speed & Declination**: All celestial points now include daily motion speed and declination
|
|
1354
|
+
- **Element & Quality Analysis**: Automatic calculation of element/quality distributions
|
|
1355
|
+
- **Relationship Scoring**: Built-in compatibility analysis for synastry
|
|
1356
|
+
- **House Comparison**: Detailed house overlay analysis
|
|
1357
|
+
- **Transit Time Ranges**: Advanced transit tracking over time periods
|
|
1358
|
+
- **Report Module**: Comprehensive text reports with ASCII tables
|
|
1359
|
+
- **Axis Orb Control**: Chart axes now share the same orb as planets by default; pass the keyword-only `axis_orb_limit` to return to a traditional, tighter axis filtering when you need it.
|
|
1360
|
+
- **Element Weight Strategies**: Element and quality stats now default to a curated weighted balance; pass `distribution_method` or `custom_distribution_weights` when you need equal counts or bespoke weightings (including a `__default__` fallback) across any chart factory helper.
|
|
1361
|
+
|
|
1362
|
+
### 🚨 Breaking Changes
|
|
1363
|
+
|
|
1364
|
+
#### 1. Removed Legacy Classes
|
|
1365
|
+
|
|
1366
|
+
The following classes have been **completely removed** and must be replaced:
|
|
1367
|
+
|
|
1368
|
+
| Removed (v4) | Replacement (v5) |
|
|
1369
|
+
| ---------------------- | ---------------------------------------------- |
|
|
1370
|
+
| `AstrologicalSubject` | `AstrologicalSubjectFactory.from_birth_data()` |
|
|
1371
|
+
| `KerykeionChartSVG` | `ChartDrawer` + `ChartDataFactory` |
|
|
1372
|
+
| `NatalAspects` | `AspectsFactory.single_chart_aspects()` |
|
|
1373
|
+
| `SynastryAspects` | `AspectsFactory.dual_chart_aspects()` |
|
|
1374
|
+
| `relationship_score()` | `RelationshipScoreFactory` |
|
|
1375
|
+
|
|
1376
|
+
**Note**: The `kerykeion.backword` module provides temporary wrappers for `AstrologicalSubject` and `KerykeionChartSVG` with deprecation warnings. These will be **removed in v6.0**.
|
|
1377
|
+
|
|
1378
|
+
#### 2. Import Changes
|
|
1379
|
+
|
|
1380
|
+
Module structure has been completely reorganized:
|
|
1381
|
+
|
|
1382
|
+
**Old imports (v4):**
|
|
1383
|
+
|
|
1384
|
+
```python
|
|
1385
|
+
from kerykeion import AstrologicalSubject, KerykeionChartSVG
|
|
1386
|
+
from kerykeion.kr_types import KerykeionException
|
|
1387
|
+
from kerykeion.kr_types.kr_literals import Planet, AxialCusps
|
|
1388
|
+
```
|
|
1389
|
+
|
|
1390
|
+
**New imports (v5):**
|
|
1391
|
+
|
|
1392
|
+
```python
|
|
1393
|
+
from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
|
|
1394
|
+
from kerykeion.schemas import KerykeionException
|
|
1395
|
+
from kerykeion.schemas.kr_literals import AstrologicalPoint
|
|
1396
|
+
```
|
|
1397
|
+
|
|
1398
|
+
**Backward compatibility (v5 only, removed in v6.0):**
|
|
1399
|
+
|
|
1400
|
+
```python
|
|
1401
|
+
# Old kr_types imports still work with deprecation warnings
|
|
1402
|
+
from kerykeion.kr_types import Planet, AxialCusps # Shows warning
|
|
1403
|
+
from kerykeion.schemas import Planet, AxialCusps # Works, no warning
|
|
1404
|
+
```
|
|
1405
|
+
|
|
1406
|
+
#### 3. Type Aliases Unified
|
|
1407
|
+
|
|
1408
|
+
**Old (v4):** `Planet` and `AxialCusps` were separate types
|
|
1409
|
+
**New (v5):** Unified as `AstrologicalPoint`
|
|
1410
|
+
|
|
1411
|
+
```python
|
|
1412
|
+
# v4
|
|
1413
|
+
from kerykeion.kr_types.kr_literals import Planet, AxialCusps
|
|
1414
|
+
|
|
1415
|
+
# v5 (recommended)
|
|
1416
|
+
from kerykeion.schemas.kr_literals import AstrologicalPoint
|
|
1417
|
+
|
|
1418
|
+
# v5 (transition, uses aliases)
|
|
1419
|
+
from kerykeion.schemas import Planet, AxialCusps # Still available
|
|
1420
|
+
```
|
|
1421
|
+
|
|
1422
|
+
#### 4. Lunar Nodes Naming
|
|
1423
|
+
|
|
1424
|
+
All lunar node fields have been renamed for clarity:
|
|
1425
|
+
|
|
1426
|
+
| Old Name (v4) | New Name (v5) |
|
|
1427
|
+
| ----------------- | ----------------------- |
|
|
1428
|
+
| `Mean_Node` | `Mean_North_Lunar_Node` |
|
|
1429
|
+
| `True_Node` | `True_North_Lunar_Node` |
|
|
1430
|
+
| `Mean_South_Node` | `Mean_South_Lunar_Node` |
|
|
1431
|
+
| `True_South_Node` | `True_South_Lunar_Node` |
|
|
1432
|
+
|
|
1433
|
+
**Migration example:**
|
|
1434
|
+
|
|
1435
|
+
```python
|
|
1436
|
+
from kerykeion import AstrologicalSubject, AstrologicalSubjectFactory
|
|
1437
|
+
|
|
1438
|
+
# v4 alias (still available, emits DeprecationWarning)
|
|
1439
|
+
legacy_subject = AstrologicalSubject(
|
|
1440
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1441
|
+
lng=-0.1276,
|
|
1442
|
+
lat=51.5074,
|
|
1443
|
+
tz_str="Europe/London",
|
|
1444
|
+
online=False,
|
|
1445
|
+
)
|
|
1446
|
+
print(legacy_subject.mean_node)
|
|
1447
|
+
|
|
1448
|
+
# v5 canonical name
|
|
1449
|
+
modern_subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1450
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1451
|
+
lng=-0.1276,
|
|
1452
|
+
lat=51.5074,
|
|
1453
|
+
tz_str="Europe/London",
|
|
1454
|
+
online=False,
|
|
1455
|
+
)
|
|
1456
|
+
print(modern_subject.mean_north_lunar_node)
|
|
1457
|
+
```
|
|
1458
|
+
|
|
1459
|
+
#### 5. Axis Orb Filtering
|
|
1460
|
+
|
|
1461
|
+
Modern default orbs now treat chart axes (ASC, MC, DSC, IC) exactly like planets. If you prefer a traditional, constrained approach, every public aspect factory exposes the keyword-only `axis_orb_limit` parameter so you can set a dedicated threshold when needed.
|
|
1462
|
+
|
|
1463
|
+
#### 6. Chart Generation Changes
|
|
1464
|
+
|
|
1465
|
+
The two-step process (data + rendering) is now required:
|
|
1466
|
+
|
|
1467
|
+
**Old v4:**
|
|
1468
|
+
|
|
1469
|
+
```python
|
|
1470
|
+
from pathlib import Path
|
|
1471
|
+
from kerykeion import AstrologicalSubject, KerykeionChartSVG
|
|
1472
|
+
|
|
1473
|
+
output_dir = Path("charts_output")
|
|
1474
|
+
output_dir.mkdir(exist_ok=True)
|
|
1475
|
+
|
|
1476
|
+
subject = AstrologicalSubject(
|
|
1477
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1478
|
+
lng=-0.1276,
|
|
1479
|
+
lat=51.5074,
|
|
1480
|
+
tz_str="Europe/London",
|
|
1481
|
+
online=False,
|
|
1482
|
+
)
|
|
1483
|
+
chart = KerykeionChartSVG(subject, new_output_directory=output_dir)
|
|
1484
|
+
chart.makeSVG()
|
|
1485
|
+
```
|
|
1486
|
+
|
|
1487
|
+
**New v5:**
|
|
1488
|
+
|
|
1489
|
+
```python
|
|
1490
|
+
from pathlib import Path
|
|
1491
|
+
from kerykeion import AstrologicalSubjectFactory, ChartDataFactory
|
|
1492
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
1493
|
+
|
|
1494
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1495
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1496
|
+
lng=-0.1276,
|
|
1497
|
+
lat=51.5074,
|
|
1498
|
+
tz_str="Europe/London",
|
|
1499
|
+
online=False,
|
|
1500
|
+
)
|
|
1501
|
+
chart_data = ChartDataFactory.create_natal_chart_data(subject)
|
|
1502
|
+
drawer = ChartDrawer(chart_data=chart_data)
|
|
1503
|
+
|
|
1504
|
+
output_dir = Path("charts_output")
|
|
1505
|
+
output_dir.mkdir(exist_ok=True)
|
|
1506
|
+
drawer.save_svg(output_path=output_dir, filename="john-v5-demo")
|
|
1507
|
+
```
|
|
1508
|
+
|
|
1509
|
+
#### 7. Aspects API Changes
|
|
1510
|
+
|
|
1511
|
+
Aspects are now calculated through the factory:
|
|
1512
|
+
|
|
1513
|
+
**Old v4:**
|
|
1514
|
+
|
|
1515
|
+
```python
|
|
1516
|
+
from kerykeion import AstrologicalSubjectFactory, NatalAspects, SynastryAspects
|
|
1517
|
+
|
|
1518
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1519
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1520
|
+
lng=-0.1276,
|
|
1521
|
+
lat=51.5074,
|
|
1522
|
+
tz_str="Europe/London",
|
|
1523
|
+
online=False,
|
|
1524
|
+
)
|
|
1525
|
+
subject1 = subject
|
|
1526
|
+
subject2 = AstrologicalSubjectFactory.from_birth_data(
|
|
1527
|
+
"Jane", 1990, 6, 5, 8, 30,
|
|
1528
|
+
lng=-0.1276,
|
|
1529
|
+
lat=51.5074,
|
|
1530
|
+
tz_str="Europe/London",
|
|
1531
|
+
online=False,
|
|
1532
|
+
)
|
|
1533
|
+
|
|
1534
|
+
natal_aspects = NatalAspects(subject)
|
|
1535
|
+
synastry_aspects = SynastryAspects(subject1, subject2)
|
|
1536
|
+
```
|
|
1537
|
+
|
|
1538
|
+
**New v5:**
|
|
1539
|
+
|
|
1540
|
+
```python
|
|
1541
|
+
from kerykeion import AstrologicalSubjectFactory, AspectsFactory
|
|
1542
|
+
|
|
1543
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1544
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1545
|
+
lng=-0.1276,
|
|
1546
|
+
lat=51.5074,
|
|
1547
|
+
tz_str="Europe/London",
|
|
1548
|
+
online=False,
|
|
1549
|
+
)
|
|
1550
|
+
subject1 = subject
|
|
1551
|
+
subject2 = AstrologicalSubjectFactory.from_birth_data(
|
|
1552
|
+
"Jane", 1990, 6, 5, 8, 30,
|
|
1553
|
+
lng=-0.1276,
|
|
1554
|
+
lat=51.5074,
|
|
1555
|
+
tz_str="Europe/London",
|
|
1556
|
+
online=False,
|
|
1557
|
+
)
|
|
1558
|
+
|
|
1559
|
+
natal_aspects = AspectsFactory.single_chart_aspects(subject)
|
|
1560
|
+
synastry_aspects = AspectsFactory.dual_chart_aspects(subject1, subject2)
|
|
1561
|
+
```
|
|
1562
|
+
|
|
1563
|
+
Note (v5.1): The two lists `relevant_aspects` and `all_aspects` were unified into a single, cleaned list: `aspects`. If you previously used either property, switch to `aspects`. The legacy properties still work via the backward-compatibility layer but both return the same unified list.
|
|
1564
|
+
|
|
1565
|
+
### 🔄 Migration Guide
|
|
1566
|
+
|
|
1567
|
+
#### Using the Backward Compatibility Layer
|
|
1568
|
+
|
|
1569
|
+
For a gradual migration, use the `kerykeion.backword` module:
|
|
1570
|
+
|
|
1571
|
+
```python
|
|
1572
|
+
from kerykeion import AstrologicalSubject # Legacy wrapper
|
|
1573
|
+
|
|
1574
|
+
subject = AstrologicalSubject(
|
|
1575
|
+
"John Doe", 1990, 1, 1, 12, 0,
|
|
1576
|
+
lng=-0.1276,
|
|
1577
|
+
lat=51.5074,
|
|
1578
|
+
tz_str="Europe/London",
|
|
1579
|
+
online=False,
|
|
1580
|
+
)
|
|
1581
|
+
|
|
1582
|
+
# These still work but show DeprecationWarnings
|
|
1583
|
+
print(subject.mean_node) # Maps to mean_north_lunar_node
|
|
1584
|
+
print(subject.true_node) # Maps to true_north_lunar_node
|
|
1585
|
+
```
|
|
1586
|
+
|
|
1587
|
+
**⚠️ Warning**: This compatibility layer will be **removed in v6.0**.
|
|
1588
|
+
|
|
1589
|
+
#### Step-by-Step Migration
|
|
1590
|
+
|
|
1591
|
+
1. **Update imports**
|
|
1592
|
+
|
|
1593
|
+
```python
|
|
1594
|
+
# Old (v4)
|
|
1595
|
+
from kerykeion import AstrologicalSubject, KerykeionChartSVG
|
|
1596
|
+
|
|
1597
|
+
# New (v5)
|
|
1598
|
+
from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
|
|
1599
|
+
```
|
|
1600
|
+
|
|
1601
|
+
2. **Update subject creation**
|
|
1602
|
+
|
|
1603
|
+
```python
|
|
1604
|
+
from kerykeion import AstrologicalSubject, AstrologicalSubjectFactory
|
|
1605
|
+
|
|
1606
|
+
# Old (v4)
|
|
1607
|
+
subject = AstrologicalSubject(
|
|
1608
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1609
|
+
lng=-0.1276,
|
|
1610
|
+
lat=51.5074,
|
|
1611
|
+
tz_str="Europe/London",
|
|
1612
|
+
online=False,
|
|
1613
|
+
)
|
|
1614
|
+
|
|
1615
|
+
# New (v5)
|
|
1616
|
+
subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1617
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1618
|
+
lng=-0.1276,
|
|
1619
|
+
lat=51.5074,
|
|
1620
|
+
tz_str="Europe/London",
|
|
1621
|
+
online=False,
|
|
1622
|
+
)
|
|
1623
|
+
```
|
|
1624
|
+
|
|
1625
|
+
3. **Update chart generation**
|
|
1626
|
+
|
|
1627
|
+
```python
|
|
1628
|
+
from pathlib import Path
|
|
1629
|
+
from kerykeion import AstrologicalSubject, AstrologicalSubjectFactory, ChartDataFactory, KerykeionChartSVG
|
|
1630
|
+
from kerykeion.charts.chart_drawer import ChartDrawer
|
|
1631
|
+
|
|
1632
|
+
# Old (v4)
|
|
1633
|
+
legacy_subject = AstrologicalSubject(
|
|
1634
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1635
|
+
lng=-0.1276,
|
|
1636
|
+
lat=51.5074,
|
|
1637
|
+
tz_str="Europe/London",
|
|
1638
|
+
online=False,
|
|
1639
|
+
)
|
|
1640
|
+
output_dir = Path("charts_output")
|
|
1641
|
+
output_dir.mkdir(exist_ok=True)
|
|
1642
|
+
|
|
1643
|
+
chart = KerykeionChartSVG(legacy_subject, new_output_directory=output_dir)
|
|
1644
|
+
chart.makeSVG()
|
|
1645
|
+
|
|
1646
|
+
# New (v5)
|
|
1647
|
+
modern_subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1648
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1649
|
+
lng=-0.1276,
|
|
1650
|
+
lat=51.5074,
|
|
1651
|
+
tz_str="Europe/London",
|
|
1652
|
+
online=False,
|
|
1653
|
+
)
|
|
1654
|
+
chart_data = ChartDataFactory.create_natal_chart_data(modern_subject)
|
|
1655
|
+
drawer = ChartDrawer(chart_data=chart_data)
|
|
1656
|
+
drawer.save_svg(output_path=output_dir, filename="john-v5-migration")
|
|
1657
|
+
```
|
|
1658
|
+
|
|
1659
|
+
4. **Update field access** (lunar nodes)
|
|
1660
|
+
|
|
1661
|
+
```python
|
|
1662
|
+
from kerykeion import AstrologicalSubject, AstrologicalSubjectFactory
|
|
1663
|
+
|
|
1664
|
+
# Old (v4)
|
|
1665
|
+
legacy_subject = AstrologicalSubject(
|
|
1666
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1667
|
+
lng=-0.1276,
|
|
1668
|
+
lat=51.5074,
|
|
1669
|
+
tz_str="Europe/London",
|
|
1670
|
+
online=False,
|
|
1671
|
+
)
|
|
1672
|
+
legacy_mean_node = legacy_subject.mean_node
|
|
1673
|
+
print(getattr(legacy_mean_node, "position", "Legacy mean node not active"))
|
|
1674
|
+
|
|
1675
|
+
# New (v5)
|
|
1676
|
+
modern_subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1677
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1678
|
+
lng=-0.1276,
|
|
1679
|
+
lat=51.5074,
|
|
1680
|
+
tz_str="Europe/London",
|
|
1681
|
+
online=False,
|
|
1682
|
+
)
|
|
1683
|
+
modern_mean_node = modern_subject.mean_north_lunar_node
|
|
1684
|
+
print(getattr(modern_mean_node, "position", "Modern mean node not active"))
|
|
1685
|
+
```
|
|
1686
|
+
|
|
1687
|
+
5. **Update aspects**
|
|
1688
|
+
|
|
1689
|
+
```python
|
|
1690
|
+
from kerykeion import AstrologicalSubject, AstrologicalSubjectFactory, NatalAspects, AspectsFactory
|
|
1691
|
+
|
|
1692
|
+
# Old (v4)
|
|
1693
|
+
legacy_subject = AstrologicalSubject(
|
|
1694
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1695
|
+
lng=-0.1276,
|
|
1696
|
+
lat=51.5074,
|
|
1697
|
+
tz_str="Europe/London",
|
|
1698
|
+
online=False,
|
|
1699
|
+
)
|
|
1700
|
+
legacy_aspects = NatalAspects(legacy_subject)
|
|
1701
|
+
print(f"Legacy aspects count: {len(legacy_aspects.relevant_aspects)}")
|
|
1702
|
+
|
|
1703
|
+
# New (v5)
|
|
1704
|
+
modern_subject = AstrologicalSubjectFactory.from_birth_data(
|
|
1705
|
+
"John", 1990, 1, 1, 12, 0,
|
|
1706
|
+
lng=-0.1276,
|
|
1707
|
+
lat=51.5074,
|
|
1708
|
+
tz_str="Europe/London",
|
|
1709
|
+
online=False,
|
|
1710
|
+
)
|
|
1711
|
+
modern_aspects = AspectsFactory.single_chart_aspects(modern_subject)
|
|
1712
|
+
print(f"Modern aspects count: {len(modern_aspects.aspects)}")
|
|
1713
|
+
```
|
|
1714
|
+
|
|
1715
|
+
#### Automated Migration Script
|
|
1716
|
+
|
|
1717
|
+
Use this sed script to update Python files automatically:
|
|
1718
|
+
|
|
1719
|
+
```bash
|
|
1720
|
+
# Update lunar node references
|
|
1721
|
+
find . -name "*.py" -type f -exec sed -i.bak \
|
|
1722
|
+
-e 's/\.mean_node/.mean_north_lunar_node/g' \
|
|
1723
|
+
-e 's/\.true_node/.true_north_lunar_node/g' \
|
|
1724
|
+
-e 's/\.mean_south_node/.mean_south_lunar_node/g' \
|
|
1725
|
+
-e 's/\.true_south_node/.true_south_lunar_node/g' \
|
|
1726
|
+
-e 's/"Mean_Node"/"Mean_North_Lunar_Node"/g' \
|
|
1727
|
+
-e 's/"True_Node"/"True_North_Lunar_Node"/g' \
|
|
1728
|
+
-e 's/"Mean_South_Node"/"Mean_South_Lunar_Node"/g' \
|
|
1729
|
+
-e 's/"True_South_Node"/"True_South_Lunar_Node"/g' \
|
|
1730
|
+
{} \;
|
|
1731
|
+
```
|
|
1732
|
+
|
|
1733
|
+
**Note**: Always review automated changes and test thoroughly before committing.
|
|
1734
|
+
|
|
1735
|
+
### 📦 Other Notable Changes
|
|
1736
|
+
|
|
1737
|
+
- **Packaging**: Migrated from Poetry to PEP 621 + Hatchling with `uv.lock`
|
|
1738
|
+
- **Settings**: Centralized in `kerykeion.schemas` and `kerykeion.settings`
|
|
1739
|
+
- **Configuration**: Default chart presets consolidated in `kerykeion/settings/chart_defaults.py`
|
|
1740
|
+
- **Type System**: All literals consolidated in `kr_literals.py`
|
|
1741
|
+
- **Performance**: Caching improvements with `functools.lru_cache`
|
|
1742
|
+
- **Testing**: 376 tests with 87% coverage, regenerated fixtures for v5
|
|
1743
|
+
|
|
1744
|
+
### 🎨 New Themes
|
|
1745
|
+
|
|
1746
|
+
Additional chart themes added:
|
|
1747
|
+
|
|
1748
|
+
- `classic` (default)
|
|
1749
|
+
- `dark`
|
|
1750
|
+
- `dark-high-contrast`
|
|
1751
|
+
- `light`
|
|
1752
|
+
- `strawberry`
|
|
1753
|
+
- `black-and-white`
|
|
1754
|
+
|
|
1755
|
+
### 📚 Resources
|
|
1756
|
+
|
|
1757
|
+
- **Full Release Notes**: [v5.0.0.md](release_notes/v5.0.0b1.md)
|
|
1758
|
+
- **Documentation**: [kerykeion.readthedocs.io](https://kerykeion.readthedocs.io)
|
|
1759
|
+
- **API Reference**: [kerykeion.net/pydocs](https://www.kerykeion.net/pydocs/kerykeion.html)
|
|
1760
|
+
- **Examples**: See the `examples/` folder for runnable code
|
|
1761
|
+
- **Support**: [GitHub Discussions](https://github.com/g-battaglia/kerykeion/discussions)
|
|
1762
|
+
|
|
1763
|
+
**Migration Timeline:**
|
|
1764
|
+
|
|
1765
|
+
- **v5.0**: Current - Backward compatibility layer available
|
|
1766
|
+
- **v6.0**: Future - Compatibility layer will be removed
|
|
1767
|
+
|
|
1768
|
+
## Integrating Kerykeion into Your Project
|
|
1769
|
+
|
|
1770
|
+
If you would like to incorporate Kerykeion's astrological features into your application, please reach out via [email](mailto:kerykeion.astrology@gmail.com?subject=Integration%20Request). Whether you need custom features, support, or specialized consulting, I am happy to discuss potential collaborations.
|
|
1771
|
+
|
|
1772
|
+
## License
|
|
1773
|
+
|
|
1774
|
+
This project is covered under the AGPL-3.0 License. For detailed information, please see the [LICENSE](LICENSE) file. If you have questions, feel free to contact me at [kerykeion.astrology@gmail.com](mailto:kerykeion.astrology@gmail.com?subject=Kerykeion).
|
|
1775
|
+
|
|
1776
|
+
As a rule of thumb, if you use this library in a project, you should open-source that project under a compatible license. Alternatively, if you wish to keep your source closed, consider using the [AstrologerAPI](https://rapidapi.com/gbattaglia/api/astrologer/), which is AGPL-3.0 compliant and also helps support the project.
|
|
1777
|
+
|
|
1778
|
+
Since the AstrologerAPI is an external third-party service, using it does _not_ require your code to be open-source.
|
|
1779
|
+
|
|
1780
|
+
## Contributing
|
|
1781
|
+
|
|
1782
|
+
Contributions are welcome! Feel free to submit pull requests or report issues.
|
|
1783
|
+
|
|
1784
|
+
By submitting a contribution, you agree to assign the copyright of that contribution to the maintainer. The project stays openly available under the AGPL for everyone, while the re-licensing option helps sustain future development. Your authorship remains acknowledged in the commit history and release notes.
|
|
1785
|
+
|
|
1786
|
+
## Citations
|
|
1787
|
+
|
|
1788
|
+
If using Kerykeion in published or academic work, please cite as follows:
|
|
1789
|
+
|
|
1790
|
+
```
|
|
1791
|
+
Battaglia, G. (2025). Kerykeion: A Python Library for Astrological Calculations and Chart Generation.
|
|
1792
|
+
https://github.com/g-battaglia/kerykeion
|
|
1793
|
+
```
|