kerykeion 4.12.3__py3-none-any.whl → 4.14.2__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.

@@ -3,17 +3,18 @@
3
3
  <svg
4
4
  xmlns="http://www.w3.org/2000/svg"
5
5
  xmlns:xlink="http://www.w3.org/1999/xlink"
6
- width="$svgWidth"
7
- height="$svgHeight"
6
+ xmlns:kr="https://www.kerykeion.net/"
7
+ width="100%"
8
+ height="100%"
8
9
  viewBox="$viewbox"
9
10
  preserveAspectRatio="xMidYMid"
10
11
  >
11
12
  <title>$stringTitle | Kerykeion</title>
12
13
  <!--- Main Chart -->
13
- <g transform="rotate($cfgRotate)">
14
- <g transform="scale($cfgZoom)">
15
- <rect class="background-rectangle" x="0" y="0" width="$chart_width"
16
- height="$chart_height" style="fill: $paper_color_1" />
14
+ <g kr:node="Main_Chart" transform="rotate($cfgRotate)">
15
+
16
+ <g kr:node="Main_Text">
17
+ <rect class="background-rectangle" x="0" y="0" width="$chart_width" height="$chart_height" style="fill: $paper_color_1" />
17
18
  <text x="20" y="22" style="fill: $paper_color_0; font-size: 24px">$stringTitle</text>
18
19
  <text x="20" y="50" style="fill: $paper_color_0; font-size: 11px">$stringName</text>
19
20
  <text x="20" y="62" style="fill: $paper_color_0; font-size: 11px">$stringLocation</text>
@@ -26,77 +27,80 @@
26
27
  <text x="20" y="480" style="fill: $paper_color_0; font-size: 10px">$bottomLeft2</text>
27
28
  <text x="20" y="494" style="fill: $paper_color_0; font-size: 10px">$bottomLeft3</text>
28
29
  <text x="20" y="508" style="fill: $paper_color_0; font-size: 10px">$bottomLeft4</text>
29
- <!-- Lunar Phase -->
30
- <g transform="translate(20,518)">
31
- <g transform="rotate($lunar_phase_rotate 20 10)">
32
- <defs>
33
- <clipPath id="cut-off-circle">
34
- <circle cx="20" cy="10" r="10" />
35
- </clipPath>
36
- </defs>
37
- <circle cx="20" cy="10" r="10" style="fill: $lunar_phase_bg" />
38
- <circle
39
- cx="$lunar_phase_cx"
40
- cy="10"
41
- r="$lunar_phase_r"
42
- style="fill: $lunar_phase_fg"
43
- clip-path="url(#cut-off-circle)"
44
- />
45
- <circle
46
- cx="20"
47
- cy="10"
48
- r="10"
49
- style="fill: none; stroke: $lunar_phase_outline; stroke-width: 0.5px; stroke-opacity: 0.5"
50
- />
51
- </g>
52
- </g>
53
- <g transform="translate(50,50)">
54
- <g transform="translate($circleX,$circleY)">
55
- <!-- Zodiac -->
56
- $makeZodiac
30
+ </g>
57
31
 
58
- <!-- First Circle -->
59
- $first_circle
32
+ <!-- Lunar Phase -->
33
+ <g kr:node="Lunar_Phase" transform="translate(20,518)">
34
+ $moon_phase
35
+ </g>
60
36
 
61
- <!-- Second Circle -->
62
- $second_circle
37
+ <g kr:node="Main_Content" transform="translate(50,50)">
38
+ <!-- Zodiac -->
39
+ <g kr:node="Zodiac">
40
+ $makeZodiac
41
+ </g>
63
42
 
64
- <!-- Third Circle -->
65
- <circle $c3 style="$c3style" />
43
+ <!-- First Circle -->
44
+ <g kr:node="First_Circle">
45
+ $first_circle
46
+ </g>
66
47
 
67
- <!-- TransitRing -->
68
- $transitRing
48
+ <!-- Second Circle -->
49
+ <g kr:node="Second_Circle">
50
+ $second_circle
51
+ </g>
69
52
 
