kerykeion 5.1.5__tar.gz → 5.1.7__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 (249) hide show
  1. {kerykeion-5.1.5 → kerykeion-5.1.7}/PKG-INFO +3 -1
  2. {kerykeion-5.1.5 → kerykeion-5.1.7}/README.md +2 -0
  3. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/astrological_subject_factory.py +18 -14
  4. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/backword.py +44 -1
  5. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/chart_drawer.py +15 -12
  6. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/ephemeris_data_factory.py +13 -4
  7. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/fetch_geonames.py +16 -11
  8. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/report.py +1 -2
  9. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/schemas/kr_literals.py +1 -1
  10. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/settings/kerykeion_settings.py +1 -1
  11. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/utilities.py +121 -121
  12. {kerykeion-5.1.5 → kerykeion-5.1.7}/pyproject.toml +1 -1
  13. kerykeion-5.1.7/scripts/regenerate_expected_subjects.py +170 -0
  14. {kerykeion-5.1.5 → kerykeion-5.1.7}/scripts/regenerate_test_charts.py +34 -0
  15. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/astrological_subject_factory.md +11 -11
  16. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/composite_subject_factory.md +2 -2
  17. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/aspects/test_natal_aspects.py +0 -11
  18. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/aspects/test_synastry_aspects.py +0 -10
  19. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Black and White Theme - Transit Chart.svg +2 -2
  20. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - TCWTG - Transit Chart.svg +2 -2
  21. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Transit Chart.svg +2 -2
  22. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Moon Phases.svg +15 -15
  23. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/test_charts.py +0 -10
  24. kerykeion-5.1.7/tests/data/__init__.py +11 -0
  25. kerykeion-5.1.7/tests/data/expected_astrological_subjects.py +652 -0
  26. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_astrological_subject.py +10 -398
  27. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_astrological_subject_jyotish.py +4 -402
  28. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_chart_drawer_complete.py +28 -0
  29. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_ephemeris_data.py +0 -10
  30. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_fetch_geonames.py +2 -12
  31. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_json_dump.py +1 -11
  32. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_relationship_score.py +0 -9
  33. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_utc.py +0 -10
  34. kerykeion-5.1.7/tests/test_utilities.py +163 -0
  35. kerykeion-5.1.5/tests/test_utilities.py +0 -341
  36. {kerykeion-5.1.5 → kerykeion-5.1.7}/.coveragerc +0 -0
  37. {kerykeion-5.1.5 → kerykeion-5.1.7}/.github/FUNDING.yml +0 -0
  38. {kerykeion-5.1.5 → kerykeion-5.1.7}/.gitignore +0 -0
  39. {kerykeion-5.1.5 → kerykeion-5.1.7}/CHANGELOG.md +0 -0
  40. {kerykeion-5.1.5 → kerykeion-5.1.7}/DEVELOPMENT.md +0 -0
  41. {kerykeion-5.1.5 → kerykeion-5.1.7}/LICENSE +0 -0
  42. {kerykeion-5.1.5 → kerykeion-5.1.7}/MANIFEST.in +0 -0
  43. {kerykeion-5.1.5 → kerykeion-5.1.7}/TODO.md +0 -0
  44. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/index.html +0 -0
  45. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/aspects/aspects_utils.html +0 -0
  46. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/aspects/natal_aspects.html +0 -0
  47. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/aspects/synastry_aspects.html +0 -0
  48. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/aspects/transits_time_range.html +0 -0
  49. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/aspects.html +0 -0
  50. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/astrological_subject.html +0 -0
  51. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/charts/charts_utils.html +0 -0
  52. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/charts/draw_planets.html +0 -0
  53. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/charts/kerykeion_chart_svg.html +0 -0
  54. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/charts.html +0 -0
  55. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/composite_subject_factory.html +0 -0
  56. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/enums.html +0 -0
  57. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/ephemeris_data.html +0 -0
  58. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/fetch_geonames.html +0 -0
  59. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/kr_types/chart_types.html +0 -0
  60. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/kr_types/kerykeion_exception.html +0 -0
  61. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/kr_types/kr_literals.html +0 -0
  62. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/kr_types/kr_models.html +0 -0
  63. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/kr_types/settings_models.html +0 -0
  64. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/kr_types.html +0 -0
  65. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/relationship_score/relationship_score.html +0 -0
  66. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/relationship_score/relationship_score_factory.html +0 -0
  67. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/relationship_score.html +0 -0
  68. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/report.html +0 -0
  69. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/settings/config_constants.html +0 -0
  70. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/settings/kerykeion_settings.html +0 -0
  71. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/settings.html +0 -0
  72. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/transits_time_range.html +0 -0
  73. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion/utilities.html +0 -0
  74. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/kerykeion.html +0 -0
  75. {kerykeion-5.1.5 → kerykeion-5.1.7}/docs/search.js +0 -0
  76. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/aspects_synastry.py +0 -0
  77. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/composite_report_example.py +0 -0
  78. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/current_time_report.py +0 -0
  79. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/dual_return_report_example.py +0 -0
  80. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/natal_report_example.py +0 -0
  81. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/planetary_return.py +0 -0
  82. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/quickstart_natal_chart.py +0 -0
  83. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/solar_return_report_example.py +0 -0
  84. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/subject_report_example.py +0 -0
  85. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/synastry_report_example.py +0 -0
  86. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/transit_report_example.py +0 -0
  87. {kerykeion-5.1.5 → kerykeion-5.1.7}/examples/transits_time_range.py +0 -0
  88. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/__init__.py +0 -0
  89. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/aspects/__init__.py +0 -0
  90. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/aspects/aspects_factory.py +0 -0
  91. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/aspects/aspects_utils.py +0 -0
  92. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/chart_data_factory.py +0 -0
  93. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/__init__.py +0 -0
  94. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/charts_utils.py +0 -0
  95. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/draw_planets.py +0 -0
  96. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/templates/aspect_grid_only.xml +0 -0
  97. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/templates/chart.xml +0 -0
  98. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/templates/wheel_only.xml +0 -0
  99. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/themes/black-and-white.css +0 -0
  100. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/themes/classic.css +0 -0
  101. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/themes/dark-high-contrast.css +0 -0
  102. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/themes/dark.css +0 -0
  103. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/themes/light.css +0 -0
  104. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/charts/themes/strawberry.css +0 -0
  105. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/composite_subject_factory.py +0 -0
  106. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/house_comparison/__init__.py +0 -0
  107. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/house_comparison/house_comparison_factory.py +0 -0
  108. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/house_comparison/house_comparison_utils.py +0 -0
  109. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/kr_types/__init__.py +0 -0
  110. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/kr_types/chart_template_model.py +0 -0
  111. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/kr_types/kerykeion_exception.py +0 -0
  112. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/kr_types/kr_literals.py +0 -0
  113. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/kr_types/kr_models.py +0 -0
  114. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/kr_types/settings_models.py +0 -0
  115. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/planetary_return_factory.py +0 -0
  116. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/relationship_score_factory.py +0 -0
  117. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/schemas/__init__.py +0 -0
  118. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/schemas/chart_template_model.py +0 -0
  119. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/schemas/kerykeion_exception.py +0 -0
  120. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/schemas/kr_models.py +0 -0
  121. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/schemas/settings_models.py +0 -0
  122. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/settings/__init__.py +0 -0
  123. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/settings/chart_defaults.py +0 -0
  124. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/settings/config_constants.py +0 -0
  125. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/settings/translation_strings.py +0 -0
  126. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/settings/translations.py +0 -0
  127. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/sweph/README.md +0 -0
  128. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/sweph/ast136/s136108s.se1 +0 -0
  129. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/sweph/ast136/s136199s.se1 +0 -0
  130. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/sweph/ast136/s136472s.se1 +0 -0
  131. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/sweph/ast28/se28978s.se1 +0 -0
  132. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/sweph/ast50/se50000s.se1 +0 -0
  133. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/sweph/ast90/se90377s.se1 +0 -0
  134. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/sweph/ast90/se90482s.se1 +0 -0
  135. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/sweph/seas_18.se1 +0 -0
  136. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/sweph/sefstars.txt +0 -0
  137. {kerykeion-5.1.5 → kerykeion-5.1.7}/kerykeion/transits_time_range_factory.py +0 -0
  138. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/V4.14.0.md +0 -0
  139. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/V4.16.0.md +0 -0
  140. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/V4.17.0.md +0 -0
  141. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/V4.19.0.md +0 -0
  142. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/V4.21.0.md +0 -0
  143. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/V4.22.0.md +0 -0
  144. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/V4.23.0.md +0 -0
  145. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/V4.24.0.md +0 -0
  146. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/V4.25.0.md +0 -0
  147. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/V4.26.0.md +0 -0
  148. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/v5.0.0.md +0 -0
  149. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/v5.0.0a.md +0 -0
  150. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/v5.0.0b.md +0 -0
  151. {kerykeion-5.1.5 → kerykeion-5.1.7}/release_notes/v5.1.0.md +0 -0
  152. {kerykeion-5.1.5 → kerykeion-5.1.7}/scripts/README.md +0 -0
  153. {kerykeion-5.1.5 → kerykeion-5.1.7}/scripts/__init__.py +0 -0
  154. {kerykeion-5.1.5 → kerykeion-5.1.7}/scripts/quality_check.py +0 -0
  155. {kerykeion-5.1.5 → kerykeion-5.1.7}/scripts/regenerate_expected_aspects.py +0 -0
  156. {kerykeion-5.1.5 → kerykeion-5.1.7}/scripts/regenerate_synastry_aspects.py +0 -0
  157. {kerykeion-5.1.5 → kerykeion-5.1.7}/scripts/regenerate_synastry_from_test.py +0 -0
  158. {kerykeion-5.1.5 → kerykeion-5.1.7}/scripts/test_markdown_snippets.py +0 -0
  159. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/aspects.md +0 -0
  160. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/chart_data_factory.md +0 -0
  161. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/charts.md +0 -0
  162. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/element_quality_distribution.md +0 -0
  163. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/ephemeris_data_factory.md +0 -0
  164. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/house_comparison.md +0 -0
  165. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/planetary_return_factory.md +0 -0
  166. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/relationship_score_factory.md +0 -0
  167. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/report.md +0 -0
  168. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/transits_time_range_factory.md +0 -0
  169. {kerykeion-5.1.5 → kerykeion-5.1.7}/site-docs/utilities.md +0 -0
  170. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/__init__.py +0 -0
  171. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/aspects/__init__.py +0 -0
  172. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/aspects/expected_natal_aspects.py +0 -0
  173. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/aspects/expected_synastry_aspects.py +0 -0
  174. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/__init__.py +0 -0
  175. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/compare_svg_lines.py +0 -0
  176. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Albert Einstein - Natal Chart.svg +0 -0
  177. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Amitabh Bachchan - Natal Chart.svg +0 -0
  178. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Angelina Jolie and Brad Pitt Composite Chart - Black and White Theme - Composite Chart.svg +0 -0
  179. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Angelina Jolie and Brad Pitt Composite Chart - Composite Chart.svg +0 -0
  180. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Antonio Banderas - Natal Chart.svg +0 -0
  181. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Cristiano Ronaldo - Natal Chart.svg +0 -0
  182. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Hua Chenyu - Natal Chart.svg +0 -0
  183. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Jeanne Moreau - Natal Chart.svg +0 -0
  184. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - All Active Points - Natal Chart - Aspect Grid Only.svg +0 -0
  185. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - All Active Points - Natal Chart - Wheel Only.svg +0 -0
  186. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - All Active Points - Natal Chart.svg +0 -0
  187. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - All Active Points - Synastry Chart - Aspect Grid Only.svg +0 -0
  188. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - All Active Points - Synastry Chart - Grid.svg +0 -0
  189. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - All Active Points - Synastry Chart - List.svg +0 -0
  190. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - All Active Points - Synastry Chart - Wheel Only.svg +0 -0
  191. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Aspect Grid Dark Synastry - Synastry Chart - Aspect Grid Only.svg +0 -0
  192. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Aspect Grid Dark Theme - Natal Chart - Aspect Grid Only.svg +0 -0
  193. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Aspect Grid Light Theme - Natal Chart - Aspect Grid Only.svg +0 -0
  194. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Aspect Grid Only - Natal Chart - Aspect Grid Only.svg +0 -0
  195. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Aspect Grid Synastry - Synastry Chart - Aspect Grid Only.svg +0 -0
  196. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Aspect Grid Transit - Transit Chart - Aspect Grid Only.svg +0 -0
  197. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Black and White Theme - DualReturnChart Chart - Solar Return.svg +0 -0
  198. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Black and White Theme - Natal Chart.svg +0 -0
  199. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Black and White Theme - Synastry Chart.svg +0 -0
  200. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - DTS - Synastry Chart.svg +0 -0
  201. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Dark High Contrast Theme - Natal Chart.svg +0 -0
  202. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Dark Theme - Natal Chart.svg +0 -0
  203. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Dark Theme External - Natal Chart.svg +0 -0
  204. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - DualReturnChart Chart - Lunar Return.svg +0 -0
  205. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - DualReturnChart Chart - Solar Return.svg +0 -0
  206. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - ExternalNatal - Natal Chart.svg +0 -0
  207. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Heliocentric - Natal Chart.svg +0 -0
  208. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - House System Morinus - Natal Chart.svg +0 -0
  209. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Light Theme - Natal Chart.svg +0 -0
  210. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Minified - Natal Chart.svg +0 -0
  211. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Natal Chart.svg +0 -0
  212. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - SCTWL - Synastry Chart.svg +0 -0
  213. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Topocentric - Natal Chart.svg +0 -0
  214. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Transparent Background - Natal Chart.svg +0 -0
  215. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - True Geocentric - Natal Chart.svg +0 -0
  216. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Wheel External Only - ExternalNatal Chart - Wheel Only.svg +0 -0
  217. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Wheel Only - Natal Chart - Wheel Only.svg +0 -0
  218. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Wheel Synastry Only - Synastry Chart - Wheel Only.svg +0 -0
  219. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon - Wheel Transit Only - Transit Chart - Wheel Only.svg +0 -0
  220. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon DeLuce - Natal Chart.svg +0 -0
  221. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon Fagan-Bradley - Light Theme - Natal Chart - Wheel Only.svg +0 -0
  222. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon Fagan-Bradley - Natal Chart.svg +0 -0
  223. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon J2000 - Natal Chart.svg +0 -0
  224. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon Lahiri - Dark Theme - Natal Chart - Wheel Only.svg +0 -0
  225. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon Lahiri - Natal Chart.svg +0 -0
  226. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon Lunar Return - SingleReturnChart Chart.svg +0 -0
  227. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon Solar Return - Black and White Theme - SingleReturnChart Chart.svg +0 -0
  228. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/John Lennon Solar Return - SingleReturnChart Chart.svg +0 -0
  229. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Kanye - Natal Chart.svg +0 -0
  230. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Mehmet Oz - Natal Chart.svg +0 -0
  231. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Mikhail Bulgakov - Natal Chart.svg +0 -0
  232. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/svg/Sophia Loren - Natal Chart.svg +0 -0
  233. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/test_draw_planets.py +0 -0
  234. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/charts/test_lunar_phase_svg.py +0 -0
  235. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/settings/test_settings.py +0 -0
  236. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_all_active_points.py +0 -0
  237. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_backward_compatibility.py +0 -0
  238. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_backword.py +0 -0
  239. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_chart_data_factory.py +0 -0
  240. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_chart_data_factory_complete.py +0 -0
  241. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_composite_subject_factory_complete.py +0 -0
  242. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_ephemeris_data_factory_complete.py +0 -0
  243. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_planetary_return_factory_complete.py +0 -0
  244. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_relationship_score_factory_complete.py +0 -0
  245. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_report.py +0 -0
  246. {kerykeion-5.1.5 → kerykeion-5.1.7}/tests/test_transits_time_range_factory_complete.py +0 -0
  247. {kerykeion-5.1.5 → kerykeion-5.1.7}/uv.lock +0 -0
  248. {kerykeion-5.1.5 → kerykeion-5.1.7}/workspace/README.md +0 -0
  249. {kerykeion-5.1.5 → kerykeion-5.1.7}/workspace/main.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kerykeion
