kerykeion.ephemeris_data

  1from kerykeion import AstrologicalSubject
  2from kerykeion.utilities import get_houses_list, get_available_astrological_points_list
  3from kerykeion.astrological_subject import DEFAULT_HOUSES_SYSTEM_IDENTIFIER, DEFAULT_PERSPECTIVE_TYPE, DEFAULT_ZODIAC_TYPE
  4from kerykeion.kr_types import EphemerisDictModel
  5from kerykeion.kr_types import SiderealMode, HousesSystemIdentifier, PerspectiveType, ZodiacType
  6from datetime import datetime, timedelta
  7from typing import Literal, Union, List
  8import logging
  9
 10
 11class EphemerisDataFactory:
 12    """
 13    This class is used to generate ephemeris data for a given date range.
 14
 15    Parameters:
 16    - start_datetime: datetime object representing the start date and time.
 17    - end_datetime: datetime object representing the end date and time.
 18    - step_type: string representing the step type. It can be "days", "hours", or "minutes". Default is "days".
 19    - step: integer representing the step value. Default is 1.
 20    - lat: float representing the latitude. Default is 51.4769 (Greenwich).
 21    - lng: float representing the longitude. Default is 0.0005 (Greenwich).
 22    - tz_str: string representing the timezone. Default is "Etc/UTC".
 23    - is_dst: boolean representing if daylight saving time is active. Default is False.
 24    - disable_chiron_and_lilith: boolean representing if Chiron and Lilith should be disabled. Default is False.
 25    - zodiac_type: ZodiacType object representing the zodiac type. Default is DEFAULT_ZODIAC_TYPE.
 26    - sidereal_mode: SiderealMode object representing the sidereal mode. Default is None.
 27    - houses_system_identifier: HousesSystemIdentifier object representing the houses system identifier. Default is DEFAULT_HOUSES_SYSTEM_IDENTIFIER.
 28    - perspective_type: PerspectiveType object representing the perspective type. Default is DEFAULT_PERSPECTIVE_TYPE.
 29    - max_days: integer representing the maximum number of days.
 30        Set it to None to disable the check. Default is 730.
 31    - max_hours: integer representing the maximum number of hours.
 32        Set it to None to disable the check. Default is 8760.
 33    - max_minutes: integer representing the maximum number of minutes.
 34        Set it to None to disable the check. Default is 525600.
 35
 36    Raises:
 37    - ValueError: if the step type is invalid.
 38    - ValueError: if the number of days, hours, or minutes is greater than the maximum allowed.
 39    """
 40
 41    def __init__(
 42        self,
 43        start_datetime: datetime,
 44        end_datetime: datetime,
 45        step_type: Literal["days", "hours", "minutes"] = "days",
 46        step: int = 1,
 47        lat: float = 51.4769,
 48        lng: float = 0.0005,
 49        tz_str: str = "Etc/UTC",
 50        is_dst: bool = False,
 51        disable_chiron_and_lilith: bool = False,
 52        zodiac_type: ZodiacType = DEFAULT_ZODIAC_TYPE,
 53        sidereal_mode: Union[SiderealMode, None] = None,
 54        houses_system_identifier: HousesSystemIdentifier = DEFAULT_HOUSES_SYSTEM_IDENTIFIER,
 55        perspective_type: PerspectiveType = DEFAULT_PERSPECTIVE_TYPE,
 56        max_days: Union[int, None] = 730,
 57        max_hours: Union[int, None] = 8760,
 58        max_minutes: Union[int, None] = 525600,
 59    ):
 60        self.start_datetime = start_datetime
 61        self.end_datetime = end_datetime
 62        self.step_type = step_type
 63        self.step = step
 64        self.lat = lat
 65        self.lng = lng
 66        self.tz_str = tz_str
 67        self.is_dst = is_dst
 68        self.disable_chiron_and_lilith = disable_chiron_and_lilith
 69        self.zodiac_type = zodiac_type
 70        self.sidereal_mode = sidereal_mode
 71        self.houses_system_identifier = houses_system_identifier
 72        self.perspective_type = perspective_type
 73        self.max_days = max_days
 74        self.max_hours = max_hours
 75        self.max_minutes = max_minutes
 76
 77        self.dates_list = []
 78        if self.step_type == "days":
 79            self.dates_list = [self.start_datetime + timedelta(days=i * self.step) for i in range((self.end_datetime - self.start_datetime).days // self.step + 1)]
 80            if max_days and (len(self.dates_list) > max_days):
 81                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.")
 82
 83        elif self.step_type == "hours":
 84            hours_diff = (self.end_datetime - self.start_datetime).total_seconds() / 3600
 85            self.dates_list = [self.start_datetime + timedelta(hours=i * self.step) for i in range(int(hours_diff) // self.step + 1)]
 86            if max_hours and (len(self.dates_list) > max_hours):
 87                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.")
 88
 89        elif self.step_type == "minutes":
 90            minutes_diff = (self.end_datetime - self.start_datetime).total_seconds() / 60
 91            self.dates_list = [self.start_datetime + timedelta(minutes=i * self.step) for i in range(int(minutes_diff) // self.step + 1)]
 92            if max_minutes and (len(self.dates_list) > max_minutes):
 93                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.")
 94
 95        else:
 96            raise ValueError(f"Invalid step type: {self.step_type}")
 97
 98        if not self.dates_list:
 99            raise ValueError("No dates found. Check the date range and step values.")
100
101        if len(self.dates_list) > 1000:
102            logging.warning(f"Large number of dates: {len(self.dates_list)}. The calculation may take a while.")
103
104    def get_ephemeris_data(self, as_model: bool = False) -> list:
105        """
106        Generate ephemeris data for the specified date range.
107        The data is structured as a list of dictionaries, where each dictionary contains the date, planets, and houses data.
108        Example:
109        [
110            {
111                "date": "2020-01-01T00:00:00",
112                "planets": [{...}, {...}, ...],
113                "houses": [{...}, {...}, ...]
114            },
115            ...
116        ]
117
118        Args:
119        - as_model (bool): If True, the ephemeris data will be returned as model instances. Default is False.
120
121        Returns:
122        - list: A list of dictionaries representing the ephemeris data. If as_model is True, a list of EphemerisDictModel instances is returned.
123        """
124        ephemeris_data_list = []
125        for date in self.dates_list:
126            subject = AstrologicalSubject(
127                year=date.year,
128                month=date.month,
129                day=date.day,
130                hour=date.hour,
131                minute=date.minute,
132                lng=self.lng,
133                lat=self.lat,
134                tz_str=self.tz_str,
135                city="Placeholder",
136                nation="Placeholder",
137                online=False,
138                disable_chiron_and_lilith=self.disable_chiron_and_lilith,
139                zodiac_type=self.zodiac_type,
140                sidereal_mode=self.sidereal_mode,
141                houses_system_identifier=self.houses_system_identifier,
142                perspective_type=self.perspective_type,
143                is_dst=self.is_dst,
144            )
145
146            houses_list = get_houses_list(subject)
147            available_planets = get_available_astrological_points_list(subject)
148
149            ephemeris_data_list.append({"date": date.isoformat(), "planets": available_planets, "houses": houses_list})
150
151        if as_model:
152            return [EphemerisDictModel(**data) for data in ephemeris_data_list]
153
154        return ephemeris_data_list
155
156    def get_ephemeris_data_as_astrological_subjects(self, as_model: bool = False) -> List[AstrologicalSubject]:
157        """
158        Generate ephemeris data for the specified date range as AstrologicalSubject instances.
159
160        This method creates a complete AstrologicalSubject object for each date in the date range,
161        allowing direct access to all properties and methods of the AstrologicalSubject class.
162
163        Args:
164        - as_model (bool): If True, the AstrologicalSubject instances will be returned as model instances. Default is False.
165
166        Returns:
167        - List[AstrologicalSubject]: A list of AstrologicalSubject instances, one for each date in the date range.
168
169        Example usage:
170            subjects = factory.get_ephemeris_data_as_astrological_subjects()
171            # Access methods and properties of the first subject
172            sun_position = subjects[0].get_sun()
173            all_points = subjects[0].get_all_points()
174            chart_drawing = subjects[0].draw_chart()
175        """
176        subjects_list = []
177        for date in self.dates_list:
178            subject = AstrologicalSubject(
179                year=date.year,
180                month=date.month,
181                day=date.day,
182                hour=date.hour,
183                minute=date.minute,
184                lng=self.lng,
185                lat=self.lat,
186                tz_str=self.tz_str,
187                city="Placeholder",
188                nation="Placeholder",
189                online=False,
190                disable_chiron_and_lilith=self.disable_chiron_and_lilith,
191                zodiac_type=self.zodiac_type,
192                sidereal_mode=self.sidereal_mode,
193                houses_system_identifier=self.houses_system_identifier,
194                perspective_type=self.perspective_type,
195                is_dst=self.is_dst,
196            )
197
198            if as_model:
199                subjects_list.append(subject.model())
200            else:
201                subjects_list.append(subject)
202
203        return subjects_list
204
205
206if "__main__" == __name__:
207    start_date = datetime.fromisoformat("2020-01-01")
208    end_date = datetime.fromisoformat("2020-01-03")
209
210    factory = EphemerisDataFactory(
211        start_datetime=start_date,
212        end_datetime=end_date,
213        step_type="minutes",
214        step=60,  # One hour intervals to make the example more manageable
215        lat=37.9838,
216        lng=23.7275,
217        tz_str="Europe/Athens",
218        is_dst=False,
219        max_hours=None,
220        max_minutes=None,
221        max_days=None,
222    )
223
224    # Test original method
225    ephemeris_data = factory.get_ephemeris_data(as_model=True)
226    print(f"Number of ephemeris data points: {len(ephemeris_data)}")
227    print(f"First data point date: {ephemeris_data[0].date}")
228
229    # Test new method
230    subjects = factory.get_ephemeris_data_as_astrological_subjects()
231    print(f"Number of astrological subjects: {len(subjects)}")
232    print(f"First subject sun position: {subjects[0].sun}")
233
234    # Example of accessing more data from the first subject
235    first_subject = subjects[0]
236    print(f"Sun sign: {first_subject.sun['sign']}")
237
238    # Compare sun positions from both methods
239    for i in range(min(3, len(subjects))):
240        print(f"Date: {ephemeris_data[i].date}")
241        print(f"Sun position from dict: {ephemeris_data[i].planets[0]['abs_pos']}")
242        print("---")
class EphemerisDataFactory:
 12class EphemerisDataFactory:
 13    """
 14    This class is used to generate ephemeris data for a given date range.
 15
 16    Parameters:
 17    - start_datetime: datetime object representing the start date and time.
 18    - end_datetime: datetime object representing the end date and time.
 19    - step_type: string representing the step type. It can be "days", "hours", or "minutes". Default is "days".
 20    - step: integer representing the step value. Default is 1.
 21    - lat: float representing the latitude. Default is 51.4769 (Greenwich).
 22    - lng: float representing the longitude. Default is 0.0005 (Greenwich).
 23    - tz_str: string representing the timezone. Default is "Etc/UTC".
 24    - is_dst: boolean representing if daylight saving time is active. Default is False.
 25    - disable_chiron_and_lilith: boolean representing if Chiron and Lilith should be disabled. Default is False.
 26    - zodiac_type: ZodiacType object representing the zodiac type. Default is DEFAULT_ZODIAC_TYPE.
 27    - sidereal_mode: SiderealMode object representing the sidereal mode. Default is None.
 28    - houses_system_identifier: HousesSystemIdentifier object representing the houses system identifier. Default is DEFAULT_HOUSES_SYSTEM_IDENTIFIER.
 29    - perspective_type: PerspectiveType object representing the perspective type. Default is DEFAULT_PERSPECTIVE_TYPE.
 30    - max_days: integer representing the maximum number of days.
 31        Set it to None to disable the check. Default is 730.
 32    - max_hours: integer representing the maximum number of hours.
 33        Set it to None to disable the check. Default is 8760.
 34    - max_minutes: integer representing the maximum number of minutes.
 35        Set it to None to disable the check. Default is 525600.
 36
 37    Raises:
 38    - ValueError: if the step type is invalid.
 39    - ValueError: if the number of days, hours, or minutes is greater than the maximum allowed.
 40    """
 41
 42    def __init__(
 43        self,
 44        start_datetime: datetime,
 45        end_datetime: datetime,
 46        step_type: Literal["days", "hours", "minutes"] = "days",
 47        step: int = 1,
 48        lat: float = 51.4769,
 49        lng: float = 0.0005,
 50        tz_str: str = "Etc/UTC",
 51        is_dst: bool = False,
 52        disable_chiron_and_lilith: bool = False,
 53        zodiac_type: ZodiacType = DEFAULT_ZODIAC_TYPE,
 54        sidereal_mode: Union[SiderealMode, None] = None,
 55        houses_system_identifier: HousesSystemIdentifier = DEFAULT_HOUSES_SYSTEM_IDENTIFIER,
 56        perspective_type: PerspectiveType = DEFAULT_PERSPECTIVE_TYPE,
 57        max_days: Union[int, None] = 730,
 58        max_hours: Union[int, None] = 8760,
 59        max_minutes: Union[int, None] = 525600,
 60    ):
 61        self.start_datetime = start_datetime
 62        self.end_datetime = end_datetime
 63        self.step_type = step_type
 64        self.step = step
 65        self.lat = lat
 66        self.lng = lng
 67        self.tz_str = tz_str
 68        self.is_dst = is_dst
 69        self.disable_chiron_and_lilith = disable_chiron_and_lilith
 70        self.zodiac_type = zodiac_type
 71        self.sidereal_mode = sidereal_mode
 72        self.houses_system_identifier = houses_system_identifier
 73        self.perspective_type = perspective_type
 74        self.max_days = max_days
 75        self.max_hours = max_hours
 76        self.max_minutes = max_minutes
 77
 78        self.dates_list = []
 79        if self.step_type == "days":
 80            self.dates_list = [self.start_datetime + timedelta(days=i * self.step) for i in range((self.end_datetime - self.start_datetime).days // self.step + 1)]
 81            if max_days and (len(self.dates_list) > max_days):
 82                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.")
 83
 84        elif self.step_type == "hours":
 85            hours_diff = (self.end_datetime - self.start_datetime).total_seconds() / 3600
 86            self.dates_list = [self.start_datetime + timedelta(hours=i * self.step) for i in range(int(hours_diff) // self.step + 1)]
 87            if max_hours and (len(self.dates_list) > max_hours):
 88                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.")
 89
 90        elif self.step_type == "minutes":
 91            minutes_diff = (self.end_datetime - self.start_datetime).total_seconds() / 60
 92            self.dates_list = [self.start_datetime + timedelta(minutes=i * self.step) for i in range(int(minutes_diff) // self.step + 1)]
 93            if max_minutes and (len(self.dates_list) > max_minutes):
 94                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.")
 95
 96        else:
 97            raise ValueError(f"Invalid step type: {self.step_type}")
 98
 99        if not self.dates_list:
100            raise ValueError("No dates found. Check the date range and step values.")
101
102        if len(self.dates_list) > 1000:
103            logging.warning(f"Large number of dates: {len(self.dates_list)}. The calculation may take a while.")
104
105    def get_ephemeris_data(self, as_model: bool = False) -> list:
106        """
107        Generate ephemeris data for the specified date range.
108        The data is structured as a list of dictionaries, where each dictionary contains the date, planets, and houses data.
109        Example:
110        [
111            {
112                "date": "2020-01-01T00:00:00",
113                "planets": [{...}, {...}, ...],
114                "houses": [{...}, {...}, ...]
115            },
116            ...
117        ]
118
119        Args:
120        - as_model (bool): If True, the ephemeris data will be returned as model instances. Default is False.
121
122        Returns:
123        - list: A list of dictionaries representing the ephemeris data. If as_model is True, a list of EphemerisDictModel instances is returned.
124        """
125        ephemeris_data_list = []
126        for date in self.dates_list:
127            subject = AstrologicalSubject(
128                year=date.year,
129                month=date.month,
130                day=date.day,
131                hour=date.hour,
132                minute=date.minute,
133                lng=self.lng,
134                lat=self.lat,
135                tz_str=self.tz_str,
136                city="Placeholder",
137                nation="Placeholder",
138                online=False,
139                disable_chiron_and_lilith=self.disable_chiron_and_lilith,
140                zodiac_type=self.zodiac_type,
141                sidereal_mode=self.sidereal_mode,
142                houses_system_identifier=self.houses_system_identifier,
143                perspective_type=self.perspective_type,
144                is_dst=self.is_dst,
145            )
146
147            houses_list = get_houses_list(subject)
148            available_planets = get_available_astrological_points_list(subject)
149
150            ephemeris_data_list.append({"date": date.isoformat(), "planets": available_planets, "houses": houses_list})
151
152        if as_model:
153            return [EphemerisDictModel(**data) for data in ephemeris_data_list]
154
155        return ephemeris_data_list
156
157    def get_ephemeris_data_as_astrological_subjects(self, as_model: bool = False) -> List[AstrologicalSubject]:
158        """
159        Generate ephemeris data for the specified date range as AstrologicalSubject instances.
160
161        This method creates a complete AstrologicalSubject object for each date in the date range,
162        allowing direct access to all properties and methods of the AstrologicalSubject class.
163
164        Args:
165        - as_model (bool): If True, the AstrologicalSubject instances will be returned as model instances. Default is False.
166
167        Returns:
168        - List[AstrologicalSubject]: A list of AstrologicalSubject instances, one for each date in the date range.
169
170        Example usage:
171            subjects = factory.get_ephemeris_data_as_astrological_subjects()
172            # Access methods and properties of the first subject
173            sun_position = subjects[0].get_sun()
174            all_points = subjects[0].get_all_points()
175            chart_drawing = subjects[0].draw_chart()
176        """
177        subjects_list = []
178        for date in self.dates_list:
179            subject = AstrologicalSubject(
180                year=date.year,
181                month=date.month,
182                day=date.day,
183                hour=date.hour,
184                minute=date.minute,
185                lng=self.lng,
186                lat=self.lat,
187                tz_str=self.tz_str,
188                city="Placeholder",
189                nation="Placeholder",
190                online=False,
191                disable_chiron_and_lilith=self.disable_chiron_and_lilith,
192                zodiac_type=self.zodiac_type,
193                sidereal_mode=self.sidereal_mode,
194                houses_system_identifier=self.houses_system_identifier,
195                perspective_type=self.perspective_type,
196                is_dst=self.is_dst,
197            )
198
199            if as_model:
200                subjects_list.append(subject.model())
201            else:
202                subjects_list.append(subject)
203
204        return subjects_list

This class is used to generate ephemeris data for a given date range.

Parameters:

  • start_datetime: datetime object representing the start date and time.
  • end_datetime: datetime object representing the end date and time.
  • step_type: string representing the step type. It can be "days", "hours", or "minutes". Default is "days".
  • step: integer representing the step value. Default is 1.
  • lat: float representing the latitude. Default is 51.4769 (Greenwich).
  • lng: float representing the longitude. Default is 0.0005 (Greenwich).
  • tz_str: string representing the timezone. Default is "Etc/UTC".
  • is_dst: boolean representing if daylight saving time is active. Default is False.
  • disable_chiron_and_lilith: boolean representing if Chiron and Lilith should be disabled. Default is False.
  • zodiac_type: ZodiacType object representing the zodiac type. Default is DEFAULT_ZODIAC_TYPE.
  • sidereal_mode: SiderealMode object representing the sidereal mode. Default is None.
  • houses_system_identifier: HousesSystemIdentifier object representing the houses system identifier. Default is DEFAULT_HOUSES_SYSTEM_IDENTIFIER.
  • perspective_type: PerspectiveType object representing the perspective type. Default is DEFAULT_PERSPECTIVE_TYPE.
  • max_days: integer representing the maximum number of days. Set it to None to disable the check. Default is 730.
  • max_hours: integer representing the maximum number of hours. Set it to None to disable the check. Default is 8760.
  • max_minutes: integer representing the maximum number of minutes. Set it to None to disable the check. Default is 525600.

Raises:

  • ValueError: if the step type is invalid.
  • ValueError: if the number of days, hours, or minutes is greater than the maximum allowed.
EphemerisDataFactory( start_datetime: datetime.datetime, end_datetime: datetime.datetime, step_type: Literal['days', 'hours', 'minutes'] = 'days', step: int = 1, lat: float = 51.4769, lng: float = 0.0005, tz_str: str = 'Etc/UTC', is_dst: bool = False, disable_chiron_and_lilith: bool = False, zodiac_type: Literal['Tropic', 'Sidereal'] = 'Tropic', sidereal_mode: Optional[Literal['FAGAN_BRADLEY', 'LAHIRI', 'DELUCE', 'RAMAN', 'USHASHASHI', 'KRISHNAMURTI', 'DJWHAL_KHUL', 'YUKTESHWAR', 'JN_BHASIN', 'BABYL_KUGLER1', 'BABYL_KUGLER2', 'BABYL_KUGLER3', 'BABYL_HUBER', 'BABYL_ETPSC', 'ALDEBARAN_15TAU', 'HIPPARCHOS', 'SASSANIAN', 'J2000', 'J1900', 'B1950']] = None, houses_system_identifier: Literal['A', 'B', 'C', 'D', 'F', 'H', 'I', 'i', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y'] = 'P', perspective_type: Literal['Apparent Geocentric', 'Heliocentric', 'Topocentric', 'True Geocentric'] = 'Apparent Geocentric', max_days: Optional[int] = 730, max_hours: Optional[int] = 8760, max_minutes: Optional[int] = 525600)
 42    def __init__(
 43        self,
 44        start_datetime: datetime,
 45        end_datetime: datetime,
 46        step_type: Literal["days", "hours", "minutes"] = "days",
 47        step: int = 1,
 48        lat: float = 51.4769,
 49        lng: float = 0.0005,
 50        tz_str: str = "Etc/UTC",
 51        is_dst: bool = False,
 52        disable_chiron_and_lilith: bool = False,
 53        zodiac_type: ZodiacType = DEFAULT_ZODIAC_TYPE,
 54        sidereal_mode: Union[SiderealMode, None] = None,
 55        houses_system_identifier: HousesSystemIdentifier = DEFAULT_HOUSES_SYSTEM_IDENTIFIER,
 56        perspective_type: PerspectiveType = DEFAULT_PERSPECTIVE_TYPE,
 57        max_days: Union[int, None] = 730,
 58        max_hours: Union[int, None] = 8760,
 59        max_minutes: Union[int, None] = 525600,
 60    ):
 61        self.start_datetime = start_datetime
 62        self.end_datetime = end_datetime
 63        self.step_type = step_type
 64        self.step = step
 65        self.lat = lat
 66        self.lng = lng
 67        self.tz_str = tz_str
 68        self.is_dst = is_dst
 69        self.disable_chiron_and_lilith = disable_chiron_and_lilith
 70        self.zodiac_type = zodiac_type
 71        self.sidereal_mode = sidereal_mode
 72        self.houses_system_identifier = houses_system_identifier
 73        self.perspective_type = perspective_type
 74        self.max_days = max_days
 75        self.max_hours = max_hours
 76        self.max_minutes = max_minutes
 77
 78        self.dates_list = []
 79        if self.step_type == "days":
 80            self.dates_list = [self.start_datetime + timedelta(days=i * self.step) for i in range((self.end_datetime - self.start_datetime).days // self.step + 1)]
 81            if max_days and (len(self.dates_list) > max_days):
 82                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.")
 83
 84        elif self.step_type == "hours":
 85            hours_diff = (self.end_datetime - self.start_datetime).total_seconds() / 3600
 86            self.dates_list = [self.start_datetime + timedelta(hours=i * self.step) for i in range(int(hours_diff) // self.step + 1)]
 87            if max_hours and (len(self.dates_list) > max_hours):
 88                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.")
 89
 90        elif self.step_type == "minutes":
 91            minutes_diff = (self.end_datetime - self.start_datetime).total_seconds() / 60
 92            self.dates_list = [self.start_datetime + timedelta(minutes=i * self.step) for i in range(int(minutes_diff) // self.step + 1)]
 93            if max_minutes and (len(self.dates_list) > max_minutes):
 94                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.")
 95
 96        else:
 97            raise ValueError(f"Invalid step type: {self.step_type}")
 98
 99        if not self.dates_list:
100            raise ValueError("No dates found. Check the date range and step values.")
101
102        if len(self.dates_list) > 1000:
103            logging.warning(f"Large number of dates: {len(self.dates_list)}. The calculation may take a while.")
start_datetime
end_datetime
step_type
step
lat
lng
tz_str
is_dst
disable_chiron_and_lilith
zodiac_type
sidereal_mode
houses_system_identifier
perspective_type
max_days
max_hours
max_minutes
dates_list
def get_ephemeris_data(self, as_model: bool = False) -> list:
105    def get_ephemeris_data(self, as_model: bool = False) -> list:
106        """
107        Generate ephemeris data for the specified date range.
108        The data is structured as a list of dictionaries, where each dictionary contains the date, planets, and houses data.
109        Example:
110        [
111            {
112                "date": "2020-01-01T00:00:00",
113                "planets": [{...}, {...}, ...],
114                "houses": [{...}, {...}, ...]
115            },
116            ...
117        ]
118
119        Args:
120        - as_model (bool): If True, the ephemeris data will be returned as model instances. Default is False.
121
122        Returns:
123        - list: A list of dictionaries representing the ephemeris data. If as_model is True, a list of EphemerisDictModel instances is returned.
124        """
125        ephemeris_data_list = []
126        for date in self.dates_list:
127            subject = AstrologicalSubject(
128                year=date.year,
129                month=date.month,
130                day=date.day,
131                hour=date.hour,
132                minute=date.minute,
133                lng=self.lng,
134                lat=self.lat,
135                tz_str=self.tz_str,
136                city="Placeholder",
137                nation="Placeholder",
138                online=False,
139                disable_chiron_and_lilith=self.disable_chiron_and_lilith,
140                zodiac_type=self.zodiac_type,
141                sidereal_mode=self.sidereal_mode,
142                houses_system_identifier=self.houses_system_identifier,
143                perspective_type=self.perspective_type,
144                is_dst=self.is_dst,
145            )
146
147            houses_list = get_houses_list(subject)
148            available_planets = get_available_astrological_points_list(subject)
149
150            ephemeris_data_list.append({"date": date.isoformat(), "planets": available_planets, "houses": houses_list})
151
152        if as_model:
153            return [EphemerisDictModel(**data) for data in ephemeris_data_list]
154
155        return ephemeris_data_list

Generate ephemeris data for the specified date range. The data is structured as a list of dictionaries, where each dictionary contains the date, planets, and houses data. Example: [ { "date": "2020-01-01T00:00:00", "planets": [{...}, {...}, ...], "houses": [{...}, {...}, ...] }, ... ]

Args:

  • as_model (bool): If True, the ephemeris data will be returned as model instances. Default is False.

Returns:

  • list: A list of dictionaries representing the ephemeris data. If as_model is True, a list of EphemerisDictModel instances is returned.
def get_ephemeris_data_as_astrological_subjects( self, as_model: bool = False) -> List[kerykeion.astrological_subject.AstrologicalSubject]:
157    def get_ephemeris_data_as_astrological_subjects(self, as_model: bool = False) -> List[AstrologicalSubject]:
158        """
159        Generate ephemeris data for the specified date range as AstrologicalSubject instances.
160
161        This method creates a complete AstrologicalSubject object for each date in the date range,
162        allowing direct access to all properties and methods of the AstrologicalSubject class.
163
164        Args:
165        - as_model (bool): If True, the AstrologicalSubject instances will be returned as model instances. Default is False.
166
167        Returns:
168        - List[AstrologicalSubject]: A list of AstrologicalSubject instances, one for each date in the date range.
169
170        Example usage:
171            subjects = factory.get_ephemeris_data_as_astrological_subjects()
172            # Access methods and properties of the first subject
173            sun_position = subjects[0].get_sun()
174            all_points = subjects[0].get_all_points()
175            chart_drawing = subjects[0].draw_chart()
176        """
177        subjects_list = []
178        for date in self.dates_list:
179            subject = AstrologicalSubject(
180                year=date.year,
181                month=date.month,
182                day=date.day,
183                hour=date.hour,
184                minute=date.minute,
185                lng=self.lng,
186                lat=self.lat,
187                tz_str=self.tz_str,
188                city="Placeholder",
189                nation="Placeholder",
190                online=False,
191                disable_chiron_and_lilith=self.disable_chiron_and_lilith,
192                zodiac_type=self.zodiac_type,
193                sidereal_mode=self.sidereal_mode,
194                houses_system_identifier=self.houses_system_identifier,
195                perspective_type=self.perspective_type,
196                is_dst=self.is_dst,
197            )
198
199            if as_model:
200                subjects_list.append(subject.model())
201            else:
202                subjects_list.append(subject)
203
204        return subjects_list

Generate ephemeris data for the specified date range as AstrologicalSubject instances.

This method creates a complete AstrologicalSubject object for each date in the date range, allowing direct access to all properties and methods of the AstrologicalSubject class.

Args:

  • as_model (bool): If True, the AstrologicalSubject instances will be returned as model instances. Default is False.

Returns:

  • List[AstrologicalSubject]: A list of AstrologicalSubject instances, one for each date in the date range.

Example usage: subjects = factory.get_ephemeris_data_as_astrological_subjects() # Access methods and properties of the first subject sun_position = subjects[0].get_sun() all_points = subjects[0].get_all_points() chart_drawing = subjects[0].draw_chart()