70
- <!-- Degree Ring -->
71
- $degreeRing
53
+ <!-- Third Circle -->
54
+ <g kr:node="Third_Circle">
55
+ $third_circle
56
+ </g>
72
57
 
73
- <!-- Houses -->
74
- $makeHouses
58
+ <!-- Transit_Ring -->
59
+ <g kr:node="Transint_Ring">
60
+ $transitRing
61
+ </g>
75
62
 
76
- <!-- Planets -->
77
- $makePlanets
63
+ <!-- Degree Ring -->
64
+ <g kr:node="Degree_Ring">
65
+ $degreeRing
66
+ </g>
78
67
 
79
- <!-- Aspects -->
80
- $makeAspects
81
- </g>
68
+ <!-- Houses -->
69
+ <g kr:node="Houses_Wheel">
70
+ $makeHouses
71
+ </g>
72
+
73
+ <!-- Planets -->
74
+ <g kr:node="Planets_Wheel">
75
+ $makePlanets
76
+ </g>
82
77
 
83
- <!-- makePatterns -->
84
- $makePatterns
78
+ <!-- Aspects -->
79
+ <g kr:node="Aspects_Wheel">
80
+ $makeAspects
81
+ </g>
85
82
 
86
- <!-- AspectGrid -->
83
+ <!-- AspectGrid -->
84
+ <g kr:node="Aspect_Grid">
87
85
  $makeAspectGrid
86
+ </g>
88
87
 
89
- <!-- Elements -->
88
+ <!-- Elements -->
89
+ <g kr:node="Elements_Percentages">
90
90
  $elements_percentages
91
+ </g>
91
92
 
92
- <!-- Planet Grid -->
93
+ <!-- Planet Grid -->
94
+ <g kr:node="Planet_Grid">
93
95
  $makePlanetGrid
96
+ </g>
94
97
 
95
- <!-- Houses Grid -->
98
+ <!-- Houses Grid -->
99
+ <g kr:node="Houses_Grid">
96
100
  $makeHousesGrid
97
-
98
101
  </g>
99
102
  </g>
103
+
100
104
  </g>
101
105
 
102
106
  <!-- Symbols Definitions -->
@@ -228,6 +232,13 @@
228
232
  d="M 10.019873,13.068981 L 10.185542,0.80951431 M 10.195591,6.7442901 L 15.496983,2.2712408 M 10.214831,6.6321726 L 15.516217,11.105216 M 17.192934,17.998774 C 17.192934,20.8646 14.867052,23.190487 12.001226,23.190487 C 9.1353988,23.190487 6.8095128,20.8646 6.8095128,17.998774 C 6.8095128,15.132953 9.1353988,12.807066 12.001226,12.807066 C 14.867052,12.807066 17.192934,15.132953 17.192934,17.998774 z "
229
233
  style="stroke: $planets_color_16;stroke-width:2px; fill:none;" />
230
234
  </symbol>
235
+ <symbol id="Mean_Lilith">
236
+ <g transform="translate(1,2)">
237
+ <path
238
+ d="M 5.2255055,0.5001842 C 4.5318761,0.5265765 3.8737679,0.6459111 3.2335607,0.83217502 C 6.682099,1.8494555 9.2093951,5.0469634 9.2093951,8.8236674 C 9.2093953,12.600373 6.682099,15.797873 3.2335607,16.815161 C 3.9722573,17.030079 4.7497456,17.147152 5.5574963,17.147152 C 6.4110015,17.147152 7.2245796,17.006704 8,16.767734 L 8,19.803079 L 4.490383,19.803079 L 4.490383,21.629028 L 8,21.629028 L 8,23.739541 L 9.7785222,23.739541 L 9.7785222,21.629028 L 13.430421,21.629028 L 13.430421,19.803079 L 9.7785222,19.803079 L 9.7785222,15.985184 C 12.226487,14.535184 13.88098,11.873186 13.88098,8.8236674 C 13.88098,4.2284374 10.152727,0.5001842 5.5574963,0.5001842 C 5.4497948,0.5001842 5.3322206,0.4961168 5.2255055,0.5001842 z"
239
+ style="fill: $planets_color_16;" />
240
+ </g>
241
+ </symbol>
231
242
  <symbol id="First_House">