3
- Version: 5.1.5
3
+ Version: 5.1.7
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
@@ -1781,6 +1781,8 @@ Since the AstrologerAPI is an external third-party service, using it does _not_
1781
1781
 
1782
1782
  Contributions are welcome! Feel free to submit pull requests or report issues.
1783
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
+
1784
1786
  ## Citations
1785
1787
 
1786
1788
  If using Kerykeion in published or academic work, please cite as follows:
@@ -1741,6 +1741,8 @@ Since the AstrologerAPI is an external third-party service, using it does _not_
1741
1741
 
1742
1742
  Contributions are welcome! Feel free to submit pull requests or report issues.
1743
1743
 
1744
+ 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.
1745
+
1744
1746
  ## Citations
1745
1747
 
1746
1748
  If using Kerykeion in published or academic work, please cite as follows:
@@ -59,7 +59,8 @@ from kerykeion.utilities import (
59
59
  check_and_adjust_polar_latitude,
60
60
  calculate_moon_phase,
61
61
  datetime_to_julian,
62
- get_house_number
62
+ get_house_number,
63
+ normalize_zodiac_type,
63
64
  )
64
65
  from kerykeion.settings.config_constants import DEFAULT_ACTIVE_POINTS
65
66
 
@@ -67,7 +68,7 @@ from kerykeion.settings.config_constants import DEFAULT_ACTIVE_POINTS
67
68
  DEFAULT_GEONAMES_USERNAME = "century.boy"
