kerykeion 5.0.0a9__tar.gz → 5.0.0a10__tar.gz

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 (199) hide show
  1. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/.gitignore +1 -1
  2. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/PKG-INFO +9 -4
  3. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/__init__.py +22 -1
  4. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/aspects/__init__.py +7 -2
  5. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/aspects/aspects_utils.py +1 -3
  6. kerykeion-5.0.0a10/kerykeion/aspects/natal_aspects_factory.py +236 -0
  7. kerykeion-5.0.0a10/kerykeion/aspects/synastry_aspects_factory.py +234 -0
  8. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/astrological_subject_factory.py +5 -9
  9. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/charts_utils.py +12 -12
  10. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/draw_planets.py +3 -4
  11. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/draw_planets_v2.py +5 -6
  12. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/kerykeion_chart_svg.py +10 -10
  13. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/composite_subject_factory.py +1 -1
  14. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/house_comparison/__init__.py +6 -0
  15. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/house_comparison/house_comparison_factory.py +1 -1
  16. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/house_comparison/house_comparison_utils.py +0 -1
  17. kerykeion-5.0.0a10/kerykeion/kr_types/__init__.py +59 -0
  18. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/kr_types/kr_models.py +29 -0
  19. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/kr_types/settings_models.py +9 -1
  20. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/planetary_return_factory.py +6 -5
  21. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/relationship_score_factory.py +27 -17
  22. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/report.py +0 -1
  23. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/settings/__init__.py +5 -0
  24. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/settings/config_constants.py +20 -6
  25. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/settings/kr.config.json +80 -0
  26. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/transits_time_range.py +4 -4
  27. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/utilities.py +1 -1
  28. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/pyproject.toml +26 -19
  29. kerykeion-5.0.0a10/test_utils/README.md +3 -0
  30. kerykeion-5.0.0a10/test_utils/regenerate_expected_aspects.py +94 -0
  31. kerykeion-5.0.0a10/test_utils/regenerate_synastry_aspects.py +43 -0
  32. kerykeion-5.0.0a10/test_utils/regenerate_synastry_from_test.py +40 -0
  33. kerykeion-5.0.0a9/tests/charts/generate_test_charts.py → kerykeion-5.0.0a10/test_utils/regenerate_test_charts.py +112 -90
  34. kerykeion-5.0.0a10/tests/aspects/expected_natal_aspects.py +985 -0
  35. kerykeion-5.0.0a10/tests/aspects/expected_synastry_aspects.py +1853 -0
  36. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/aspects/test_natal_aspects.py +3 -3
  37. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/aspects/test_synastry_aspects.py +3 -3
  38. kerykeion-5.0.0a10/tests/charts/svg/Albert Einstein - Natal Chart.svg +802 -0
  39. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/Amitabh Bachchan - Natal Chart.svg +294 -161
  40. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/Angelina Jolie and Brad Pitt Composite Chart - Composite Chart.svg +287 -154
  41. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/Antonio Banderas - Natal Chart.svg +294 -161
  42. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/Cristiano Ronaldo - Natal Chart.svg +294 -161
  43. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - Aspect Grid Transit - Transit Chart - Aspect Grid Only.svg → kerykeion-5.0.0a10/tests/charts/svg/Grid - Transit Chart - Aspect Grid Only.svg +145 -80
  44. kerykeion-5.0.0a10/tests/charts/svg/Grid - Transit Chart - Wheel Only.svg +672 -0
  45. kerykeion-5.0.0a10/tests/charts/svg/Grid - Transit Chart.svg +849 -0
  46. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/Hua Chenyu - Natal Chart.svg +295 -162
  47. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/Jeanne Moreau - Natal Chart.svg +294 -161
  48. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - Aspect Grid Dark Synastry - Synastry Chart - Aspect Grid Only.svg +137 -111
  49. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - Aspect Grid Only - Natal Chart - Aspect Grid Only.svg → kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Aspect Grid Dark Theme - Natal Chart - Aspect Grid Only.svg +145 -80
  50. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - Aspect Grid Light Theme - Natal Chart - Aspect Grid Only.svg +137 -107
  51. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - Aspect Grid Dark Theme - Natal Chart - Aspect Grid Only.svg → kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Aspect Grid Only - Natal Chart - Aspect Grid Only.svg +96 -117
  52. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - Aspect Grid Synastry - Synastry Chart - Aspect Grid Only.svg +98 -80
  53. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Aspect Grid Transit - Transit Chart - Aspect Grid Only.svg +570 -0
  54. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - DTS - Synastry Chart.svg +840 -0
  55. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - Heliocentric - Natal Chart.svg → kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Dark High Contrast Theme - Natal Chart.svg +344 -165
  56. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Dark Theme - Natal Chart.svg +849 -0
  57. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - Dark Theme External - ExternalNatal Chart.svg +347 -210
  58. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - ExternalNatal Chart.svg +300 -171
  59. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Heliocentric - Natal Chart.svg +802 -0
  60. kerykeion-5.0.0a9/tests/charts/svg/John Lennon Lahiri - Natal Chart.svg → kerykeion-5.0.0a10/tests/charts/svg/John Lennon - House System Morinus - Natal Chart.svg +297 -164
  61. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Light Theme - Natal Chart.svg +849 -0
  62. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Minified - Natal Chart.svg +1 -0
  63. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - Natal Chart.svg +293 -160
  64. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Return Chart - Lunar Return.svg +849 -0
  65. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Return Chart - Solar Return.svg +802 -0
  66. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - SCTWL - Synastry Chart.svg +840 -0
  67. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Synastry Chart.svg +793 -0
  68. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - TCWTG - Transit Chart.svg +849 -0
  69. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - Topocentric - Natal Chart.svg +293 -160
  70. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Transit Chart.svg +802 -0
  71. kerykeion-5.0.0a10/tests/charts/svg/John Lennon - Transparent Background - Natal Chart.svg +802 -0
  72. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - True Geocentric - Natal Chart.svg +293 -160
  73. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - Wheel External Only - ExternalNatal Chart - Wheel Only.svg +125 -103
  74. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - Wheel Only - Natal Chart - Wheel Only.svg +118 -92
  75. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - Wheel Synastry Only - Synastry Chart - Wheel Only.svg +118 -92
  76. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon - Wheel Transit Only - Transit Chart - Wheel Only.svg +118 -92
  77. kerykeion-5.0.0a9/tests/charts/svg/John Lennon Fagan-Bradley - Natal Chart.svg → kerykeion-5.0.0a10/tests/charts/svg/John Lennon DeLuce - Natal Chart.svg +296 -163
  78. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon Fagan-Bradley - Light Theme - Natal Chart - Wheel Only.svg +157 -119
  79. kerykeion-5.0.0a10/tests/charts/svg/John Lennon Fagan-Bradley - Natal Chart.svg +802 -0
  80. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon J2000 - Natal Chart.svg +293 -160
  81. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/John Lennon Lahiri - Dark Theme - Natal Chart - Wheel Only.svg +157 -123
  82. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - House System Morinus - Natal Chart.svg → kerykeion-5.0.0a10/tests/charts/svg/John Lennon Lahiri - Natal Chart.svg +297 -164
  83. kerykeion-5.0.0a10/tests/charts/svg/John Lennon Solar Return - SingleWheelReturn Chart.svg +849 -0
  84. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/Kanye - Natal Chart.svg +293 -160
  85. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - Light Theme - Natal Chart.svg → kerykeion-5.0.0a10/tests/charts/svg/Mehmet Oz - Natal Chart.svg +301 -203
  86. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/Mikhail Bulgakov - Natal Chart.svg +294 -161
  87. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/svg/Sophia Loren - Natal Chart.svg +294 -161
  88. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/settings/test-settings.json +311 -11
  89. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/test_astrological_subject.py +0 -52
  90. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/test_astrological_subject_jyotish.py +0 -26
  91. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/test_json_dump.py +1 -1
  92. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/test_relationship_score.py +8 -8
  93. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/test_utc.py +0 -1
  94. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/test_utilities.py +1 -1
  95. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/uv.lock +29 -72
  96. kerykeion-5.0.0a9/kerykeion/aspects/natal_aspects.py +0 -181
  97. kerykeion-5.0.0a9/kerykeion/aspects/synastry_aspects.py +0 -141
  98. kerykeion-5.0.0a9/kerykeion/aspects/transits_time_range.py +0 -41
  99. kerykeion-5.0.0a9/kerykeion/kr_types/__init__.py +0 -10
  100. kerykeion-5.0.0a9/tests/aspects/expected_natal_aspects.py +0 -1237
  101. kerykeion-5.0.0a9/tests/aspects/expected_synastry_aspects.py +0 -2861
  102. kerykeion-5.0.0a9/tests/charts/svg/Albert Einstein - Natal Chart.svg +0 -669
  103. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - DTS - Synastry Chart.svg +0 -699
  104. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - Dark High Contrast Theme - Natal Chart.svg +0 -708
  105. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - Dark Theme - Natal Chart.svg +0 -708
  106. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - Minified - Natal Chart.svg +0 -1
  107. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - SCTWL - Synastry Chart.svg +0 -699
  108. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - Synastry Chart.svg +0 -660
  109. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - TCWTG - Transit Chart.svg +0 -708
  110. kerykeion-5.0.0a9/tests/charts/svg/John Lennon - Transit Chart.svg +0 -669
  111. kerykeion-5.0.0a9/tests/charts/svg/John Lennon DeLuce - Natal Chart.svg +0 -669
  112. kerykeion-5.0.0a9/tests/charts/svg/Mehmet Oz - Natal Chart.svg +0 -669
  113. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/.github/FUNDING.yml +0 -0
  114. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/CHANGELOG.md +0 -0
  115. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/DEVELOPMENT.md +0 -0
  116. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/LICENSE +0 -0
  117. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/MANIFEST.in +0 -0
  118. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/README.md +0 -0
  119. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/TODO.md +0 -0
  120. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/index.html +0 -0
  121. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/aspects/aspects_utils.html +0 -0
  122. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/aspects/natal_aspects.html +0 -0
  123. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/aspects/synastry_aspects.html +0 -0
  124. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/aspects/transits_time_range.html +0 -0
  125. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/aspects.html +0 -0
  126. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/astrological_subject.html +0 -0
  127. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/charts/charts_utils.html +0 -0
  128. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/charts/draw_planets.html +0 -0
  129. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/charts/kerykeion_chart_svg.html +0 -0
  130. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/charts.html +0 -0
  131. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/composite_subject_factory.html +0 -0
  132. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/enums.html +0 -0
  133. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/ephemeris_data.html +0 -0
  134. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/fetch_geonames.html +0 -0
  135. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/kr_types/chart_types.html +0 -0
  136. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/kr_types/kerykeion_exception.html +0 -0
  137. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/kr_types/kr_literals.html +0 -0
  138. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/kr_types/kr_models.html +0 -0
  139. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/kr_types/settings_models.html +0 -0
  140. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/kr_types.html +0 -0
  141. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/relationship_score/relationship_score.html +0 -0
  142. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/relationship_score/relationship_score_factory.html +0 -0
  143. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/relationship_score.html +0 -0
  144. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/report.html +0 -0
  145. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/settings/config_constants.html +0 -0
  146. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/settings/kerykeion_settings.html +0 -0
  147. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/settings.html +0 -0
  148. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/transits_time_range.html +0 -0
  149. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion/utilities.html +0 -0
  150. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/kerykeion.html +0 -0
  151. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/docs/search.js +0 -0
  152. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/examples/README.md +0 -0
  153. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/examples/astrologiacal_subject.py +0 -0
  154. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/examples/charts/composite_chart.py +0 -0
  155. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/examples/charts/kerykeion_chart_svg.py +0 -0
  156. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/__init__.py +0 -0
  157. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/draw_planets_v3.py +0 -0
  158. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/templates/aspect_grid_only.xml +0 -0
  159. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/templates/chart.xml +0 -0
  160. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/templates/wheel_only.xml +0 -0
  161. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/themes/classic.css +0 -0
  162. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/themes/dark-high-contrast.css +0 -0
  163. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/themes/dark.css +0 -0
  164. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/themes/light.css +0 -0
  165. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/charts/themes/strawberry.css +0 -0
  166. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/enums.py +0 -0
  167. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/ephemeris_data.py +0 -0
  168. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/fetch_geonames.py +0 -0
  169. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/house_comparison/house_comparison_models.py +0 -0
  170. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/kr_types/chart_types.py +0 -0
  171. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/kr_types/kerykeion_exception.py +0 -0
  172. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/kr_types/kr_literals.py +0 -0
  173. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/settings/kerykeion_settings.py +0 -0
  174. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/settings/legacy/__init__.py +0 -0
  175. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/settings/legacy/legacy_celestial_points_settings.py +0 -0
  176. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/settings/legacy/legacy_chart_aspects_settings.py +0 -0
  177. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/settings/legacy/legacy_color_settings.py +0 -0
  178. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/sweph/README.md +0 -0
  179. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/kerykeion/sweph/seas_18.se1 +0 -0
  180. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/V4.14.0.md +0 -0
  181. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/V4.16.0.md +0 -0
  182. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/V4.17.0.md +0 -0
  183. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/V4.19.0.md +0 -0
  184. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/V4.21.0.md +0 -0
  185. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/V4.22.0.md +0 -0
  186. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/V4.23.0.md +0 -0
  187. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/V4.24.0.md +0 -0
  188. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/V4.25.0.md +0 -0
  189. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/V4.26.0.md +0 -0
  190. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/release_notes/v5.0.0a1.md +0 -0
  191. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/__init__.py +0 -0
  192. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/aspects/__init__.py +0 -0
  193. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/__init__.py +0 -0
  194. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/compare_svg_lines.py +0 -0
  195. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/charts/test_charts.py +0 -0
  196. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/settings/test_settings.py +0 -0
  197. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/test_ephemeris_data.py +0 -0
  198. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/test_fetch_geonames.py +0 -0
  199. {kerykeion-5.0.0a9 → kerykeion-5.0.0a10}/tests/test_report.py +0 -0