232
243
  <text y="20" style="font-size: 22px; fill: $planets_color_12">As</text>
233
244
  </symbol>
@@ -518,5 +529,12 @@
518
529
  style="fill: $paper_color_0"
519
530
  />
520
531
  </symbol>
532
+
533
+ <!-- Moon Phases Cut Off Circle -->
534
+ <defs>
535
+ <clipPath id="moonPhaseCutOffCircle">
536
+ <circle cx="20" cy="10" r="10" />
537
+ </clipPath>
538
+ </defs>
521
539
  </defs>
522
540
  </svg>
kerykeion/enums.py CHANGED
@@ -15,6 +15,7 @@ class Planets(Enum):
15
15
  CHIRON = "Chiron"
16
16
  TRUE_NODE = "True_Node"
17
17
  MEAN_NODE = "Mean_Node"
18
+ MEAN_LILITH = "Mean_Lilith"
18
19
 
19
20
 
20
21
  class Aspects(Enum):
@@ -0,0 +1,174 @@
1
+ from kerykeion import AstrologicalSubject
2
+ from kerykeion.astrological_subject import DEFAULT_HOUSES_SYSTEM_IDENTIFIER, DEFAULT_PERSPECTIVE_TYPE, DEFAULT_ZODIAC_TYPE
3
+ from kerykeion.kr_types import EphemerisDictModel
4
+ from kerykeion.kr_types import SiderealMode, HousesSystemIdentifier, PerspectiveType, ZodiacType
5
+ from datetime import datetime, timedelta
6
+ from typing import Literal, Union
7
+ import logging
8
+
9
+
10
+ class EphemerisDataFactory:
11
+ """
12
+ This class is used to generate ephemeris data for a given date range.
13
+
14
+ Parameters:
15
+ - start_datetime: datetime object representing the start date and time.
16
+ - end_datetime: datetime object representing the end date and time.
17
+ - step_type: string representing the step type. It can be "days", "hours", or "minutes". Default is "days".
18
+ - step: integer representing the step value. Default is 1.
19
+ - lat: float representing the latitude. Default is 51.4769 (Greenwich).
20
+ - lng: float representing the longitude. Default is 0.0005 (Greenwich).
21
+ - tz_str: string representing the timezone. Default is "Etc/UTC".
22
+ - is_dst: boolean representing if daylight saving time is active. Default is False.
23
+ - disable_chiron_and_lilith: boolean representing if Chiron and Lilith should be disabled. Default is False.
24
+ - zodiac_type: ZodiacType object representing the zodiac type. Default is DEFAULT_ZODIAC_TYPE.
25
+ - sidereal_mode: SiderealMode object representing the sidereal mode. Default is None.
26
+ - houses_system_identifier: HousesSystemIdentifier object representing the houses system identifier. Default is DEFAULT_HOUSES_SYSTEM_IDENTIFIER.
27
+ - perspective_type: PerspectiveType object representing the perspective type. Default is DEFAULT_PERSPECTIVE_TYPE.
28
+ - max_days: integer representing the maximum number of days.
29
+ Set it to None to disable the check. Default is 730.
30
+ - max_hours: integer representing the maximum number of hours.
31
+ Set it to None to disable the check. Default is 8760.
32
+ - max_minutes: integer representing the maximum number of minutes.
33
+ Set it to None to disable the check. Default is 525600.
34
+
35
+ Raises:
36
+ - ValueError: if the step type is invalid.
37
+ - ValueError: if the number of days, hours, or minutes is greater than the maximum allowed.
38
+ """
39
+
40
+ def __init__(
41
+ self,
42
+ start_datetime: datetime,
43
+ end_datetime: datetime,
44
+ step_type: Literal["days", "hours", "minutes"] = "days",
45
+ step: int = 1,
46
+ lat: float = 51.4769,
47
+ lng: float = 0.0005,
48
+ tz_str: str = "Etc/UTC",
49
+ is_dst: bool = False,
50
+ disable_chiron_and_lilith: bool = False,
51
+ zodiac_type: ZodiacType = DEFAULT_ZODIAC_TYPE,
52
+ sidereal_mode: Union[SiderealMode, None] = None,
53
+ houses_system_identifier: HousesSystemIdentifier = DEFAULT_HOUSES_SYSTEM_IDENTIFIER,
54
+ perspective_type: PerspectiveType = DEFAULT_PERSPECTIVE_TYPE,
55
+ max_days: int = 730,
56
+ max_hours: int = 8760,
57
+ max_minutes: int = 525600,
58
+ ):
59
+ self.start_datetime = start_datetime
60
+ self.end_datetime = end_datetime
61
+ self.step_type = step_type
62
+ self.step = step
63
+ self.lat = lat
64
+ self.lng = lng
65
+ self.tz_str = tz_str
66
+ self.is_dst = is_dst
67
+ self.disable_chiron_and_lilith = disable_chiron_and_lilith
68
+ self.zodiac_type = zodiac_type
69
+ self.sidereal_mode = sidereal_mode
70
+ self.houses_system_identifier = houses_system_identifier
71
+ self.perspective_type = perspective_type
72
+ self.max_days = max_days
73
+ self.max_hours = max_hours
74
+ self.max_minutes = max_minutes
75
+
76
+ self.dates_list = []
77
+ if self.step_type == "days":
78
+ self.dates_list = [self.start_datetime + timedelta(days=i) for i in range((self.end_datetime - self.start_datetime).days)]
79
+ if max_days and (len(self.dates_list) > max_days):
80
+ raise ValueError(f"Too many days: {len(self.dates_list)} > {self.max_days}. To prevent this error, set max_days to a higher value or reduce the date range.")
81
+
82
+ elif self.step_type == "hours":
83
+ self.dates_list = [self.start_datetime + timedelta(hours=i) for i in range((self.end_datetime - self.start_datetime).days * 24)]
84
+ if max_hours and (len(self.dates_list) > max_hours):
85
+ raise ValueError(f"Too many hours: {len(self.dates_list)} > {self.max_hours}. To prevent this error, set max_hours to a higher value or reduce the date range.")
86
+
87
+ elif self.step_type == "minutes":
88
+ self.dates_list = [self.start_datetime + timedelta(minutes=i) for i in range((self.end_datetime - self.start_datetime).days * 24 * 60)]
89
+ if max_minutes and (len(self.dates_list) > max_minutes):
90
+ raise ValueError(f"Too many minutes: {len(self.dates_list)} > {self.max_minutes}. To prevent this error, set max_minutes to a higher value or reduce the date range.")
91
+
92
+ else:
93
+ raise ValueError(f"Invalid step type: {self.step_type}")
94
+
95
+ if not self.dates_list:
96
+ raise ValueError("No dates found. Check the date range and step values.")
97
+
98
+ if len(self.dates_list) > 1000:
99
+ logging.warning(f"Large number of dates: {len(self.dates_list)}. The calculation may take a while.")
100
+
101
+ def get_ephemeris_data(self) -> list:
102
+ """
103
+ Generate ephemeris data for the specified date range.
104
+ The data is structured as a list of dictionaries, where each dictionary contains the date, planets, and houses data.
105
+ Eg. [{"date": "2020-01-01T00:00:00", "planets": [{...}, {...}, ...], "houses": [{...}, {...}, ...]}, ...]
106
+
107
+ Args:
108
+ - as_model: boolean representing if the ephemeris data should be returned as model instances. Default is False.
109
+ - as_dict: boolean representing if the ephemeris data should be returned as dictionaries. Default is False.
110
+
111
+ Returns:
112
+ - list of dictionaries representing the ephemeris data.
113
+ """
114
+ ephemeris_data_list = []
115
+ for date in self.dates_list:
116
+ subject = AstrologicalSubject(
117
+ year=date.year,
118
+ month=date.month,
119
+ day=date.day,
120
+ hour=date.hour,
121
+ minute=date.minute,
122
+ lng=self.lng,
123
+ lat=self.lat,
124
+ tz_str=self.tz_str,
125
+ city="Placeholder",
126
+ nation="Placeholder",
127
+ online=False,
128
+ disable_chiron_and_lilith=self.disable_chiron_and_lilith,
129
+ zodiac_type=self.zodiac_type,
130
+ sidereal_mode=self.sidereal_mode,
131
+ houses_system_identifier=self.houses_system_identifier,
132
+ perspective_type=self.perspective_type,
133
+ is_dst=self.is_dst,
134
+ )
135
+
136
+ ephemeris_data_list.append({"date": date.isoformat(), "planets": subject.planets_list, "houses": subject.houses_list})
137
+
138
+ return ephemeris_data_list
139
+
140
+ def get_ephemeris_data_as_model(self) -> list[EphemerisDictModel]:
141
+ """
142
+ Generate ephemeris data as model instances for the specified date range.
143
+ The data is structured as a list of EphemerisDictModel instances.
144
+
145
+ Returns:
146
+ - list of EphemerisDictModel instances representing the ephemeris data.
147
+ """
148
+ return [EphemerisDictModel(**data) for data in self.get_ephemeris_data()]
149
+
150
+
151
+ if "__main__" == __name__:
152
+ start_date = datetime.fromisoformat("2020-01-01")
153
+ end_date = datetime.fromisoformat("2020-01-03")
154
+
155
+ factory = EphemerisDataFactory(
156
+ start_datetime=start_date,
157
+ end_datetime=end_date,
158
+ step_type="minutes",
159
+ step=1,
160
+ lat=37.9838,
161
+ lng=23.7275,
162
+ tz_str="Europe/Athens",
163
+ is_dst=False,
164
+ max_hours=None,
165
+ max_minutes=None,
166
+ max_days=None,
167
+ )
168
+
169
+ ephemeris_data = factory.get_ephemeris_data_as_model()
170
+ print(ephemeris_data[0])
171
+ print(len(ephemeris_data))
172
+
173
+ for ephe in ephemeris_data:
174
+ print(ephe.planets[0]["abs_pos"])
@@ -79,12 +79,11 @@ class FetchGeonames:
79
79
 