68
69
  DEFAULT_SIDEREAL_MODE: SiderealMode = "FAGAN_BRADLEY"
69
70
  DEFAULT_HOUSES_SYSTEM_IDENTIFIER: HousesSystemIdentifier = "P"
70
- DEFAULT_ZODIAC_TYPE: ZodiacType = "Tropic"
71
+ DEFAULT_ZODIAC_TYPE: ZodiacType = "Tropical"
71
72
  DEFAULT_PERSPECTIVE_TYPE: PerspectiveType = "Apparent Geocentric"
72
73
  DEFAULT_GEONAMES_CACHE_EXPIRE_AFTER_DAYS = 30
73
74
 
@@ -148,8 +149,8 @@ class ChartConfiguration:
148
149
  combinations.
149
150
 
150
151
  Attributes:
151
- zodiac_type (ZodiacType): The zodiac system to use ('Tropic' or 'Sidereal').
152
- Defaults to 'Tropic'.
152
+ zodiac_type (ZodiacType): The zodiac system to use ('Tropical' or 'Sidereal').
153
+ Defaults to 'Tropical'.
153
154
  sidereal_mode (Optional[SiderealMode]): The sidereal calculation mode when using
154
155
  sidereal zodiac. Only required/used when zodiac_type is 'Sidereal'.