@@ -51,4 +51,4 @@ dist/
51
51
  kr_venv
52
52
  request_cache
53
53
  Pipfile
54
- .mypy_cache
54
+ .mypy_cache
@@ -1,23 +1,28 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kerykeion
3
- Version: 5.0.0a9
4
- Summary: A python library for astrology.
3
+ Version: 5.0.0a10
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
7
7
  Author-email: Giacomo Battaglia <kerykeion.astrology@gmail.com>
8
8
  License: AGPL-3.0
9
9
  License-File: LICENSE
10
- Keywords: astrology,astrology library,astrology-calculator,astronomical-algorithms,birtchart,ephemeris,svg,synastry,zodiac,zodiac-sing
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
11
  Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Intended Audience :: Information Technology
14
- Classifier: License :: OSI Approved :: GNU General Public License (GPL)
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
15
16
  Classifier: Operating System :: OS Independent
16
17
  Classifier: Programming Language :: Python :: 3 :: Only
17
18
  Classifier: Programming Language :: Python :: 3.9
18
19
  Classifier: Programming Language :: Python :: 3.10
19
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
20
24
  Classifier: Topic :: Scientific/Engineering :: Astronomy
25
+ Classifier: Topic :: Scientific/Engineering :: Visualization
21
26
  Classifier: Topic :: Software Development