80
80
  params = {
81
81
  "q": city_name,
82
- "contry": country_code,
82
+ "country": country_code,
83
83
  "username": self.username,
84
84
  "maxRows": 1,
85
85
  "style": "SHORT",
86
- "featureClass": "A",
87
- "featureClass": "P",
86
+ "featureClass": ["A", "P"],
88
87
  }
89
88
 
90
89
  prepared_request = Request("GET", self.base_url, params=params).prepare()
@@ -6,17 +6,11 @@ class ChartTemplateDictionary(TypedDict):
6
6
  degreeRing: str
7
7
  first_circle: str
8
8
  second_circle: str
9
- c3: str
10
- c3style: str
9
+ third_circle: str
11
10
  makeAspects: str
12
11
  makeAspectGrid: str
13
- makePatterns: str
14
12
  chart_height: float
15
13
  chart_width: float
16
- circleX: str
17
- circleY: str
18
- svgWidth: str
19
- svgHeight: str
20
14
  viewbox: str
21
15
  stringTitle: str
22
16
  stringName: str
@@ -42,7 +36,7 @@ class ChartTemplateDictionary(TypedDict):
42
36
  # Background color of the chart
43
37
  paper_color_1: str
44
38
 
45
- # Planets colors, from 1 to 15 (0 is the Sun)
39
+ # Planets colors, from 0 to 16 (0 is the Sun)
46
40
  planets_color_0: str