155
156
  Defaults to None (auto-set to FAGAN_BRADLEY for sidereal).
@@ -198,14 +199,17 @@ class ChartConfiguration:
198
199
  - Logs informational message when setting default sidereal mode
199
200
  """
200
201
  # Validate zodiac type
201
- if self.zodiac_type not in get_args(ZodiacType):
202
- raise KerykeionException(
203
- f"'{self.zodiac_type}' is not a valid zodiac type! Available types are: {get_args(ZodiacType)}"
204
- )
202
+ try:
203
+ normalized_zodiac_type = normalize_zodiac_type(self.zodiac_type)
204
+ except ValueError as exc:
205
+ raise KerykeionException(str(exc)) from exc
206
+ else:
207
+ if normalized_zodiac_type != self.zodiac_type:
208
+ self.zodiac_type = normalized_zodiac_type
205
209
 
206
210
  # Validate sidereal mode settings
207
- if self.sidereal_mode and self.zodiac_type == "Tropic":
208
- raise KerykeionException("You can't set a sidereal mode with a Tropic zodiac type!")
211
+ if self.sidereal_mode and self.zodiac_type == "Tropical":
212
+ raise KerykeionException("You can't set a sidereal mode with a Tropical zodiac type!")
209
213
 
210
214
  if self.zodiac_type == "Sidereal":
211
215
  if not self.sidereal_mode:
@@ -475,8 +479,8 @@ class AstrologicalSubjectFactory:
475
479
  online location lookup. Get one free at geonames.org.
476
480
  online (bool, optional): Whether to fetch location data online. If False,
477
481
  lng, lat, and tz_str must be provided. Defaults to True.
478
- zodiac_type (ZodiacType, optional): Zodiac system - 'Tropic' or 'Sidereal'.
479
- Defaults to 'Tropic'.
482
+ zodiac_type (ZodiacType, optional): Zodiac system - 'Tropical' or 'Sidereal'.
483
+ Defaults to 'Tropical'.
480
484
  sidereal_mode (SiderealMode, optional): Sidereal calculation mode (e.g.,
481
485
  'FAGAN_BRADLEY', 'LAHIRI'). Only used with zodiac_type='Sidereal'.
482
486
  houses_system_identifier (HousesSystemIdentifier, optional): House system
@@ -726,7 +730,7 @@ class AstrologicalSubjectFactory:
726
730
  or as fallback. Defaults to 51.5074 (Greenwich).
727
731
  geonames_username (str, optional): GeoNames API username. Required when
728
732
  online=True. Defaults to DEFAULT_GEONAMES_USERNAME.
729
- zodiac_type (ZodiacType, optional): Zodiac system. Defaults to 'Tropic'.
733
+ zodiac_type (ZodiacType, optional): Zodiac system. Defaults to 'Tropical'.
730
734
  sidereal_mode (SiderealMode, optional): Sidereal mode when zodiac_type
731
735
  is 'Sidereal'. Defaults to None.
732
736
  houses_system_identifier (HousesSystemIdentifier, optional): House system.
@@ -866,7 +870,7 @@ class AstrologicalSubjectFactory:
866
870
  online (bool, optional): Whether to fetch location data online.
867
871
  Defaults to True.
868
872
  zodiac_type (ZodiacType, optional): Zodiac system to use.
869
- Defaults to 'Tropic'.
873
+ Defaults to 'Tropical'.
870
874
  sidereal_mode (SiderealMode, optional): Sidereal calculation mode.
871
875
  Only used when zodiac_type is 'Sidereal'. Defaults to None.
872
876
  houses_system_identifier (HousesSystemIdentifier, optional): House
@@ -36,6 +36,7 @@ from .chart_data_factory import ChartDataFactory
36
36
  from .charts.chart_drawer import ChartDrawer
37
37
  from .aspects import AspectsFactory
38
38
  from .settings.config_constants import DEFAULT_ACTIVE_POINTS, DEFAULT_ACTIVE_ASPECTS
39
+ from .utilities import normalize_zodiac_type
39
40
  from .schemas.kr_models import (
40
41
  AstrologicalSubjectModel,
41
42
  CompositeSubjectModel,
@@ -74,6 +75,42 @@ LEGACY_NODE_NAMES_MAP = {
74
75
  }
75
76
 
76
77
 
78
+ def _normalize_zodiac_type_with_warning(zodiac_type: Optional[Union[str, ZodiacType]]) -> Optional[ZodiacType]:
79
+ """Normalize legacy zodiac type values with deprecation warning.
80
+
81
+ Wraps the utilities.normalize_zodiac_type function and adds a deprecation
82
+ warning for legacy formats like "tropic" or case-insensitive variants.
83
+
84
+ Args:
85
+ zodiac_type: Input zodiac type (may be legacy format)
86
+
87
+ Returns:
88
+ Normalized ZodiacType or None if input was None
89
+ """
90
+ if zodiac_type is None:
91
+ return None
92
+
93
+ zodiac_str = str(zodiac_type)
94
+
95
+ # Check if this is a legacy format (case-insensitive "tropic" or non-canonical case)
96
+ zodiac_lower = zodiac_str.lower()
97
+ if zodiac_lower in ("tropic", "tropical", "sidereal") and zodiac_str not in ("Tropical", "Sidereal"):
98
+ # Normalize using the utilities function
99
+ normalized = normalize_zodiac_type(zodiac_str)
100
+
101
+ # Emit deprecation warning for legacy usage
102
+ warnings.warn(
103
+ f"Zodiac type '{zodiac_str}' is deprecated in Kerykeion v5. "
104
+ f"Use '{normalized}' instead.",
105
+ DeprecationWarning,
106
+ stacklevel=4,
107
+ )
108
+ return normalized
109
+
110
+ # Already in correct format or will be normalized by utilities function
111
+ return cast(ZodiacType, normalize_zodiac_type(zodiac_str))
112
+
113
+
77
114
  def _normalize_active_points(points: Optional[Iterable[Union[str, AstrologicalPoint]]]) -> Optional[List[AstrologicalPoint]]:
78
115
  """Best-effort normalization of legacy string active points list.
