kerykeion 5.0.0b2__py3-none-any.whl → 5.0.0b5__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.

Files changed (36) hide show
  1. kerykeion/__init__.py +3 -2
  2. kerykeion/aspects/aspects_factory.py +60 -21
  3. kerykeion/aspects/aspects_utils.py +1 -1
  4. kerykeion/backword.py +111 -18
  5. kerykeion/chart_data_factory.py +72 -7
  6. kerykeion/charts/chart_drawer.py +524 -203
  7. kerykeion/charts/charts_utils.py +416 -253
  8. kerykeion/charts/templates/aspect_grid_only.xml +269 -312
  9. kerykeion/charts/templates/chart.xml +248 -304
  10. kerykeion/charts/templates/wheel_only.xml +271 -312
  11. kerykeion/charts/themes/black-and-white.css +148 -0
  12. kerykeion/kr_types/__init__.py +70 -0
  13. kerykeion/kr_types/chart_template_model.py +20 -0
  14. kerykeion/kr_types/kerykeion_exception.py +20 -0
  15. kerykeion/kr_types/kr_literals.py +20 -0
  16. kerykeion/kr_types/kr_models.py +20 -0
  17. kerykeion/kr_types/settings_models.py +20 -0
  18. kerykeion/relationship_score_factory.py +12 -2
  19. kerykeion/schemas/__init__.py +7 -0
  20. kerykeion/schemas/kr_literals.py +12 -1
  21. kerykeion/settings/__init__.py +16 -2
  22. kerykeion/settings/chart_defaults.py +444 -0
  23. kerykeion/settings/config_constants.py +0 -5
  24. kerykeion/settings/kerykeion_settings.py +31 -74
  25. kerykeion/settings/translation_strings.py +1479 -0
  26. kerykeion/settings/translations.py +74 -0
  27. kerykeion/transits_time_range_factory.py +10 -1
  28. {kerykeion-5.0.0b2.dist-info → kerykeion-5.0.0b5.dist-info}/METADATA +333 -207
  29. {kerykeion-5.0.0b2.dist-info → kerykeion-5.0.0b5.dist-info}/RECORD +31 -26
  30. kerykeion/settings/kr.config.json +0 -1474
  31. kerykeion/settings/legacy/__init__.py +0 -0
  32. kerykeion/settings/legacy/legacy_celestial_points_settings.py +0 -299
  33. kerykeion/settings/legacy/legacy_chart_aspects_settings.py +0 -71
  34. kerykeion/settings/legacy/legacy_color_settings.py +0 -42
  35. {kerykeion-5.0.0b2.dist-info → kerykeion-5.0.0b5.dist-info}/WHEEL +0 -0
  36. {kerykeion-5.0.0b2.dist-info → kerykeion-5.0.0b5.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kerykeion
3
- Version: 5.0.0b2
3
+ Version: 5.0.0b5
4
4
  Summary: A Python library for astrological calculations, including natal charts, houses, planetary aspects, and SVG chart generation.
5
5
  Project-URL: Homepage, https://www.kerykeion.net/
6
6
  Project-URL: Repository, https://github.com/g-battaglia/kerykeion
@@ -47,7 +47,9 @@ Description-Content-Type: text/markdown
47
47
  <div align="center">
48
48
  <img src="https://static.pepy.tech/badge/kerykeion/month" alt="PyPI Downloads">
49
49
  <img src="https://static.pepy.tech/badge/kerykeion/week" alt="PyPI Downloads">
50
- <img src="https://img.shields.io/github/contributors/g-battaglia/kerykeion?color=blue&logo=github" alt="contributors">
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">
51
53
  <img src="https://img.shields.io/pypi/v/kerykeion?label=pypi%20package" alt="Package version">
52
54
  <img src="https://img.shields.io/pypi/pyversions/kerykeion.svg" alt="Supported Python versions">
53
55
  </div>
@@ -58,14 +60,13 @@ Kerykeion is a Python library for astrology. It computes planetary and house pos
58
60
 
59
61
  The main goal of this project is to offer a clean, data-driven approach to astrology, making it accessible and programmable.
60
62
 
61
- Kerykeion also integrates seamlessly with LLM and AI applications.
63
+ Kerykeion also integrates seamlessly with LLM and AI applications.
62
64
 
63
65
  Here is an example of a birthchart:
64
66
 
65
67
  ![John Lenon Chart](https://raw.githubusercontent.com/g-battaglia/kerykeion/refs/heads/master/tests/charts/svg/John%20Lennon%20-%20Dark%20Theme%20-%20Natal%20Chart.svg)
66
68
 
67
- **Web API**
68
- ---
69
+ ## **Web API**
69
70
 
70
71
  If you want to use Kerykeion in a web application, you can try the dedicated web API:
71
72
 
@@ -73,8 +74,7 @@ If you want to use Kerykeion in a web application, you can try the dedicated web
73
74
 
74
75
  It is [open source](https://github.com/g-battaglia/Astrologer-API) and directly supports this project.
75
76
 
76
- **Donate**
77
- --
77
+ ## **Donate**
78
78
 
79
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
80
 
@@ -87,62 +87,63 @@ This branch (`next`) is **not the stable version** of Kerykeion. It is the **dev
87
87
  If you're looking for the latest stable version, please check out the [`master`](https://github.com/g-battaglia/kerykeion/tree/master) branch instead.
88
88
 
89
89
  ## Table of Contents
90
- - [**Web API**](#web-api)
91
- - [**Donate**](#donate)
92
- - [⚠️ Development Branch Notice](#️-development-branch-notice)
93
- - [Table of Contents](#table-of-contents)
94
- - [Installation](#installation)
95
- - [Basic Usage](#basic-usage)
96
- - [Generate a SVG Chart](#generate-a-svg-chart)
97
- - [Birth Chart](#birth-chart)
98
- - [External Birth Chart](#external-birth-chart)
99
- - [Synastry Chart](#synastry-chart)
100
- - [Transit Chart](#transit-chart)
101
- - [Composite Chart](#composite-chart)
102
- - [Wheel Only Charts](#wheel-only-charts)
103
- - [Birth Chart](#birth-chart-1)
104
- - [Wheel Only Birth Chart (External)](#wheel-only-birth-chart-external)
105
- - [Synastry Chart](#synastry-chart-1)
106
- - [Change the Output Directory](#change-the-output-directory)
107
- - [Change Language](#change-language)
108
- - [Minified SVG](#minified-svg)
109
- - [SVG without CSS Variables](#svg-without-css-variables)
110
- - [Grid Only SVG](#grid-only-svg)
111
- - [Report Generator](#report-generator)
112
- - [Quick Examples](#quick-examples)
113
- - [Section Access](#section-access)
114
- - [Example: Retrieving Aspects](#example-retrieving-aspects)
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. Lunar Nodes Naming](#3-lunar-nodes-naming)
133
- - [4. Chart Generation Changes](#4-chart-generation-changes)
134
- - [5. Aspects API Changes](#5-aspects-api-changes)
135
- - [🔄 Migration Guide](#-migration-guide)
136
- - [Using the Backward Compatibility Layer](#using-the-backward-compatibility-layer)
137
- - [Step-by-Step Migration](#step-by-step-migration)
138
- - [Automated Migration Script](#automated-migration-script)
139
- - [📦 Other Notable Changes](#-other-notable-changes)
140
- - [🎨 New Themes](#-new-themes)
141
- - [📚 Resources](#-resources)
142
- - [Integrating Kerykeion into Your Project](#integrating-kerykeion-into-your-project)
143
- - [License](#license)
144
- - [Contributing](#contributing)
145
- - [Citations](#citations)
90
+
91
+ - [**Web API**](#web-api)
92
+ - [**Donate**](#donate)
93
+ - [⚠️ Development Branch Notice](#️-development-branch-notice)
94
+ - [Table of Contents](#table-of-contents)
95
+ - [Installation](#installation)
96
+ - [Basic Usage](#basic-usage)
97
+ - [Generate a SVG Chart](#generate-a-svg-chart)
98
+ - [Birth Chart](#birth-chart)
99
+ - [External Birth Chart](#external-birth-chart)
100
+ - [Synastry Chart](#synastry-chart)
101
+ - [Transit Chart](#transit-chart)
102
+ - [Composite Chart](#composite-chart)
103
+ - [Wheel Only Charts](#wheel-only-charts)
104
+ - [Birth Chart](#birth-chart-1)
105
+ - [Wheel Only Birth Chart (External)](#wheel-only-birth-chart-external)
106
+ - [Synastry Chart](#synastry-chart-1)
107
+ - [Change the Output Directory](#change-the-output-directory)
108
+ - [Change Language](#change-language)
109
+ - [Minified SVG](#minified-svg)
110
+ - [SVG without CSS Variables](#svg-without-css-variables)
111
+ - [Grid Only SVG](#grid-only-svg)
112
+ - [Report Generator](#report-generator)
113
+ - [Quick Examples](#quick-examples)
114
+ - [Section Access](#section-access)
115
+ - [Example: Retrieving Aspects](#example-retrieving-aspects)
116
+ - [Ayanamsa (Sidereal Modes)](#ayanamsa-sidereal-modes)
117
+ - [House Systems](#house-systems)
118
+ - [Perspective Type](#perspective-type)
119
+ - [Themes](#themes)
120
+ - [Alternative Initialization](#alternative-initialization)
121
+ - [Lunar Nodes (Rahu \& Ketu)](#lunar-nodes-rahu--ketu)
122
+ - [JSON Support](#json-support)
123
+ - [Auto Generated Documentation](#auto-generated-documentation)
124
+ - [Development](#development)
125
+ - [Kerykeion v5.0 – What's New](#kerykeion-v50--whats-new)
126
+ - [🎯 Key Highlights](#-key-highlights)
127
+ - [Factory-Centered Architecture](#factory-centered-architecture)
128
+ - [Pydantic 2 Models \& Type Safety](#pydantic-2-models--type-safety)
129
+ - [Enhanced Features](#enhanced-features)
130
+ - [🚨 Breaking Changes](#-breaking-changes)
131
+ - [1. Removed Legacy Classes](#1-removed-legacy-classes)
132
+ - [2. Import Changes](#2-import-changes)
133
+ - [3. Lunar Nodes Naming](#3-lunar-nodes-naming)
134
+ - [4. Chart Generation Changes](#4-chart-generation-changes)
135
+ - [5. Aspects API Changes](#5-aspects-api-changes)
136
+ - [🔄 Migration Guide](#-migration-guide)
137
+ - [Using the Backward Compatibility Layer](#using-the-backward-compatibility-layer)
138
+ - [Step-by-Step Migration](#step-by-step-migration)
139
+ - [Automated Migration Script](#automated-migration-script)
140
+ - [📦 Other Notable Changes](#-other-notable-changes)
141
+ - [🎨 New Themes](#-new-themes)
142
+ - [📚 Resources](#-resources)
143
+ - [Integrating Kerykeion into Your Project](#integrating-kerykeion-into-your-project)
144
+ - [License](#license)
145
+ - [Contributing](#contributing)
146
+ - [Citations](#citations)
146
147
 
147
148
  ## Installation
148
149
 
@@ -184,7 +185,7 @@ john = AstrologicalSubjectFactory.from_birth_data(
184
185
  lng=-2.9833, # Longitude for Liverpool
185
186
  lat=53.4000, # Latitude for Liverpool
186
187
  tz_str="Europe/London", # Timezone for Liverpool
187
- city="Liverpool",
188
+ city="Liverpool",
188
189
  )
189
190
  ```
190
191
 
@@ -192,7 +193,7 @@ john = AstrologicalSubjectFactory.from_birth_data(
192
193
 
193
194
  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.
194
195
 
195
- **Tip:**
196
+ **Tip:**
196
197
  The optimized way to open the generated SVG files is with a web browser (e.g., Chrome, Firefox).
197
198
  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.
198
199
 
@@ -234,6 +235,7 @@ chart_data = ChartDataFactory.create_external_natal_chart_data(birth_chart)
234
235
  birth_chart_svg = ChartDrawer(chart_data=chart_data)
235
236
  birth_chart_svg.save_svg()
236
237
  ```
238
+
237
239
  ![John Lennon External Birth Chart](https://raw.githubusercontent.com/g-battaglia/kerykeion/refs/heads/master/tests/charts/svg/John%20Lennon%20-%20ExternalNatal%20Chart.svg)
238
240
 
239
241
  ### Synastry Chart
@@ -257,7 +259,6 @@ synastry_chart.save_svg()
257
259
 
258
260
  ![John Lennon and Paul McCartney Synastry](https://www.kerykeion.net/img/examples/synastry-chart.svg)
259
261
 
260
-
261
262
  ### Transit Chart
262
263
 
263
264
  ```python
@@ -307,9 +308,10 @@ composite_chart.save_svg()
307
308
 
308
309
  ## Wheel Only Charts
309
310
 
310
- For *all* the charts, you can generate a wheel-only chart by using the method `makeWheelOnlySVG()`:
311
+ For _all_ the charts, you can generate a wheel-only chart by using the method `makeWheelOnlySVG()`:
311
312
 
312
313
  ### Birth Chart
314
+
313
315
  ```python
314
316
  from kerykeion import AstrologicalSubjectFactory
315
317
  from kerykeion.chart_data_factory import ChartDataFactory
@@ -325,6 +327,7 @@ chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
325
327
  birth_chart_svg = ChartDrawer(chart_data=chart_data)
326
328
  birth_chart_svg.save_wheel_only_svg_file()
327
329
  ```
330
+
328
331
  ![John Lennon Birth Chart](https://raw.githubusercontent.com/g-battaglia/kerykeion/refs/heads/master/tests/charts/svg/John%20Lennon%20-%20Wheel%20Only%20-%20Natal%20Chart%20-%20Wheel%20Only.svg)
329
332
 
330
333
  ### Wheel Only Birth Chart (External)
@@ -351,6 +354,7 @@ birth_chart_svg.save_wheel_only_svg_file(
351
354
  ![John Lennon Birth Chart](https://raw.githubusercontent.com/g-battaglia/kerykeion/refs/heads/master/tests/charts/svg/John%20Lennon%20-%20Wheel%20External%20Only%20-%20ExternalNatal%20Chart%20-%20Wheel%20Only.svg)
352
355
 
353
356
  ### Synastry Chart
357
+
354
358
  ```python
355
359
  from kerykeion import AstrologicalSubjectFactory
356
360
  from kerykeion.chart_data_factory import ChartDataFactory
@@ -393,7 +397,7 @@ synastry_chart.save_svg(output_path=".")
393
397
 
394
398
  ### Change Language
395
399
 
396
- You can switch chart language by passing `chart_language` to the `ChartDrawer` class:
400
+ You can switch chart language by passing `chart_language` to the `ChartDrawer` class:
397
401
 
398
402
  ```python
399
403
  from kerykeion import AstrologicalSubjectFactory
@@ -412,23 +416,43 @@ birth_chart_svg = ChartDrawer(
412
416
  chart_language="IT" # Change to Italian
413
417
  )
414
418
  birth_chart_svg.save_svg()
419
+
420
+ You can also provide custom labels (or introduce a brand-new language) by passing
421
+ a dictionary to `language_pack`. Only the keys you supply are merged on top of the
422
+ built-in strings:
423
+
424
+ ```python
425
+ custom_labels = {
426
+ "PT": {
427
+ "info": "Informações",
428
+ "celestial_points": {"Sun": "Sol", "Moon": "Lua"},
429
+ }
430
+ }
431
+
432
+ birth_chart_svg = ChartDrawer(
433
+ chart_data=chart_data,
434
+ chart_language="PT",
435
+ language_pack=custom_labels["PT"],
436
+ )
437
+ ```
415
438
  ```
416
439
 
417
440
  More details [here](https://www.kerykeion.net/docs/chart-language).
418
441
 
419
442
  The available languages are:
420
- - EN (English)
421
- - FR (French)
422
- - PT (Portuguese)
423
- - ES (Spanish)
424
- - TR (Turkish)
425
- - RU (Russian)
426
- - IT (Italian)
427
- - CN (Chinese)
428
- - DE (German)
429
443
 
444
+ - EN (English)
445
+ - FR (French)
446
+ - PT (Portuguese)
447
+ - ES (Spanish)
448
+ - TR (Turkish)
449
+ - RU (Russian)
450
+ - IT (Italian)
451
+ - CN (Chinese)
452
+ - DE (German)
430
453
 
431
454
  ### Minified SVG
455
+
432
456
  To generate a minified SVG, set `minify_svg=True` in the `makeSVG()` method:
433
457
 
434
458
  ```python
@@ -450,6 +474,7 @@ birth_chart_svg.save_svg(
450
474
  ```
451
475
 
452
476
  ### SVG without CSS Variables
477
+
453
478
  To generate an SVG without CSS variables, set `remove_css_variables=True` in the `makeSVG()` method:
454
479
 
455
480
  ```python
@@ -469,8 +494,8 @@ birth_chart_svg.save_svg(
469
494
  remove_css_variables=True
470
495
  )
471
496
  ```
472
- This will inline all styles and eliminate CSS variables, resulting in an SVG that is more broadly supported.
473
497
 
498
+ This will inline all styles and eliminate CSS variables, resulting in an SVG that is more broadly supported.
474
499
 
475
500
  ### Grid Only SVG
476
501
 
@@ -492,6 +517,7 @@ chart_data = ChartDataFactory.create_synastry_chart_data(birth_chart, second)
492
517
  aspect_grid_chart = ChartDrawer(chart_data=chart_data, theme="dark")
493
518
  aspect_grid_chart.save_aspect_grid_only_svg_file()
494
519
  ```
520
+
495
521
  ![John Lennon Birth Chart](https://raw.githubusercontent.com/g-battaglia/kerykeion/refs/heads/master/tests/charts/svg/John%20Lennon%20-%20Aspect%20Grid%20Only%20-%20Natal%20Chart%20-%20Aspect%20Grid%20Only.svg)
496
522
 
497
523
  ## Report Generator
@@ -522,14 +548,15 @@ ReportGenerator(synastry_data).print_report(max_aspects=12)
522
548
  ```
523
549
 
524
550
  Each report contains:
525
- - A chart-aware title summarising the subject(s) and chart type
526
- - Birth/event metadata and configuration settings
527
- - Celestial points with sign, position, **daily motion**, **declination**, retrograde flag, and house
528
- - House cusp tables for every subject involved
529
- - Lunar phase details when available
530
- - Element/quality distributions and active configuration summaries (for chart data)
531
- - Aspect listings tailored for single or dual charts, with symbols for type and movement
532
- - Dual-chart extras such as house comparisons and relationship scores (when provided by the data)
551
+
552
+ - A chart-aware title summarising the subject(s) and chart type
553
+ - Birth/event metadata and configuration settings
554
+ - Celestial points with sign, position, **daily motion**, **declination**, retrograde flag, and house
555
+ - House cusp tables for every subject involved
556
+ - Lunar phase details when available
557
+ - Element/quality distributions and active configuration summaries (for chart data)
558
+ - Aspect listings tailored for single or dual charts, with symbols for type and movement
559
+ - Dual-chart extras such as house comparisons and relationship scores (when provided by the data)
533
560
 
534
561
  ### Section Access
535
562
 
@@ -590,6 +617,43 @@ custom_aspects = DEFAULT_ACTIVE_ASPECTS.copy()
590
617
  # and filters aspects based on relevance and orb thresholds
591
618
  ```
592
619
 
620
+ ## Element & Quality Distribution Strategies
621
+
622
+ `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.
623
+
624
+ 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.
625
+
626
+ ```python
627
+ from kerykeion import AstrologicalSubjectFactory, ChartDataFactory
628
+
629
+ subject = AstrologicalSubjectFactory.from_birth_data(
630
+ "Sample", 1986, 4, 12, 8, 45, "Bologna", "IT"
631
+ )
632
+
633
+ # Equal weighting: every active point counts once
634
+ pure_data = ChartDataFactory.create_natal_chart_data(
635
+ subject,
636
+ distribution_method="pure_count",
637
+ )
638
+
639
+ # Custom emphasis: boost the Sun, soften everything else
640
+ weighted_data = ChartDataFactory.create_natal_chart_data(
641
+ subject,
642
+ distribution_method="weighted",
643
+ custom_distribution_weights={
644
+ "sun": 3.0,
645
+ "__default__": 0.75,
646
+ },
647
+ )
648
+
649
+ print(pure_data.element_distribution.fire)
650
+ print(weighted_data.element_distribution.fire)
651
+ ```
652
+
653
+ 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.
654
+
655
+ For an extended walkthrough (including category breakdowns of the default map), see `site-docs/element_quality_distribution.md`.
656
+
593
657
  ## Ayanamsa (Sidereal Modes)
594
658
 
595
659
  By default, the zodiac type is **Tropical**. To use **Sidereal**, specify the sidereal mode:
@@ -645,13 +709,17 @@ Full list of supported perspective types [here](https://www.kerykeion.net/pydocs
645
709
 
646
710
  Kerykeion provides several chart themes:
647
711
 
648
- - **Classic** (default)
649
- - **Dark**
650
- - **Dark High Contrast**
651
- - **Light**
652
-
712
+ - **Classic** (default)
713
+ - **Dark**
714
+ - **Dark High Contrast**
715
+ - **Light**
716
+ - **Strawberry**
717
+ - **Black & White** (optimized for monochrome printing)
718
+
653
719
  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)
654
720
 
721
+ 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.
722
+
655
723
  Here's an example of how to set the theme:
656
724
 
657
725
  ```python
@@ -666,7 +734,7 @@ dark_theme_subject = AstrologicalSubjectFactory.from_birth_data("John Lennon - D
666
734
  chart_data = ChartDataFactory.create_natal_chart_data(dark_theme_subject)
667
735
 
668
736
  # Step 3: Create visualization with dark high contrast theme
669
- dark_theme_natal_chart = ChartDrawer(chart_data=chart_data, theme="dark_high_contrast")
737
+ dark_theme_natal_chart = ChartDrawer(chart_data=chart_data, theme="dark-high-contrast")
670
738
  dark_theme_natal_chart.save_svg()
671
739
  ```
672
740
 
@@ -696,10 +764,10 @@ subject = AstrologicalSubject.get_from_iso_utc_time(
696
764
 
697
765
  Kerykeion supports both **True** and **Mean** Lunar Nodes:
698
766
 
699
- - **True North Lunar Node**: `"true_node"` (name kept without "north" for backward compatibility).
700
- - **True South Lunar Node**: `"true_south_node"`.
701
- - **Mean North Lunar Node**: `"mean_node"` (name kept without "north" for backward compatibility).
702
- - **Mean South Lunar Node**: `"mean_south_node"`.
767
+ - **True North Lunar Node**: `"true_node"` (name kept without "north" for backward compatibility).
768
+ - **True South Lunar Node**: `"true_south_node"`.
769
+ - **Mean North Lunar Node**: `"mean_node"` (name kept without "north" for backward compatibility).
770
+ - **Mean South Lunar Node**: `"mean_south_node"`.
703
771
 
704
772
  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.
705
773
 
@@ -717,23 +785,23 @@ subject = AstrologicalSubjectFactory.from_birth_data("John Lennon", 1940, 10, 9,
717
785
  chart_data = ChartDataFactory.create_natal_chart_data(
718
786
  subject,
719
787
  active_points=[
720
- "Sun",
721
- "Moon",
722
- "Mercury",
723
- "Venus",
724
- "Mars",
725
- "Jupiter",
788
+ "Sun",
789
+ "Moon",
790
+ "Mercury",
791
+ "Venus",
792
+ "Mars",
793
+ "Jupiter",
726
794
  "Saturn",
727
- "Uranus",
728
- "Neptune",
729
- "Pluto",
730
- "Mean_Node",
731
- "Mean_South_Node",
732
- "True_Node", # Activates True North Node
795
+ "Uranus",
796
+ "Neptune",
797
+ "Pluto",
798
+ "Mean_Node",
799
+ "Mean_South_Node",
800
+ "True_Node", # Activates True North Node
733
801
  "True_South_Node", # Activates True South Node
734
802
  "Ascendant",
735
- "Medium_Coeli",
736
- "Descendant",
803
+ "Medium_Coeli",
804
+ "Descendant",
737
805
  "Imum_Coeli"
738
806
  ]
739
807
  )
@@ -770,17 +838,19 @@ Kerykeion v5 is a **complete redesign** that modernizes the library with a data-
770
838
  ### 🎯 Key Highlights
771
839
 
772
840
  #### Factory-Centered Architecture
841
+
773
842
  The old class-based approach has been replaced with a modern factory pattern:
774
843
 
775
- - **`AstrologicalSubjectFactory`**: Replaces the old `AstrologicalSubject` class
776
- - **`ChartDataFactory`**: Pre-computes enriched chart data (elements, qualities, aspects)
777
- - **`ChartDrawer`**: Pure SVG rendering separated from calculations
778
- - **`AspectsFactory`**: Unified aspects calculation for natal and synastry charts
779
- - **`PlanetaryReturnFactory`**: Solar and Lunar returns computation
780
- - **`HouseComparisonFactory`**: House overlay analysis for synastry
781
- - **`RelationshipScoreFactory`**: Compatibility scoring between charts
844
+ - **`AstrologicalSubjectFactory`**: Replaces the old `AstrologicalSubject` class
845
+ - **`ChartDataFactory`**: Pre-computes enriched chart data (elements, qualities, aspects)
846
+ - **`ChartDrawer`**: Pure SVG rendering separated from calculations
847
+ - **`AspectsFactory`**: Unified aspects calculation for natal and synastry charts
848
+ - **`PlanetaryReturnFactory`**: Solar and Lunar returns computation
849
+ - **`HouseComparisonFactory`**: House overlay analysis for synastry
850
+ - **`RelationshipScoreFactory`**: Compatibility scoring between charts
782
851
 
783
852
  **Old v4 API:**
853
+
784
854
  ```python
785
855
  from kerykeion import AstrologicalSubject, KerykeionChartSVG
786
856
 
@@ -791,6 +861,7 @@ chart.makeSVG()
791
861
  ```
792
862
 
793
863
  **New v5 API:**
864
+
794
865
  ```python
795
866
  from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
796
867
 
@@ -802,70 +873,107 @@ drawer.save_svg()
802
873
  ```
803
874
 
804
875
  #### Pydantic 2 Models & Type Safety
876
+
805
877
  All data structures are now strongly typed Pydantic models:
806
878
 
807
- - **`AstrologicalSubjectModel`**: Subject data with full validation
808
- - **`ChartDataModel`**: Enriched chart data with elements, qualities, aspects
809
- - **`SingleChartAspectsModel` / `DualChartAspectsModel`**: Typed aspect collections
810
- - **`PlanetReturnModel`**: Planetary return data
811
- - **`ElementDistributionModel`**: Element statistics (fire, earth, air, water)
812
- - **`QualityDistributionModel`**: Quality statistics (cardinal, fixed, mutable)
879
+ - **`AstrologicalSubjectModel`**: Subject data with full validation
880
+ - **`ChartDataModel`**: Enriched chart data with elements, qualities, aspects
881
+ - **`SingleChartAspectsModel` / `DualChartAspectsModel`**: Typed aspect collections
882
+ - **`PlanetReturnModel`**: Planetary return data
883
+ - **`ElementDistributionModel`**: Element statistics (fire, earth, air, water)
884
+ - **`QualityDistributionModel`**: Quality statistics (cardinal, fixed, mutable)
813
885
 
814
886
  All models support:
815
- - JSON serialization/deserialization
816
- - Dictionary export
817
- - Subscript access
818
- - Full IDE autocomplete and type checking
887
+
888
+ - JSON serialization/deserialization
889
+ - Dictionary export
890
+ - Subscript access
891
+ - Full IDE autocomplete and type checking
819
892
 
820
893
  #### Enhanced Features
821
- - **Speed & Declination**: All celestial points now include daily motion speed and declination
822
- - **Element & Quality Analysis**: Automatic calculation of element/quality distributions
823
- - **Relationship Scoring**: Built-in compatibility analysis for synastry
824
- - **House Comparison**: Detailed house overlay analysis
825
- - **Transit Time Ranges**: Advanced transit tracking over time periods
826
- - **Report Module**: Comprehensive text reports with ASCII tables
894
+
895
+ - **Speed & Declination**: All celestial points now include daily motion speed and declination
896
+ - **Element & Quality Analysis**: Automatic calculation of element/quality distributions
897
+ - **Relationship Scoring**: Built-in compatibility analysis for synastry
898
+ - **House Comparison**: Detailed house overlay analysis
899
+ - **Transit Time Ranges**: Advanced transit tracking over time periods
900
+ - **Report Module**: Comprehensive text reports with ASCII tables
901
+ - **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.
902
+ - **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.
827
903
 
828
904
  ### 🚨 Breaking Changes
829
905
 
830
906
  #### 1. Removed Legacy Classes
907
+
831
908
  The following classes have been **completely removed** and must be replaced:
832
909
 
833
- | Removed (v4) | Replacement (v5) |
834
- |--------------|------------------|
835
- | `AstrologicalSubject` | `AstrologicalSubjectFactory.from_birth_data()` |
836
- | `KerykeionChartSVG` | `ChartDrawer` + `ChartDataFactory` |
837
- | `NatalAspects` | `AspectsFactory.single_chart_aspects()` |
838
- | `SynastryAspects` | `AspectsFactory.dual_chart_aspects()` |
839
- | `relationship_score()` | `RelationshipScoreFactory` |
910
+ | Removed (v4) | Replacement (v5) |
911
+ | ---------------------- | ---------------------------------------------- |
912
+ | `AstrologicalSubject` | `AstrologicalSubjectFactory.from_birth_data()` |
913
+ | `KerykeionChartSVG` | `ChartDrawer` + `ChartDataFactory` |
914
+ | `NatalAspects` | `AspectsFactory.single_chart_aspects()` |
915
+ | `SynastryAspects` | `AspectsFactory.dual_chart_aspects()` |
916
+ | `relationship_score()` | `RelationshipScoreFactory` |
840
917
 
841
918
  **Note**: The `kerykeion.backword` module provides temporary wrappers for `AstrologicalSubject` and `KerykeionChartSVG` with deprecation warnings. These will be **removed in v6.0**.
842
919
 
843
920
  #### 2. Import Changes
921
+
844
922
  Module structure has been completely reorganized:
845
923
 
846
924
  **Old imports (v4):**
925
+
847
926
  ```python
848
927
  from kerykeion import AstrologicalSubject, KerykeionChartSVG
849
928
  from kerykeion.kr_types import KerykeionException
929
+ from kerykeion.kr_types.kr_literals import Planet, AxialCusps
850
930
  ```
851
931
 
852
932
  **New imports (v5):**
933
+
853
934
  ```python
854
935
  from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
855
- from kerykeion.schemas.kerykeion_exception import KerykeionException
936
+ from kerykeion.schemas import KerykeionException
937
+ from kerykeion.schemas.kr_literals import AstrologicalPoint
938
+ ```
939
+
940
+ **Backward compatibility (v5 only, removed in v6.0):**
941
+
942
+ ```python
943
+ # Old kr_types imports still work with deprecation warnings
944
+ from kerykeion.kr_types import Planet, AxialCusps # Shows warning
945
+ from kerykeion.schemas import Planet, AxialCusps # Works, no warning
856
946
  ```
857
947
 
858
- #### 3. Lunar Nodes Naming
948
+ #### 3. Type Aliases Unified
949
+
950
+ **Old (v4):** `Planet` and `AxialCusps` were separate types
951
+ **New (v5):** Unified as `AstrologicalPoint`
952
+
953
+ ```python
954
+ # v4
955
+ from kerykeion.kr_types.kr_literals import Planet, AxialCusps
956
+
957
+ # v5 (recommended)
958
+ from kerykeion.schemas.kr_literals import AstrologicalPoint
959
+
960
+ # v5 (transition, uses aliases)
961
+ from kerykeion.schemas import Planet, AxialCusps # Still available
962
+ ```
963
+
964
+ #### 4. Lunar Nodes Naming
965
+
859
966
  All lunar node fields have been renamed for clarity:
860
967
 
861
- | Old Name (v4) | New Name (v5) |
862
- |---------------|---------------|
863
- | `Mean_Node` | `Mean_North_Lunar_Node` |
864
- | `True_Node` | `True_North_Lunar_Node` |
968
+ | Old Name (v4) | New Name (v5) |
969
+ | ----------------- | ----------------------- |
970
+ | `Mean_Node` | `Mean_North_Lunar_Node` |
971
+ | `True_Node` | `True_North_Lunar_Node` |
865
972
  | `Mean_South_Node` | `Mean_South_Lunar_Node` |
866
973
  | `True_South_Node` | `True_South_Lunar_Node` |
867
974
 
868
975
  **Migration example:**
976
+
869
977
  ```python
870
978
  # v4
871
979
  print(subject.mean_node)
@@ -874,26 +982,35 @@ print(subject.mean_node)
874
982
  print(subject.mean_north_lunar_node)
875
983
  ```
876
984
 
877
- #### 4. Chart Generation Changes
985
+ #### 5. Axis Orb Filtering
986
+
987
+ 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.
988
+
989
+ #### 6. Chart Generation Changes
990
+
878
991
  The two-step process (data + rendering) is now required:
879
992
 
880
993
  **Old v4:**
994
+
881
995
  ```python
882
996
  chart = KerykeionChartSVG(subject)
883
997
  chart.makeSVG()
884
998
  ```
885
999
 
886
1000
  **New v5:**
1001
+
887
1002
  ```python
888
1003
  chart_data = ChartDataFactory.create_natal_chart_data(subject)
889
1004
  drawer = ChartDrawer(chart_data=chart_data)
890
1005
  drawer.save_svg()
891
1006
  ```
892
1007
 
893
- #### 5. Aspects API Changes
1008
+ #### 7. Aspects API Changes
1009
+
894
1010
  Aspects are now calculated through the factory:
895
1011
 
896
1012
  **Old v4:**
1013
+
897
1014
  ```python
898
1015
  from kerykeion import NatalAspects, SynastryAspects
899
1016
 
@@ -902,6 +1019,7 @@ synastry_aspects = SynastryAspects(subject1, subject2)
902
1019
  ```
903
1020
 
904
1021
  **New v5:**
1022
+
905
1023
  ```python
906
1024
  from kerykeion import AspectsFactory
907
1025
 
@@ -930,54 +1048,59 @@ print(subject.true_node) # Maps to true_north_lunar_node
930
1048
  #### Step-by-Step Migration
931
1049
 
932
1050
  1. **Update imports**
933
- ```python
934
- # Old
935
- from kerykeion import AstrologicalSubject, KerykeionChartSVG
936
-
937
- # New
938
- from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
939
- ```
1051
+
1052
+ ```python
1053
+ # Old
1054
+ from kerykeion import AstrologicalSubject, KerykeionChartSVG
1055
+
1056
+ # New
1057
+ from kerykeion import AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer
1058
+ ```
940
1059
 
941
1060
  2. **Update subject creation**
942
- ```python
943
- # Old
944
- subject = AstrologicalSubject("John", 1990, 1, 1, 12, 0, "London", "GB")
945
-
946
- # New
947
- subject = AstrologicalSubjectFactory.from_birth_data("John", 1990, 1, 1, 12, 0, "London", "GB")
948
- ```
1061
+
1062
+ ```python
1063
+ # Old
1064
+ subject = AstrologicalSubject("John", 1990, 1, 1, 12, 0, "London", "GB")
1065
+
1066
+ # New
1067
+ subject = AstrologicalSubjectFactory.from_birth_data("John", 1990, 1, 1, 12, 0, "London", "GB")
1068
+ ```
949
1069
 
950
1070
  3. **Update chart generation**
951
- ```python
952
- # Old
953
- chart = KerykeionChartSVG(subject)
954
- chart.makeSVG()
955
-
956
- # New
957
- chart_data = ChartDataFactory.create_natal_chart_data(subject)
958
- drawer = ChartDrawer(chart_data=chart_data)
959
- drawer.save_svg()
960
- ```
1071
+
1072
+ ```python
1073
+ # Old
1074
+ chart = KerykeionChartSVG(subject)
1075
+ chart.makeSVG()
1076
+
1077
+ # New
1078
+ chart_data = ChartDataFactory.create_natal_chart_data(subject)
1079
+ drawer = ChartDrawer(chart_data=chart_data)
1080
+ drawer.save_svg()
1081
+ ```
961
1082
 
962
1083
  4. **Update field access** (lunar nodes)
963
- ```python
964
- # Old
965
- print(subject.mean_node.position)
966
-
967
- # New
968
- print(subject.mean_north_lunar_node.position)
969
- ```
1084
+
1085
+ ```python
1086
+ # Old
1087
+ print(subject.mean_node.position)
1088
+
1089
+ # New
1090
+ print(subject.mean_north_lunar_node.position)
1091
+ ```
970
1092
 
971
1093
  5. **Update aspects**
972
- ```python
973
- # Old
974
- from kerykeion import NatalAspects
975
- aspects = NatalAspects(subject)
976
-
977
- # New
978
- from kerykeion import AspectsFactory
979
- aspects = AspectsFactory.single_chart_aspects(subject)
980
- ```
1094
+
1095
+ ```python
1096
+ # Old
1097
+ from kerykeion import NatalAspects
1098
+ aspects = NatalAspects(subject)
1099
+
1100
+ # New
1101
+ from kerykeion import AspectsFactory
1102
+ aspects = AspectsFactory.single_chart_aspects(subject)
1103
+ ```
981
1104
 
982
1105
  #### Automated Migration Script
983
1106
 
@@ -1001,33 +1124,36 @@ find . -name "*.py" -type f -exec sed -i.bak \
1001
1124
 
1002
1125
  ### 📦 Other Notable Changes
1003
1126
 
1004
- - **Packaging**: Migrated from Poetry to PEP 621 + Hatchling with `uv.lock`
1005
- - **Settings**: Centralized in `kerykeion.schemas` and `kerykeion.settings`
1006
- - **Configuration**: Legacy presets available in `settings/legacy/`
1007
- - **Type System**: All literals consolidated in `kr_literals.py`
1008
- - **Performance**: Caching improvements with `functools.lru_cache`
1009
- - **Testing**: 376 tests with 87% coverage, regenerated fixtures for v5
1127
+ - **Packaging**: Migrated from Poetry to PEP 621 + Hatchling with `uv.lock`
1128
+ - **Settings**: Centralized in `kerykeion.schemas` and `kerykeion.settings`
1129
+ - **Configuration**: Default chart presets consolidated in `kerykeion/settings/chart_defaults.py`
1130
+ - **Type System**: All literals consolidated in `kr_literals.py`
1131
+ - **Performance**: Caching improvements with `functools.lru_cache`
1132
+ - **Testing**: 376 tests with 87% coverage, regenerated fixtures for v5
1010
1133
 
1011
1134
  ### 🎨 New Themes
1012
1135
 
1013
1136
  Additional chart themes added:
1014
- - `classic` (default)
1015
- - `dark`
1016
- - `dark_high_contrast`
1017
- - `light`
1018
- - `strawberry`
1137
+
1138
+ - `classic` (default)
1139
+ - `dark`
1140
+ - `dark-high-contrast`
1141
+ - `light`
1142
+ - `strawberry`
1143
+ - `black-and-white`
1019
1144
 
1020
1145
  ### 📚 Resources
1021
1146
 
1022
- - **Full Release Notes**: [v5.0.0.md](release_notes/v5.0.0b1.md)
1023
- - **Documentation**: [kerykeion.readthedocs.io](https://kerykeion.readthedocs.io)
1024
- - **API Reference**: [kerykeion.net/pydocs](https://www.kerykeion.net/pydocs/kerykeion.html)
1025
- - **Examples**: See the `examples/` folder for runnable code
1026
- - **Support**: [GitHub Discussions](https://github.com/g-battaglia/kerykeion/discussions)
1147
+ - **Full Release Notes**: [v5.0.0.md](release_notes/v5.0.0b1.md)
1148
+ - **Documentation**: [kerykeion.readthedocs.io](https://kerykeion.readthedocs.io)
1149
+ - **API Reference**: [kerykeion.net/pydocs](https://www.kerykeion.net/pydocs/kerykeion.html)
1150
+ - **Examples**: See the `examples/` folder for runnable code
1151
+ - **Support**: [GitHub Discussions](https://github.com/g-battaglia/kerykeion/discussions)
1027
1152
 
1028
1153
  **Migration Timeline:**
1029
- - **v5.0**: Current - Backward compatibility layer available
1030
- - **v6.0**: Future - Compatibility layer will be removed
1154
+
1155
+ - **v5.0**: Current - Backward compatibility layer available
1156
+ - **v6.0**: Future - Compatibility layer will be removed
1031
1157
 
1032
1158
  ## Integrating Kerykeion into Your Project
1033
1159
 
@@ -1039,7 +1165,7 @@ This project is covered under the AGPL-3.0 License. For detailed information, pl
1039
1165
 
1040
1166
  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.
1041
1167
 
1042
- Since the AstrologerAPI is an external third-party service, using it does *not* require your code to be open-source.
1168
+ Since the AstrologerAPI is an external third-party service, using it does _not_ require your code to be open-source.
1043
1169
 
1044
1170
  ## Contributing
1045
1171