47
41
  planets_color_1: str
48
42
  planets_color_2: str
@@ -59,6 +53,7 @@ class ChartTemplateDictionary(TypedDict):
59
53
  planets_color_13: str
60
54
  planets_color_14: str
61
55
  planets_color_15: str
56
+ planets_color_16: str
62
57
 
63
58
  # Zodiac colors, from 0 to 11 (0 is Aries)
64
59
  zodiac_color_0: str
@@ -87,7 +82,6 @@ class ChartTemplateDictionary(TypedDict):
87
82
  orb_color_150: str
88
83
  orb_color_180: str
89
84
 
90
- cfgZoom: str
91
85
  cfgRotate: str
92
86
  cfgTranslate: str
93
87
  makeZodiac: str
@@ -25,7 +25,7 @@ HouseNumbers = Literal[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
25
25
  """Literal type for House Numbers, starting from the First House (1) to the Twelfth House (12)"""
26
26
 
27
27
 
28
- Planet = Literal["Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", "Mean_Node", "True_Node", "Chiron"]
28
+ Planet = Literal["Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", "Mean_Node", "True_Node", "Chiron", "Mean_Lilith"]
29
29
  """Literal type for Planets"""
30
30
 
31
31
 
@@ -98,4 +98,4 @@ Literal type for perspective types.
98
98
  - "True Geocentric": Earth-centered, true positions.
99
99
 
100
100
  Usually the standard is "Apparent Geocentric"
101
- """
101
+ """
@@ -7,12 +7,29 @@
7
7
  from typing import Union, Optional
8
8
  from pydantic import BaseModel
9
9
 
10
- from kerykeion.kr_types import LunarPhaseEmoji, LunarPhaseName, Planet, Houses, Quality, Element, Sign, ZodiacType, SignNumbers, HouseNumbers, PointType, SiderealMode, HousesSystemIdentifier
10
+ from kerykeion.kr_types import (
11
+ LunarPhaseEmoji,
12
+ LunarPhaseName,
13
+ Planet,
14
+ Houses,
15
+ Quality,
16
+ Element,
17
+ Sign,
18
+ ZodiacType,
19
+ SignNumbers,
20
+ HouseNumbers,
21
+ PointType,
22
+ SiderealMode,
23
+ HousesSystemIdentifier,
24
+ Houses,
25
+ )
26
+
11
27
 
12
28
  class SubscriptableBaseModel(BaseModel):
13
29
  """
14
30
  Pydantic BaseModel with subscriptable support, so you can access the fields as if they were a dictionary.
15
31
  """
32
+
16
33
  def __getitem__(self, key):
17
34
  return getattr(self, key)
18
35
 
@@ -25,6 +42,7 @@ class SubscriptableBaseModel(BaseModel):
25
42
  def get(self, key, default):
26
43
  return getattr(self, key, default)
27
44
 
45
+
28
46
  class LunarPhaseModel(SubscriptableBaseModel):
29
47
  degrees_between_s_m: Union[float, int]
30
48
  moon_phase: int
@@ -47,7 +65,7 @@ class KerykeionPointModel(SubscriptableBaseModel):
47
65
  abs_pos: float
48
66
  emoji: str
49
67
  point_type: PointType
50
- house: Optional[HouseNumbers] = None
68
+ house: Optional[Houses] = None
51
69
  retrograde: Optional[bool] = None
52
70
 
53
71
 
@@ -73,6 +91,11 @@ class AstrologicalSubjectModel(SubscriptableBaseModel):
73
91
  iso_formatted_utc_datetime: str
74
92
  julian_day: float
75
93
 
94
+ # Deprecated properties -->
95
+ utc_time: float
96
+ local_time: float
97
+ # <-- Deprecated properties
98
+
76
99
  # Planets
77
100
  sun: KerykeionPointModel
78
101
  moon: KerykeionPointModel
@@ -87,6 +110,7 @@ class AstrologicalSubjectModel(SubscriptableBaseModel):
87
110
 
88
111
  # Optional Planets:
89
112
  chiron: Union[KerykeionPointModel, None]
113
+ mean_lilith: Union[KerykeionPointModel, None]
90
114
 
91
115
  # Houses
92
116
  first_house: KerykeionPointModel
@@ -109,32 +133,28 @@ class AstrologicalSubjectModel(SubscriptableBaseModel):
109
133
  # Lunar Phase
110
134
  lunar_phase: LunarPhaseModel
111
135
 
112
- # Deprecated properties
113
- utc_time: float
114
- local_time: float
115
-
116
136
  # Lists
117
137
  # houses_list: list[KerykeionPointModel]
118
138
  # planets_list: list[KerykeionPointModel]
119
139
  # planets_degrees_ut: list[float]
120
140
  # houses_degree_ut: list[float]
121
141
 
122
- if __name__ == "__main__":
123
- from kerykeion.utilities import setup_logging
124
-
125
- setup_logging(level="debug")
126
-
127
- sun = KerykeionPointModel(
128
- name="Sun",
129
- element="Air",
130
- quality="Fixed",
131
- sign="Aqu",
132
- sign_num=1,
133
- position=0,
134
- abs_pos=12.123123,
135
- emoji="♈",
136
- point_type="Planet",
137
- )
138
-
139
- print(sun.model_dump_json())
140
- print(sun)
142
+
143
+ class EphemerisDictModel(SubscriptableBaseModel):
144
+ date: str
145
+ planets: list[KerykeionPointModel]
146
+ houses: list[KerykeionPointModel]
147
+
148
+
149
+ class AspectModel(SubscriptableBaseModel):
150
+ p1_name: str
151
+ p1_abs_pos: float
152
+ p2_name: str
153
+ p2_abs_pos: float
154
+ aspect: str
155
+ orbit: float
156
+ aspect_degrees: int
157
+ aid: int
158
+ diff: float
159
+ p1: int
160
+ p2: int
@@ -64,6 +64,8 @@ class KerykeionSettingsChartColorsModel(SubscriptableBaseModel):
64
64
  zodiac_transit_ring_3: str = Field(title="Zodiac Transit Ring Color 3", description="Zodiac Transit Ring Color 3")
65
65
  houses_radix_line: str = Field(title="Houses Radix Line Color", description="Houses Radix Line Color")
66
66
  houses_transit_line: str = Field(title="Houses Transit Line Color", description="Houses Transit Line Color")
67
+
68
+ # Deprecated: Not used anymore
67
69
  lunar_phase_0: str = Field(title="Lunar Phase Color 0", description="Lunar Phase Color 0")
68
70
  lunar_phase_1: str = Field(title="Lunar Phase Color 1", description="Lunar Phase Color 1")
69
71
  lunar_phase_2: str = Field(title="Lunar Phase Color 2", description="Lunar Phase Color 2")
@@ -109,6 +111,7 @@ class KerykeionLanguageCelestialPointModel(SubscriptableBaseModel):
109
111
  Mc: str = Field(title="Medium Coeli", description="The name of Medium Coeli in the chart, in the language")
110
112
  Dsc: str = Field(title="Descendant", description="The name of Descendant in the chart, in the language")
111
113
  Ic: str = Field(title="Imum Coeli", description="The name of Imum Coeli in the chart, in the language")
114
+ Mean_Lilith: str = Field(title="Mean Lilith", description="The name of Mean Lilith in the chart, in the language")
112
115
 
113
116
 
114
117
  class KerykeionLanguageModel(SubscriptableBaseModel):
@@ -160,4 +163,4 @@ class KerykeionSettingsModel(SubscriptableBaseModel):
160
163
  aspects: List[KerykeionSettingsAspectModel] = Field(title="Aspects", description="The list of the aspects of the chart")
161
164
  language_settings: dict[str, KerykeionLanguageModel] = Field(title="Language Settings", description="The language settings of the chart")
162
165
  general_settings: KerykeionGeneralSettingsModel = Field(title="General Settings", description="The general settings of the chart")
163
- chart_settings: KerykeionChartSettingsModel = Field(title="Chart Settings", description="The chart settings of the chart")
166
+ chart_settings: KerykeionChartSettingsModel = Field(title="Chart Settings", description="The chart settings of the chart")
@@ -38,7 +38,8 @@
38
38
  "Ic": "Ic",
39
39
  "True_Node": "North Node",
40
40
  "Mean_Node": "Mean Node",
41
- "Chiron": "Chiron"
41
+ "Chiron": "Chiron",
42
+ "Mean_Lilith": "Lilith"
42
43
  }