79
116
 
@@ -159,7 +196,10 @@ class AstrologicalSubject:
159
196
  stacklevel=2,
160
197
  )
161
198
 
199
+ # Normalize legacy zodiac type values
200
+ zodiac_type = _normalize_zodiac_type_with_warning(zodiac_type)
162
201
  zodiac_type = DEFAULT_ZODIAC_TYPE if zodiac_type is None else zodiac_type
202
+
163
203
  houses_system_identifier = (
164
204
  DEFAULT_HOUSES_SYSTEM_IDENTIFIER if houses_system_identifier is None else houses_system_identifier
165
205
  )
@@ -352,6 +392,9 @@ class AstrologicalSubject:
352
392
  if online and resolved_geonames == DEFAULT_GEONAMES_USERNAME:
353
393
  warnings.warn(GEONAMES_DEFAULT_USERNAME_WARNING, UserWarning, stacklevel=2)
354
394
 
395
+ # Normalize legacy zodiac type values
396
+ normalized_zodiac_type = _normalize_zodiac_type_with_warning(zodiac_type)
397
+
355
398
  model = AstrologicalSubjectFactory.from_iso_utc_time(
356
399
  name=name,
357
400
  iso_utc_time=iso_utc_time,
@@ -362,7 +405,7 @@ class AstrologicalSubject:
362
405
  lng=float(lng),
363
406
  lat=float(lat),
364
407
  geonames_username=resolved_geonames,
365
- zodiac_type=(zodiac_type or DEFAULT_ZODIAC_TYPE), # type: ignore[arg-type]
408
+ zodiac_type=(normalized_zodiac_type or DEFAULT_ZODIAC_TYPE), # type: ignore[arg-type]
366
409
  sidereal_mode=sidereal_mode,
367
410
  houses_system_identifier=(houses_system_identifier or DEFAULT_HOUSES_SYSTEM_IDENTIFIER), # type: ignore[arg-type]
368
411
  perspective_type=(perspective_type or DEFAULT_PERSPECTIVE_TYPE), # type: ignore[arg-type]
@@ -78,6 +78,9 @@ from kerykeion.settings.chart_defaults import (
78
78
  from typing import List, Literal
79
79
 
80
80
 
81
+ logger = logging.getLogger(__name__)
82
+
83
+
81
84
  class ChartDrawer:
82
85
  """
83
86
  ChartDrawer generates astrological chart visualizations as SVG files from pre-computed chart data.
@@ -315,7 +318,7 @@ class ChartDrawer:
315
318
 
316
319
  active_points_count = len(self.available_planets_setting)
317
320
  if active_points_count > 24:
318
- logging.warning(
321
+ logger.warning(
319
322
  "ChartDrawer detected %s active celestial points; rendering may look crowded beyond 24.",
320
323
  active_points_count,
321
324
  )
@@ -856,7 +859,7 @@ class ChartDrawer:
856
859
  try:
857
860
  required_width = self._estimate_required_width_full()
858
861
  except Exception as e:
859
- logging.debug(f"Auto-size width calculation failed: {e}")
862
+ logger.debug("Auto-size width calculation failed: %s", e)
860
863
  return
861
864
 
862
865
  minimum_width = self._minimum_width_for_chart_type()
@@ -1271,7 +1274,7 @@ class ChartDrawer:
1271
1274
  template_dict["top_left_5"] = f"{self._translate('day_of_week', 'Day of Week')}: {localized_weekday}" # type: ignore
1272
1275
 
1273
1276
  # Bottom left section
1274
- if self.first_obj.zodiac_type == "Tropic":
1277
+ if self.first_obj.zodiac_type == "Tropical":
1275
1278
  zodiac_info = f"{self._translate('zodiac', 'Zodiac')}: {self._translate('tropical', 'Tropical')}"
1276
1279
  else:
1277
1280
  mode_const = "SIDM_" + self.first_obj.sidereal_mode # type: ignore
@@ -1433,7 +1436,7 @@ class ChartDrawer:
1433
1436
  template_dict["top_left_5"] = f"{latitude_string} / {longitude_string}"
1434
1437
 
1435
1438
  # Bottom left section
1436
- if self.first_obj.zodiac_type == "Tropic":
1439
+ if self.first_obj.zodiac_type == "Tropical":
1437
1440
  zodiac_info = f"{self._translate('zodiac', 'Zodiac')}: {self._translate('tropical', 'Tropical')}"
1438
1441
  else:
1439
1442
  mode_const = "SIDM_" + self.first_obj.sidereal_mode # type: ignore
@@ -1589,7 +1592,7 @@ class ChartDrawer:
1589
1592
  template_dict["top_left_5"] = ""#f"{self._translate('type', 'Type')}: {self._translate(self.chart_type, self.chart_type)}"
1590
1593
 
1591
1594
  # Bottom left section
1592
- if self.first_obj.zodiac_type == "Tropic":
1595
+ if self.first_obj.zodiac_type == "Tropical":
1593
1596
  zodiac_info = f"{self._translate('zodiac', 'Zodiac')}: {self._translate('tropical', 'Tropical')}"
1594
1597
  else:
1595
1598
  mode_const = "SIDM_" + self.first_obj.sidereal_mode # type: ignore
@@ -1609,9 +1612,9 @@ class ChartDrawer:
1609
1612
 
1610
1613
  template_dict["bottom_left_4"] = f'{self._translate("perspective_type", "Perspective")}: {self._translate(self.second_obj.perspective_type.lower().replace(" ", "_"), self.second_obj.perspective_type)}' # type: ignore
1611
1614
 
1612
- # Moon phase section calculations - use first_obj for visualization
1613
- if self.first_obj.lunar_phase is not None:
1614
- template_dict["makeLunarPhase"] = makeLunarPhase(self.first_obj.lunar_phase["degrees_between_s_m"], self.geolat)
1615
+ # Moon phase section calculations - use transit subject data only
1616
+ if self.second_obj is not None and getattr(self.second_obj, "lunar_phase", None):
1617
+ template_dict["makeLunarPhase"] = makeLunarPhase(self.second_obj.lunar_phase["degrees_between_s_m"], self.geolat)
1615
1618
  else:
1616
1619
  template_dict["makeLunarPhase"] = ""
1617
1620
 
@@ -1767,7 +1770,7 @@ class ChartDrawer:
1767
1770
  template_dict["top_left_5"] = format_datetime_with_timezone(self.second_obj.iso_formatted_local_datetime) # type: ignore
1768
1771
 
1769
1772
  # Bottom left section
1770
- if self.first_obj.zodiac_type == "Tropic":
1773
+ if self.first_obj.zodiac_type == "Tropical":
1771
1774
  zodiac_info = f"{self._translate('zodiac', 'Zodiac')}: {self._translate('tropical', 'Tropical')}"
1772
1775
  else:
1773
1776
  mode_const = "SIDM_" + self.first_obj.sidereal_mode # type: ignore
@@ -1967,7 +1970,7 @@ class ChartDrawer:
1967
1970
  template_dict["top_left_5"] = f"{latitude_string} / {longitude_string}"
1968
1971
 
1969
1972
  # Bottom left section
1970
- if self.first_obj.zodiac_type == "Tropic":
1973
+ if self.first_obj.zodiac_type == "Tropical":
1971
1974
  zodiac_info = f"{self._translate('zodiac', 'Zodiac')}: {self._translate('tropical', 'Tropical')}"
1972
1975
  else:
1973
1976
  mode_const = "SIDM_" + self.first_obj.sidereal_mode # type: ignore
@@ -2140,7 +2143,7 @@ class ChartDrawer:
2140
2143
  template_dict["top_left_5"] = f"{self._translate('type', 'Type')}: {self._translate('lunar_return', 'Lunar Return')}"
2141
2144
 
2142
2145
  # Bottom left section
2143
- if self.first_obj.zodiac_type == "Tropic":
2146
+ if self.first_obj.zodiac_type == "Tropical":
2144
2147
  zodiac_info = f"{self._translate('zodiac', 'Zodiac')}: {self._translate('tropical', 'Tropical')}"
2145
2148
  else:
2146
2149
  mode_const = "SIDM_" + self.first_obj.sidereal_mode # type: ignore
@@ -2237,7 +2240,7 @@ class ChartDrawer:
2237
2240
 
2238
2241
  # return filename
2239
2242
 
2240
- logging.debug(f"Template dictionary has {len(td.model_dump())} fields")
2243
+ logger.debug("Template dictionary includes %s fields", len(td.model_dump()))
2241
2244
 
2242
2245
  self._create_template_dictionary()
2243
2246
 
@@ -48,10 +48,19 @@ License: AGPL-3.0
48
48
 
49
49
  from kerykeion import AstrologicalSubjectFactory
50
50
  from kerykeion.schemas.kr_models import AstrologicalSubjectModel
51
- from kerykeion.utilities import get_houses_list, get_available_astrological_points_list
51
+ from kerykeion.utilities import (
52
+ get_houses_list,
53
+ get_available_astrological_points_list,
54
+ normalize_zodiac_type,
55
+ )
52
56
  from kerykeion.astrological_subject_factory import DEFAULT_HOUSES_SYSTEM_IDENTIFIER, DEFAULT_PERSPECTIVE_TYPE, DEFAULT_ZODIAC_TYPE
53
- from kerykeion.schemas import EphemerisDictModel
54
- from kerykeion.schemas import SiderealMode, HousesSystemIdentifier, PerspectiveType, ZodiacType
57
+ from kerykeion.schemas import (
58
+ EphemerisDictModel,
59
+ SiderealMode,
60
+ HousesSystemIdentifier,
61
+ PerspectiveType,
62
+ ZodiacType,
63
+ )
55
64
  from datetime import datetime, timedelta
56
65
  from typing import Literal, Union, List
57
66
  import logging
@@ -161,7 +170,7 @@ class EphemerisDataFactory:
161
170
  self.lng = lng
162
171
  self.tz_str = tz_str
163
172
  self.is_dst = is_dst
164
- self.zodiac_type = zodiac_type
173
+ self.zodiac_type = normalize_zodiac_type(zodiac_type)
165
174
  self.sidereal_mode = sidereal_mode
166
175
  self.houses_system_identifier = houses_system_identifier
167
176
  self.perspective_type = perspective_type
@@ -6,13 +6,16 @@ License: AGPL-3.0
6
6
  """
7
7
 
8
8
 
9
- import logging
9
+ from logging import getLogger
10
10
  from datetime import timedelta
11
11
  from requests import Request
12
12
  from requests_cache import CachedSession
13
13
  from typing import Union
14
14
 
15
15
 
16
+ logger = getLogger(__name__)
17
+
18
+
16
19
  class FetchGeonames:
17
20
  """
18
21
  Class to handle requests to the GeoNames API for location data and timezone information.
@@ -63,21 +66,21 @@ class FetchGeonames:
63
66
  params = {"lat": lat, "lng": lon, "username": self.username}
64
67
 
65
68
  prepared_request = Request("GET", self.timezone_url, params=params).prepare()
66
- logging.debug(f"Requesting data from GeoName timezones: {prepared_request.url}")
69
+ logger.debug("GeoNames timezone lookup url=%s", prepared_request.url)
67
70
 
68
71
  try:
69
72
  response = self.session.send(prepared_request)
70
73
  response_json = response.json()
71
74
 
72
75
  except Exception as e:
73
- logging.error(f"Error fetching {self.timezone_url}: {e}")
76
+ logger.error("GeoNames timezone request failed for %s: %s", self.timezone_url, e)
74
77
  return {}
75
78
 
76
79
  try:
77
80
  timezone_data["timezonestr"] = response_json["timezoneId"]
78
81
 
79
82
  except Exception as e:
80
- logging.error(f"Error serializing data maybe wrong username? Details: {e}")
83
+ logger.error("GeoNames timezone payload missing expected keys: %s", e)
81
84
  return {}
82
85
 
83
86
  if hasattr(response, "from_cache"):
@@ -109,15 +112,16 @@ class FetchGeonames:
109
112
  }
110
113
 
111
114
  prepared_request = Request("GET", self.base_url, params=params).prepare()
112
- logging.debug(f"Requesting data from geonames basic: {prepared_request.url}")
115
+ logger.debug("GeoNames search url=%s", prepared_request.url)
113
116
 
114
117
  try:
115
118
  response = self.session.send(prepared_request)
119
+ response.raise_for_status()
116
120
  response_json = response.json()
117
- logging.debug(f"Response from GeoNames: {response_json}")
121
+ logger.debug("GeoNames search response: %s", response_json)
118
122
 
119
123
  except Exception as e:
120
- logging.error(f"Error in fetching {self.base_url}: {e}")
124
+ logger.error("GeoNames search request failed for %s: %s", self.base_url, e)
121
125
  return {}
122
126
 
123
127
  try:
@@ -127,7 +131,7 @@ class FetchGeonames:
127
131
  city_data_whitout_tz["countryCode"] = response_json["geonames"][0]["countryCode"]
128
132
 
129
133
  except Exception as e:
130
- logging.error(f"Error serializing data maybe wrong username? Details: {e}")
134
+ logger.error("GeoNames search payload missing expected keys: %s", e)
131
135
  return {}
132
136
 
133
137
  if hasattr(response, "from_cache"):
@@ -147,15 +151,16 @@ class FetchGeonames:
147
151
  timezone_response = self.__get_timezone(city_data_response["lat"], city_data_response["lng"])
148
152
 
149
153
  except Exception as e:
150
- logging.error(f"Error in fetching timezone: {e}")
154
+ logger.error("Unable to fetch timezone details: %s", e)
151
155
  return {}
152
156
 
153
157
  return {**timezone_response, **city_data_response}
154
158
 
155
159
 
156
160
  if __name__ == "__main__":
157
- from kerykeion.utilities import setup_logging
158
- setup_logging(level="debug")
161
+ """Run a tiny demonstration when executing the module directly."""
162
+ from kerykeion.utilities import setup_logging as configure_logging
159
163
 
164
+ configure_logging("debug")
160
165
  geonames = FetchGeonames("Montichiari", "IT")
161
166
  print(geonames.get_serialized_data())
@@ -727,8 +727,7 @@ if __name__ == "__main__":
727
727
  natal_subject.iso_formatted_local_datetime,
728
728
  "Solar",
729
729
  )
730
-
731
- # Composite chart subject
730
+ # Derive a composite subject representing the pair's midpoint configuration
732
731
  composite_subject = CompositeSubjectFactory(
733
732
  natal_subject,
734
733
  partner_subject,
@@ -5,7 +5,7 @@ This is part of Kerykeion (C) 2025 Giacomo Battaglia
5
5
  from typing import Literal
6
6
 
7
7
 
8
- ZodiacType = Literal["Tropic", "Sidereal"]
8
+ ZodiacType = Literal["Tropical", "Sidereal"]
9
9
  """Literal type for Zodiac Types"""
10
10
 
11
11
 
@@ -47,5 +47,5 @@ def _deep_merge(base: Mapping[str, Any], overrides: Mapping[str, Any]) -> dict[s
47
47
  merged[key] = deepcopy(value)
48
48
  return merged
49
49
 
50
-
50
+ # Keep the public surface area explicit for downstream imports.
51
51
  __all__ = ["SettingsSource", "load_settings_mapping", "LANGUAGE_SETTINGS"]