22
27
  Classifier: Topic :: Software Development :: Libraries
23
28
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
@@ -6,7 +6,7 @@ This is part of Kerykeion (C) 2025 Giacomo Battaglia
6
6
  """
7
7
 
8
8
  # Local
9
- from .aspects import SynastryAspects, NatalAspects
9
+ from .aspects import SynastryAspectsFactory, NatalAspectsFactory
10
10
  from .astrological_subject_factory import AstrologicalSubjectFactory
11
11
  from .charts.kerykeion_chart_svg import KerykeionChartSVG
12
12
  from .composite_subject_factory import CompositeSubjectFactory
@@ -20,3 +20,24 @@ from .relationship_score_factory import RelationshipScoreFactory
20
20
  from .report import Report
21
21
  from .settings import KerykeionSettingsModel, get_settings
22
22
  from .transits_time_range import TransitsTimeRangeFactory
23
+
24
+ __all__ = [
25
+ "SynastryAspectsFactory",
26
+ "NatalAspectsFactory",
27
+ "AstrologicalSubjectFactory",
28
+ "KerykeionChartSVG",
29
+ "CompositeSubjectFactory",
30
+ "Planets",
31
+ "Aspects",
32
+ "Signs",
33
+ "EphemerisDataFactory",
34
+ "HouseComparisonFactory",
35
+ "HouseComparisonModel",
36
+ "PlanetaryReturnFactory",
37
+ "PlanetReturnModel",
38
+ "RelationshipScoreFactory",
39
+ "Report",
40
+ "KerykeionSettingsModel",
41
+ "get_settings",
42
+ "TransitsTimeRangeFactory",
43
+ ]
@@ -7,5 +7,10 @@ The aspects module contains the classes and functions for calculating
7
7
  """