43
44
  },
44
45
  "FR": {
@@ -79,7 +80,8 @@
79
80
  "Ic": "Ic",
80
81
  "True_Node": "Noeud Nord",
81
82
  "Mean_Node": "Noeud Moyen",
82
- "Chiron": "Chiron"
83
+ "Chiron": "Chiron",
84
+ "Mean_Lilith": "Lilith"
83
85
  }
84
86
  },
85
87
  "PT": {
@@ -120,7 +122,8 @@
120
122
  "Ic": "Ic",
121
123
  "True_Node": "Nodo Norte",
122
124
  "Mean_Node": "Nodo Médio",
123
- "Chiron": "Quíron"
125
+ "Chiron": "Quíron",
126
+ "Mean_Lilith": "Lilith"
124
127
  }
125
128
  },
126
129
  "IT": {
@@ -161,7 +164,8 @@
161
164
  "Ic": "Ic",
162
165
  "True_Node": "Nodo Nord",
163
166
  "Mean_Node": "Nodo Medio",
164
- "Chiron": "Chirone"
167
+ "Chiron": "Chirone",
168
+ "Mean_Lilith": "Lilith"
165
169
  }
166
170
  },
167
171
  "CN": {
@@ -202,7 +206,8 @@
202
206
  "Ic": "下中天",
203
207
  "True_Node": "北交點",
204
208
  "Mean_Node": "平交點",
205
- "Chiron": "凱龍星"
209
+ "Chiron": "凱龍星",
210
+ "Mean_Lilith": "黑月亮"
206
211
  }
