kerykeion 3.1.1__py3-none-any.whl → 5.1.9__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 (75) hide show
  1. kerykeion/__init__.py +58 -141
  2. kerykeion/aspects/__init__.py +14 -0
  3. kerykeion/aspects/aspects_factory.py +568 -0
  4. kerykeion/aspects/aspects_utils.py +164 -0
  5. kerykeion/astrological_subject_factory.py +1901 -0
  6. kerykeion/backword.py +820 -0
  7. kerykeion/chart_data_factory.py +552 -0
  8. kerykeion/charts/__init__.py +5 -0
  9. kerykeion/charts/chart_drawer.py +2794 -0
  10. kerykeion/charts/charts_utils.py +1840 -0
  11. kerykeion/charts/draw_planets.py +658 -0
  12. kerykeion/charts/templates/aspect_grid_only.xml +596 -0
  13. kerykeion/charts/templates/chart.xml +741 -0
  14. kerykeion/charts/templates/wheel_only.xml +653 -0
  15. kerykeion/charts/themes/black-and-white.css +148 -0
  16. kerykeion/charts/themes/classic.css +113 -0
  17. kerykeion/charts/themes/dark-high-contrast.css +159 -0
  18. kerykeion/charts/themes/dark.css +160 -0
  19. kerykeion/charts/themes/light.css +160 -0
  20. kerykeion/charts/themes/strawberry.css +158 -0
  21. kerykeion/composite_subject_factory.py +408 -0
  22. kerykeion/ephemeris_data_factory.py +443 -0
  23. kerykeion/fetch_geonames.py +105 -61
  24. kerykeion/house_comparison/__init__.py +6 -0
  25. kerykeion/house_comparison/house_comparison_factory.py +103 -0
  26. kerykeion/house_comparison/house_comparison_utils.py +126 -0
  27. kerykeion/kr_types/__init__.py +70 -0
  28. kerykeion/kr_types/chart_template_model.py +20 -0
  29. kerykeion/kr_types/kerykeion_exception.py +20 -0
  30. kerykeion/kr_types/kr_literals.py +20 -0
  31. kerykeion/kr_types/kr_models.py +20 -0
  32. kerykeion/kr_types/settings_models.py +20 -0
  33. kerykeion/planetary_return_factory.py +805 -0
  34. kerykeion/relationship_score_factory.py +301 -0
  35. kerykeion/report.py +779 -0
  36. kerykeion/schemas/__init__.py +106 -0
  37. kerykeion/schemas/chart_template_model.py +367 -0
  38. kerykeion/schemas/kerykeion_exception.py +20 -0
  39. kerykeion/schemas/kr_literals.py +181 -0
  40. kerykeion/schemas/kr_models.py +603 -0
  41. kerykeion/schemas/settings_models.py +188 -0
  42. kerykeion/settings/__init__.py +20 -0
  43. kerykeion/settings/chart_defaults.py +444 -0
  44. kerykeion/settings/config_constants.py +152 -0
  45. kerykeion/settings/kerykeion_settings.py +51 -0
  46. kerykeion/settings/translation_strings.py +1499 -0
  47. kerykeion/settings/translations.py +74 -0
  48. kerykeion/sweph/README.md +3 -0
  49. kerykeion/sweph/ast136/s136108s.se1 +0 -0
  50. kerykeion/sweph/ast136/s136199s.se1 +0 -0
  51. kerykeion/sweph/ast136/s136472s.se1 +0 -0
  52. kerykeion/sweph/ast28/se28978s.se1 +0 -0
  53. kerykeion/sweph/ast50/se50000s.se1 +0 -0
  54. kerykeion/sweph/ast90/se90377s.se1 +0 -0
  55. kerykeion/sweph/ast90/se90482s.se1 +0 -0
  56. kerykeion/sweph/seas_18.se1 +0 -0
  57. kerykeion/sweph/sefstars.txt +1602 -0
  58. kerykeion/transits_time_range_factory.py +302 -0
  59. kerykeion/utilities.py +762 -130
  60. kerykeion-5.1.9.dist-info/METADATA +1793 -0
  61. kerykeion-5.1.9.dist-info/RECORD +63 -0
  62. {kerykeion-3.1.1.dist-info → kerykeion-5.1.9.dist-info}/WHEEL +1 -2
  63. kerykeion-5.1.9.dist-info/licenses/LICENSE +661 -0
  64. kerykeion/aspects.py +0 -331
  65. kerykeion/charts/charts_svg.py +0 -1607
  66. kerykeion/charts/templates/basic.xml +0 -285
  67. kerykeion/charts/templates/extended.xml +0 -294
  68. kerykeion/kr.config.json +0 -464
  69. kerykeion/main.py +0 -595
  70. kerykeion/print_all_data.py +0 -44
  71. kerykeion/relationship_score.py +0 -219
  72. kerykeion/types.py +0 -190
  73. kerykeion-3.1.1.dist-info/METADATA +0 -204
  74. kerykeion-3.1.1.dist-info/RECORD +0 -17
  75. kerykeion-3.1.1.dist-info/top_level.txt +0 -1