8
8
 
9
9
 
10
- from .synastry_aspects import SynastryAspects
11
- from .natal_aspects import NatalAspects
10
+ from .synastry_aspects_factory import SynastryAspectsFactory
11
+ from .natal_aspects_factory import NatalAspectsFactory
12
+
13
+ __all__ = [
14
+ "SynastryAspectsFactory",
15
+ "NatalAspectsFactory",
16
+ ]
@@ -4,17 +4,15 @@
4
4
  """
5
5
  # TODO: Better documentation and unit tests
6
6
 
7
- from kerykeion.settings import KerykeionSettingsModel
8
7
  from swisseph import difdeg2n
9
8
  from typing import Union, TYPE_CHECKING
10
9
  from kerykeion.kr_types.kr_models import AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel
11
- from kerykeion.kr_types.kr_literals import AstrologicalPoint
12
10
  from kerykeion.kr_types.settings_models import KerykeionSettingsCelestialPointModel
13
11
  from kerykeion.settings.legacy.legacy_celestial_points_settings import DEFAULT_CELESTIAL_POINTS_SETTINGS
14
12
 
15
13
 
16
14
  if TYPE_CHECKING:
17
- from kerykeion import AstrologicalSubjectFactory
15
+ pass
18
16
 
19
17
  def get_aspect_from_two_points(
20
18
  aspects_settings: Union[list[dict], list[dict]],
@@ -0,0 +1,236 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ This is part of Kerykeion (C) 2025 Giacomo Battaglia
4
+ """
5
+
6
+ import logging
7
+ from pathlib import Path
8
+ from typing import Union, List, Optional
9
+
10
+ from kerykeion.astrological_subject_factory import AstrologicalSubjectFactory
11
+ from kerykeion.aspects.aspects_utils import get_aspect_from_two_points, get_active_points_list
12
+ from kerykeion.kr_types.kr_models import AstrologicalSubjectModel, AspectModel, ActiveAspect, CompositeSubjectModel, PlanetReturnModel, NatalAspectsModel
13
+ from kerykeion.kr_types.kr_literals import AstrologicalPoint
14
+ from kerykeion.kr_types.settings_models import KerykeionSettingsModel
15
+ from kerykeion.settings.config_constants import DEFAULT_ACTIVE_ASPECTS, DEFAULT_AXIS_ORBIT
16
+ from kerykeion.settings.legacy.legacy_celestial_points_settings import DEFAULT_CELESTIAL_POINTS_SETTINGS
17
+ from kerykeion.settings.legacy.legacy_chart_aspects_settings import DEFAULT_CHART_ASPECTS_SETTINGS
18
+ from kerykeion.utilities import find_common_active_points
19
+
20
+ # Axes constants for orb filtering
21
+ AXES_LIST = [
22
+ "Ascendant",
23
+ "Medium_Coeli",
24
+ "Descendant",
25
+ "Imum_Coeli",
26
+ ]
27
+
28
+
29
+ class NatalAspectsFactory:
30
+ """
31
+ Factory class for creating natal aspects analysis.
32
+
33
+ This factory calculates all aspects in a birth chart and provides both
34
+ comprehensive and filtered aspect lists based on orb settings and relevance.
35
+ """
36
+
37
+ @staticmethod
38
+ def from_subject(
39
+ user: Union[AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel],
40
+ new_settings_file: Union[Path, KerykeionSettingsModel, dict, None] = None,
41
+ active_points: Optional[List[AstrologicalPoint]] = None,
42
+ active_aspects: Optional[List[ActiveAspect]] = None,
43
+ ) -> NatalAspectsModel:
44
+ """
45
+ Create natal aspects analysis from an existing astrological subject.
46
+
47
+ Args:
48
+ user: The astrological subject for aspect calculation
49
+ new_settings_file: Custom settings file or settings model
50
+ active_points: List of points to include in calculations
51
+ active_aspects: List of aspects with their orb settings
52
+
53
+ Returns:
54
+ NatalAspectsModel containing all calculated aspects data
55
+ """
56
+ # Initialize settings and configurations
57
+ celestial_points = DEFAULT_CELESTIAL_POINTS_SETTINGS
58
+ aspects_settings = DEFAULT_CHART_ASPECTS_SETTINGS
59
+ axes_orbit_settings = DEFAULT_AXIS_ORBIT
60
+
61
+ # Set active aspects with default fallback
62
+ active_aspects_resolved = active_aspects if active_aspects is not None else DEFAULT_ACTIVE_ASPECTS
63
+
64
+ # Determine active points to use
65
+ if active_points is None:
66
+ active_points_resolved = user.active_points
67
+ else:
68
+ active_points_resolved = find_common_active_points(
69
+ user.active_points,
70
+ active_points,
71
+ )
72
+
73
+ return NatalAspectsFactory._create_natal_aspects_model(
74
+ user, active_points_resolved, active_aspects_resolved,
75
+ aspects_settings, axes_orbit_settings, celestial_points
76
+ )
77
+
78
+ @staticmethod
79
+ def _create_natal_aspects_model(
80
+ user: Union[AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel],
81
+ active_points_resolved: List[AstrologicalPoint],
82
+ active_aspects_resolved: List[ActiveAspect],
83
+ aspects_settings: List[dict],
84
+ axes_orbit_settings: float,
85
+ celestial_points: List[dict]
86
+ ) -> NatalAspectsModel:
87
+ """
88
+ Create the complete natal aspects model with all calculations.
89
+
90
+ Returns:
91
+ NatalAspectsModel containing all aspects data
92
+ """
93
+ all_aspects = NatalAspectsFactory._calculate_all_aspects(
94
+ user, active_points_resolved, active_aspects_resolved, aspects_settings, celestial_points
95
+ )
96
+ relevant_aspects = NatalAspectsFactory._filter_relevant_aspects(all_aspects, axes_orbit_settings)
97
+
98
+ return NatalAspectsModel(
99
+ subject=user,
100
+ all_aspects=all_aspects,
101
+ relevant_aspects=relevant_aspects,
102
+ active_points=active_points_resolved,
103
+ active_aspects=active_aspects_resolved,
104
+ )
105
+
106
+ @staticmethod
107
+ def _calculate_all_aspects(
108
+ user: Union[AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel],
109
+ active_points: List[AstrologicalPoint],
110
+ active_aspects: List[ActiveAspect],
111
+ aspects_settings: List[dict],
112
+ celestial_points: List[dict]
113
+ ) -> List[AspectModel]:
114
+ """
115
+ Calculate all aspects between active points in the natal chart.
116
+
117
+ This method handles all aspect calculations including settings updates,
118
+ opposite pair filtering, and planet ID resolution in a single comprehensive method.
119
+
120
+ Returns:
121
+ List of all calculated AspectModel instances
122
+ """
123
+ active_points_list = get_active_points_list(user, active_points)
124
+
125
+ # Update aspects settings with active aspects orbs
126
+ filtered_settings = []
127
+ for aspect_setting in aspects_settings:
128
+ for active_aspect in active_aspects:
129
+ if aspect_setting["name"] == active_aspect["name"]:
130
+ aspect_setting = aspect_setting.copy() # Don't modify original
131
+ aspect_setting["orb"] = active_aspect["orb"]
132
+ filtered_settings.append(aspect_setting)
133
+ break
134
+
135
+ # Define opposite pairs that should be skipped
136
+ opposite_pairs = {
137
+ ("Ascendant", "Descendant"),
138
+ ("Descendant", "Ascendant"),
139
+ ("Medium_Coeli", "Imum_Coeli"),
140
+ ("Imum_Coeli", "Medium_Coeli"),
141
+ ("True_Node", "True_South_Node"),
142
+ ("Mean_Node", "Mean_South_Node"),
143
+ ("True_South_Node", "True_Node"),
144
+ ("Mean_South_Node", "Mean_Node"),
145
+ }
146
+
147
+ all_aspects_list = []
148
+
149
+ for first in range(len(active_points_list)):
150
+ # Generate aspects list without repetitions
151
+ for second in range(first + 1, len(active_points_list)):
152
+ # Skip predefined opposite pairs (AC/DC, MC/IC, North/South nodes)
153
+ first_name = active_points_list[first]["name"]
154
+ second_name = active_points_list[second]["name"]
155
+
156
+ if (first_name, second_name) in opposite_pairs:
157
+ continue
158
+
159
+ aspect = get_aspect_from_two_points(
160
+ filtered_settings,
161
+ active_points_list[first]["abs_pos"],
162
+ active_points_list[second]["abs_pos"]
163
+ )
164
+
165
+ if aspect["verdict"]:
166
+ # Get planet IDs directly from celestial points settings
167
+ first_planet_id = 0
168
+ second_planet_id = 0
169
+
170
+ for planet in celestial_points:
171
+ if planet["name"] == first_name:
172
+ first_planet_id = planet["id"]
173
+ if planet["name"] == second_name:
174
+ second_planet_id = planet["id"]
175
+
176
+ aspect_model = AspectModel(
177
+ p1_name=first_name,
178
+ p1_owner=user.name,
179
+ p1_abs_pos=active_points_list[first]["abs_pos"],
180
+ p2_name=second_name,
181
+ p2_owner=user.name,
182
+ p2_abs_pos=active_points_list[second]["abs_pos"],
183
+ aspect=aspect["name"],
184
+ orbit=aspect["orbit"],
185
+ aspect_degrees=aspect["aspect_degrees"],
186
+ diff=aspect["diff"],
187
+ p1=first_planet_id,
188
+ p2=second_planet_id,
189
+ )
190
+ all_aspects_list.append(aspect_model)
191
+
192
+ return all_aspects_list
193
+
194
+ @staticmethod
195
+ def _filter_relevant_aspects(all_aspects: List[AspectModel], axes_orbit_settings: float) -> List[AspectModel]:
196
+ """
197
+ Filter aspects based on orb thresholds for axes and other comprehensive criteria.
198
+
199
+ This method consolidates all filtering logic including axes checks and orb thresholds
200
+ into a single comprehensive filtering method.
201
+
202
+ Args:
203
+ all_aspects: Complete list of calculated aspects
204
+ axes_orbit_settings: Orb threshold for axes aspects
205
+
206
+ Returns:
207
+ Filtered list of relevant aspects
208
+ """
209
+ logging.debug("Calculating relevant aspects by filtering orbs...")
210
+
211
+ relevant_aspects = []
212
+
213
+ for aspect in all_aspects:
214
+ # Check if aspect involves any of the chart axes and apply stricter orb limits
215
+ aspect_involves_axes = (aspect.p1_name in AXES_LIST or aspect.p2_name in AXES_LIST)
216
+
217
+ if aspect_involves_axes and abs(aspect.orbit) >= axes_orbit_settings:
218
+ continue
219
+
220
+ relevant_aspects.append(aspect)
221
+
222
+ return relevant_aspects
223
+
224
+
225
+ if __name__ == "__main__":
226
+ from kerykeion.utilities import setup_logging
227
+
228
+ setup_logging(level="debug")
229
+
230
+ # Create subject using AstrologicalSubjectFactory
231
+ johnny = AstrologicalSubjectFactory.from_birth_data("Johnny Depp", 1963, 6, 9, 0, 0, city="Owensboro", nation="US")
232
+
233
+ # Create aspects analysis from subject
234
+ natal_aspects = NatalAspectsFactory.from_subject(johnny)
235
+ print(f"All aspects count: {len(natal_aspects.all_aspects)}")
236
+ print(f"Relevant aspects count: {len(natal_aspects.relevant_aspects)}")
@@ -0,0 +1,234 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ This is part of Kerykeion (C) 2025 Giacomo Battaglia
4
+ """
5
+
6
+ import logging
7
+ from pathlib import Path
8
+ from typing import Union, List, Optional
9
+
10
+ from kerykeion.astrological_subject_factory import AstrologicalSubjectFactory
11
+ from kerykeion.aspects.aspects_utils import get_aspect_from_two_points, get_active_points_list
12
+ from kerykeion.kr_types.kr_models import AstrologicalSubjectModel, AspectModel, ActiveAspect, CompositeSubjectModel, PlanetReturnModel, SynastryAspectsModel
13
+ from kerykeion.kr_types.settings_models import KerykeionSettingsModel
14
+ from kerykeion.settings.config_constants import DEFAULT_ACTIVE_ASPECTS, DEFAULT_AXIS_ORBIT
15
+ from kerykeion.settings.legacy.legacy_celestial_points_settings import DEFAULT_CELESTIAL_POINTS_SETTINGS
16
+ from kerykeion.settings.legacy.legacy_chart_aspects_settings import DEFAULT_CHART_ASPECTS_SETTINGS
17
+ from kerykeion.kr_types.kr_literals import AstrologicalPoint
18
+ from kerykeion.utilities import find_common_active_points
19
+
20
+
21
+ # Axes constants for orb filtering
22
+ AXES_LIST = [
23
+ "Ascendant",
24
+ "Medium_Coeli",
25
+ "Descendant",
26
+ "Imum_Coeli",
27
+ ]
28
+
29
+
30
+ class SynastryAspectsFactory:
31
+ """
32
+ Factory class for creating synastry aspects analysis between two subjects.
33
+
34
+ This factory calculates all aspects between two charts and provides both
35
+ comprehensive and filtered aspect lists based on orb settings and relevance.
36
+ """
37
+
38
+ @staticmethod
39
+ def from_subjects(
40
+ first_subject: Union[AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel],
41
+ second_subject: Union[AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel],
42
+ new_settings_file: Union[Path, KerykeionSettingsModel, dict, None] = None,
43
+ active_points: Optional[List[AstrologicalPoint]] = None,
44
+ active_aspects: Optional[List[ActiveAspect]] = None,
45
+ ) -> SynastryAspectsModel:
46
+ """
47
+ Create synastry aspects analysis from two existing astrological subjects.
48
+
49
+ Args:
50
+ first_subject: The first astrological subject
51
+ second_subject: The second astrological subject
52
+ new_settings_file: Custom settings file or settings model
53
+ active_points: List of points to include in calculations
54
+ active_aspects: List of aspects with their orb settings
55
+
56
+ Returns:
57
+ SynastryAspectsModel containing all calculated aspects data
58
+ """
59
+ # Initialize settings and configurations
60
+ celestial_points = DEFAULT_CELESTIAL_POINTS_SETTINGS
61
+ aspects_settings = DEFAULT_CHART_ASPECTS_SETTINGS
62
+ axes_orbit_settings = DEFAULT_AXIS_ORBIT
63
+
64
+ # Set active aspects with default fallback
65
+ active_aspects_resolved = active_aspects if active_aspects is not None else DEFAULT_ACTIVE_ASPECTS
66
+
67
+ # Determine active points to use - find common points between both subjects
68
+ if active_points is None:
69
+ active_points_resolved = first_subject.active_points
70
+ else:
71
+ active_points_resolved = find_common_active_points(
72
+ first_subject.active_points,
73
+ active_points,
74
+ )
75
+
76
+ # Further filter with second subject's active points
77
+ active_points_resolved = find_common_active_points(
78
+ second_subject.active_points,
79
+ active_points_resolved,
80
+ )
81
+
82
+ return SynastryAspectsFactory._create_synastry_aspects_model(
83
+ first_subject, second_subject, active_points_resolved, active_aspects_resolved,
84
+ aspects_settings, axes_orbit_settings, celestial_points
85
+ )
86
+
87
+ @staticmethod
88
+ def _create_synastry_aspects_model(
89
+ first_subject: Union[AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel],
90
+ second_subject: Union[AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel],
91
+ active_points_resolved: List[AstrologicalPoint],
92
+ active_aspects_resolved: List[ActiveAspect],
93
+ aspects_settings: List[dict],
94
+ axes_orbit_settings: float,
95
+ celestial_points: List[dict]
96
+ ) -> SynastryAspectsModel:
97
+ """
98
+ Create the complete synastry aspects model with all calculations.
99
+
100
+ Returns:
101
+ SynastryAspectsModel containing all aspects data
102
+ """
103
+ all_aspects = SynastryAspectsFactory._calculate_all_aspects(
104
+ first_subject, second_subject, active_points_resolved, active_aspects_resolved,
105
+ aspects_settings, celestial_points
106
+ )
107
+ relevant_aspects = SynastryAspectsFactory._filter_relevant_aspects(all_aspects, axes_orbit_settings)
108
+
109
+ return SynastryAspectsModel(
110
+ first_subject=first_subject,
111
+ second_subject=second_subject,
112
+ all_aspects=all_aspects,
113
+ relevant_aspects=relevant_aspects,
114
+ active_points=active_points_resolved,
115
+ active_aspects=active_aspects_resolved,
116
+ )
117
+
118
+ @staticmethod
119
+ def _calculate_all_aspects(
120
+ first_subject: Union[AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel],
121
+ second_subject: Union[AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel],
122
+ active_points: List[AstrologicalPoint],
123
+ active_aspects: List[ActiveAspect],
124
+ aspects_settings: List[dict],
125
+ celestial_points: List[dict]
126
+ ) -> List[AspectModel]:
127
+ """
128
+ Calculate all synastry aspects between two subjects.
129
+
130
+ This method handles all aspect calculations including settings updates
131
+ and planet ID resolution in a single comprehensive method.
132
+
133
+ Returns:
134
+ List of all calculated AspectModel instances
135
+ """
136
+ # Get active points lists for both subjects
137
+ first_active_points_list = get_active_points_list(first_subject, active_points)
138
+ second_active_points_list = get_active_points_list(second_subject, active_points)
139
+
140
+ # Update aspects settings with active aspects orbs
141
+ filtered_settings = []
142
+ for aspect_setting in aspects_settings:
143
+ for active_aspect in active_aspects:
144
+ if aspect_setting["name"] == active_aspect["name"]:
145
+ aspect_setting = aspect_setting.copy() # Don't modify original
146
+ aspect_setting["orb"] = active_aspect["orb"]
147
+ filtered_settings.append(aspect_setting)
148
+ break
149
+
150
+ all_aspects_list = []
151
+ for first in range(len(first_active_points_list)):
152
+ # Generate aspects list between all points of first and second subjects
153
+ for second in range(len(second_active_points_list)):
154
+ aspect = get_aspect_from_two_points(
155
+ filtered_settings,
156
+ first_active_points_list[first]["abs_pos"],
157
+ second_active_points_list[second]["abs_pos"],
158
+ )
159
+
160
+ if aspect["verdict"]:
161
+ # Get planet IDs directly from celestial points settings
162
+ first_planet_id = 0
163
+ second_planet_id = 0
164
+
165
+ first_name = first_active_points_list[first]["name"]
166
+ second_name = second_active_points_list[second]["name"]
167
+
168
+ for planet in celestial_points:
169
+ if planet["name"] == first_name:
170
+ first_planet_id = planet["id"]
171
+ if planet["name"] == second_name:
172
+ second_planet_id = planet["id"]
173
+
174
+ aspect_model = AspectModel(
175
+ p1_name=first_name,
176
+ p1_owner=first_subject.name,
177
+ p1_abs_pos=first_active_points_list[first]["abs_pos"],
178
+ p2_name=second_name,
179
+ p2_owner=second_subject.name,
180
+ p2_abs_pos=second_active_points_list[second]["abs_pos"],
181
+ aspect=aspect["name"],
182
+ orbit=aspect["orbit"],
183
+ aspect_degrees=aspect["aspect_degrees"],
184
+ diff=aspect["diff"],
185
+ p1=first_planet_id,
186
+ p2=second_planet_id,
187
+ )
188
+ all_aspects_list.append(aspect_model)
189
+
190
+ return all_aspects_list
191
+
192
+ @staticmethod
193
+ def _filter_relevant_aspects(all_aspects: List[AspectModel], axes_orbit_settings: float) -> List[AspectModel]:
194
+ """
195
+ Filter aspects based on orb thresholds for axes and comprehensive criteria.
196
+
197
+ This method consolidates all filtering logic including axes checks and orb thresholds
198
+ for synastry aspects in a single comprehensive filtering method.
199
+
200
+ Args:
201
+ all_aspects: Complete list of calculated aspects
202
+ axes_orbit_settings: Orb threshold for axes aspects
203
+
204
+ Returns:
205
+ Filtered list of relevant aspects
206
+ """
207
+ logging.debug("Calculating relevant synastry aspects by filtering orbs...")
208
+
209
+ relevant_aspects = []
210
+
211
+ for aspect in all_aspects:
212
+ # Check if aspect involves any of the chart axes and apply stricter orb limits
213
+ aspect_involves_axes = (aspect.p1_name in AXES_LIST or aspect.p2_name in AXES_LIST)
214
+
215
+ if aspect_involves_axes and abs(aspect.orbit) >= axes_orbit_settings:
216
+ continue
217
+
218
+ relevant_aspects.append(aspect)
219
+
220
+ return relevant_aspects
221
+
222
+
223
+ if __name__ == "__main__":
224
+ from kerykeion.utilities import setup_logging
225
+
226
+ setup_logging(level="debug")
227
+
228
+ john = AstrologicalSubjectFactory.from_birth_data("John", 1940, 10, 9, 10, 30, "Liverpool", "GB")
229
+ yoko = AstrologicalSubjectFactory.from_birth_data("Yoko", 1933, 2, 18, 10, 30, "Tokyo", "JP")
230
+
231
+ # Create synastry aspects analysis using the factory
232
+ synastry_aspects_model = SynastryAspectsFactory.from_subjects(john, yoko)
233
+ print(f"All synastry aspects: {len(synastry_aspects_model.all_aspects)}")
234
+ print(f"Relevant synastry aspects: {len(synastry_aspects_model.relevant_aspects)}")
@@ -6,14 +6,11 @@
6
6
  import pytz
7
7
  import swisseph as swe
8
8
  import logging
9
- import warnings
10
9
  import math
11
10
  from datetime import datetime
12
11
  from pathlib import Path
13
- from typing import Union, Optional, List, Dict, Any, Literal, get_args, cast, TypedDict, Set
14
- from functools import cached_property, lru_cache
12
+ from typing import Optional, List, Dict, Any, get_args, cast
15
13
  from dataclasses import dataclass, field
16
- from typing import Callable
17
14
 
18
15
 
19
16
  from kerykeion.fetch_geonames import FetchGeonames
@@ -21,8 +18,6 @@ from kerykeion.kr_types import (
21
18
  KerykeionException,
22
19
  ZodiacType,
23
20
  AstrologicalSubjectModel,
24
- LunarPhaseModel,
25
- KerykeionPointModel,
26
21
  PointType,
27
22
  SiderealMode,
28
23
  HousesSystemIdentifier,
@@ -31,7 +26,6 @@ from kerykeion.kr_types import (
31
26
  Houses,
32
27
  )
33
28
  from kerykeion.utilities import (
34
- get_number_from_name,
35
29
  get_kerykeion_point_from_degree,
36
30
  get_planet_house,
37
31
  check_and_adjust_polar_latitude,
@@ -527,7 +521,8 @@ class AstrologicalSubjectFactory:
527
521
  def _calculate_houses(cls, data: Dict[str, Any], active_points: Optional[List[AstrologicalPoint]]) -> None:
528
522
  """Calculate house cusps and axis points"""
529
523
  # Skip calculation if point is not in active_points
530
- should_calculate: Callable[[AstrologicalPoint], bool] = lambda point: not active_points or point in active_points
524
+ def should_calculate(point: AstrologicalPoint) -> bool:
525
+ return not active_points or point in active_points
531
526
  # Track which axial cusps are actually calculated
532
527
  calculated_axial_cusps = []
533
528
 
@@ -656,7 +651,8 @@ class AstrologicalSubjectFactory:
656
651
  def _calculate_planets(cls, data: Dict[str, Any], active_points: List[AstrologicalPoint]) -> None:
657
652
  """Calculate planetary positions and related information"""
658
653
  # Skip calculation if point is not in active_points
659
- should_calculate: Callable[[AstrologicalPoint], bool] = lambda point: not active_points or point in active_points
654
+ def should_calculate(point: AstrologicalPoint) -> bool:
655
+ return not active_points or point in active_points
660
656
 
661
657
  point_type: PointType = "AstrologicalPoint"
662
658
  julian_day = data["julian_day"]