207
212
  }
208
213
  },
@@ -471,6 +476,15 @@
471
476
  "element_points": 0,
472
477
  "related_zodiac_signs": [],
473
478
  "label": "Ic"
479
+ },
480
+ {
481
+ "id": 17,
482
+ "name": "Mean_Lilith",
483
+ "color": "#000",
484
+ "is_active": true,
485
+ "element_points": 0,
486
+ "related_zodiac_signs": [],
487
+ "label": "Mean_Lilith"
474
488
  }
475
489
  ],
476
490
  "chart_colors": {
kerykeion/utilities.py CHANGED
@@ -35,6 +35,8 @@ def get_number_from_name(name: Planet) -> int:
35
35
  return 11
36
36
  elif name == "Chiron":
37
37
  return 15
38
+ elif name == "Mean_Lilith":
39
+ return 12
38
40
  else:
39
41
  raise KerykeionException(f"Error in getting number from name! Name: {name}")
40
42
 
@@ -356,7 +358,7 @@ def get_moon_phase_name_from_phase_int(phase: int) -> LunarPhaseName:
356
358
  return result
357
359
 
358
360
 
359
- def check_and_adjust_polar_latitude(latitude: float, longitude: float) -> bool:
361
+ def check_and_adjust_polar_latitude(latitude: float) -> float:
360
362
  """
361
363
  Utility function to check if the location is in the polar circle.
362
364
  If it is, it sets the latitude to 66 or -66 degrees.
@@ -367,4 +369,6 @@ def check_and_adjust_polar_latitude(latitude: float, longitude: float) -> bool:
367
369
 
368
370
  elif latitude < -66.0:
369
371
  latitude = -66.0
370
- logging.info("Polar circle override for houses, using -66 degrees")
372
+ logging.info("Polar circle override for houses, using -66 degrees")
373
+
374
+ return latitude