@@ -0,0 +1,164 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ This is part of Kerykeion (C) 2025 Giacomo Battaglia
4
+ """
5
+ # TODO: Better documentation and unit tests
6
+
7
+ from swisseph import difdeg2n
8
+ from typing import Union
9
+ from kerykeion.schemas.kr_models import AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel
10
+ from kerykeion.schemas.kr_literals import AspectMovementType
11
+ from kerykeion.schemas.settings_models import KerykeionSettingsCelestialPointModel
12
+ from kerykeion.settings.chart_defaults import DEFAULT_CELESTIAL_POINTS_SETTINGS
13
+
14
+
15
+ def get_aspect_from_two_points(
16
+ aspects_settings: Union[list[dict], list[dict]],
17
+ point_one: Union[float, int],
18
+ point_two: Union[float, int],
19
+ ):
20
+ """
21
+ Utility function to calculate the aspects between two points.
22
+
23
+ Args:
24
+ aspects_settings (dict): Dictionary containing aspect settings.
25
+ point_one (Union[float, int]): First point.
26
+ point_two (Union[float, int]): Second point.
27
+
28
+ Returns:
29
+ dict: Dictionary containing the aspect details.
30
+ """
31
+ distance = abs(difdeg2n(point_one, point_two))
32
+ diff = abs(point_one - point_two)
33
+
34
+ for aid, aspect in enumerate(aspects_settings):
35
+ # TODO: Remove the "degree" element EVERYWHERE!
36
+ aspect_degree = aspect["degree"] # type: ignore
37
+ aspect_orb = aspect["orb"] # type: ignore
38
+
39
+ if (aspect_degree - aspect_orb) <= int(distance) <= (aspect_degree + aspect_orb):
40
+ name = aspect["name"] # type: ignore
41
+ aspect_degrees = aspect_degree
42
+ verdict = True
43
+ break
44
+ else:
45
+ verdict = False
46
+ name = None
47
+ aspect_degrees = 0
48
+
49
+ return {
50
+ "verdict": verdict,
51
+ "name": name,
52
+ "orbit": abs(distance - aspect_degrees),
53
+ "distance": abs(distance - aspect_degrees),
54
+ "aspect_degrees": aspect_degrees,
55
+ "diff": diff,
56
+ }
57
+
58
+
59
+ def calculate_aspect_movement(
60
+ point_one_abs_pos: float,
61
+ point_two_abs_pos: float,
62
+ aspect_degrees: int,
63
+ exact_orb_threshold: float = 0.05
64
+ ) -> AspectMovementType:
65
+ """
66
+ Calculate whether an aspect is applying, separating, or exact.
67
+
68
+ An aspect is:
69
+ - "Exact": When the orb is very tight (default < 0.17°)
70
+ - "Applying": When the faster planet is moving toward the exact aspect
71
+ - "Separating": When the faster planet is moving away from the exact aspect
72
+
73
+ For simplicity, we assume the first planet (p1) is faster than the second (p2).
74
+ This is generally true for:
75
+ - Moon vs outer planets
76
+ - Inner planets vs outer planets
77
+ - Transits (transiting planet vs natal planet)
78
+
79
+ Args:
80
+ point_one_abs_pos: Absolute position of first point (0-360°)
81
+ point_two_abs_pos: Absolute position of second point (0-360°)
82
+ aspect_degrees: The exact degree of the aspect (0, 60, 90, 120, 180, etc.)
83
+ exact_orb_threshold: Maximum orb to consider aspect "exact" (default 0.17°)
84
+
85
+ Returns:
86
+ "Applying", "Separating", or "Exact"
87
+
88
+ Example:
89
+ >>> # Moon at 45° applying to Sun at 50° (conjunction at 0°/360°)
90
+ >>> calculate_aspect_movement(45, 50, 0)
91
+ 'Applying'
92
+ >>> # Moon at 55° separating from Sun at 50° (conjunction)
93
+ >>> calculate_aspect_movement(55, 50, 0)
94
+ 'Separating'
95
+ """
96
+
97
+ # Calculate the angular distance
98
+ distance = abs(difdeg2n(point_one_abs_pos, point_two_abs_pos))
99
+ orbit = abs(distance - aspect_degrees)
100
+
101
+ # Check if aspect is exact (within tight orb)
102
+ if orbit <= exact_orb_threshold:
103
+ return "Exact"
104
+
105
+ # Calculate if p1 is ahead or behind p2 relative to the aspect
106
+ # We need to determine the direction of movement
107
+ diff = difdeg2n(point_one_abs_pos, point_two_abs_pos)
108
+
109
+ # For conjunction (0°) or opposition (180°)
110
+ if aspect_degrees == 0 or aspect_degrees == 360:
111
+ # If p1 is behind p2 (negative diff), it's applying
112
+ # If p1 is ahead of p2 (positive diff), it's separating
113
+ return "Applying" if diff < 0 else "Separating"
114
+
115
+ elif aspect_degrees == 180:
116
+ # For opposition, the logic is reversed
117
+ return "Applying" if abs(diff) < 180 else "Separating"
118
+
119
+ else:
120
+ # For other aspects (60°, 90°, 120°, 150°)
121
+ # Check if the distance is increasing or decreasing
122
+ # If distance < aspect_degrees and diff < 0: applying
123
+ # If distance > aspect_degrees or diff > 0: separating
124
+ if abs(diff) < aspect_degrees:
125
+ return "Applying" if diff < 0 else "Separating"
126
+ else:
127
+ return "Separating" if diff > 0 else "Applying"
128
+
129
+
130
+ def planet_id_decoder(planets_settings: list[KerykeionSettingsCelestialPointModel], name: str) -> int:
131
+ """
132
+ Check if the name of the planet is the same in the settings and return
133
+ the correct id for the planet.
134
+ """
135
+ str_name = str(name)
136
+ for planet in planets_settings:
137
+ if planet["name"] == str_name:
138
+ result = planet["id"]
139
+ return result
140
+
141
+ raise ValueError(f"Planet {name} not found in the settings")
142
+
143
+
144
+ def get_active_points_list(
145
+ subject: Union[AstrologicalSubjectModel, CompositeSubjectModel, PlanetReturnModel],
146
+ active_points: list = [],
147
+ *,
148
+ celestial_points: list[dict] = DEFAULT_CELESTIAL_POINTS_SETTINGS,
149
+ ) -> list:
150
+ """
151
+ Given an astrological subject and the settings, return a list of the active points.
152
+ Args:
153
+ subject (AstrologicalSubject): The astrological subject to get the active points from.
154
+ settings (Union[KerykeionSettingsModel, dict]): Settings model o dictionary.
155
+
156
+ Returns:
157
+ list: List of the active points.
158
+ """
159
+ point_list = []
160
+ for planet in celestial_points:
161
+ if planet["name"] in active_points:
162
+ point_list.append(subject[planet["name"].lower()])
163
+
164
+ return point_list