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
  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) for i in range((self.end_datetime - self.start_datetime).days)]
 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            self.dates_list = [self.start_datetime + timedelta(hours=i) for i in range((self.end_datetime - self.start_datetime).days * 24)]
 85            if max_hours and (len(self.dates_list) > max_hours):
 86                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.")
 87
 88        elif self.step_type == "minutes":
 89            self.dates_list = [self.start_datetime + timedelta(minutes=i) for i in range((self.end_datetime - self.start_datetime).days * 24 * 60)]
 90            if max_minutes and (len(self.dates_list) > max_minutes):
 91                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.")
 92
 93        else:
 94            raise ValueError(f"Invalid step type: {self.step_type}")
 95
 96        if not self.dates_list:
 97            raise ValueError("No dates found. Check the date range and step values.")
 98
 99        if len(self.dates_list) > 1000:
100            logging.warning(f"Large number of dates: {len(self.dates_list)}. The calculation may take a while.")
101
102    def get_ephemeris_data(self, as_model: bool = False) -> list:
103        """
104        Generate ephemeris data for the specified date range.
105        The data is structured as a list of dictionaries, where each dictionary contains the date, planets, and houses data.
106        Example:
107        [
108            {
109                "date": "2020-01-01T00:00:00",
110                "planets": [{...}, {...}, ...],
111                "houses": [{...}, {...}, ...]
112            },
113            ...
114        ]
115
116        Args:
117        - as_model (bool): If True, the ephemeris data will be returned as model instances. Default is False.
118
119        Returns:
120        - list: A list of dictionaries representing the ephemeris data. If as_model is True, a list of EphemerisDictModel instances is returned.
121        """
122        ephemeris_data_list = []
123        for date in self.dates_list:
124            subject = AstrologicalSubject(
125                year=date.year,
126                month=date.month,
127                day=date.day,
128                hour=date.hour,
129                minute=date.minute,
130                lng=self.lng,
131                lat=self.lat,
132                tz_str=self.tz_str,
133                city="Placeholder",
134                nation="Placeholder",
135                online=False,
136                disable_chiron_and_lilith=self.disable_chiron_and_lilith,
137                zodiac_type=self.zodiac_type,
138                sidereal_mode=self.sidereal_mode,
139                houses_system_identifier=self.houses_system_identifier,
140                perspective_type=self.perspective_type,
141                is_dst=self.is_dst,
142            )
143
144            houses_list = get_houses_list(subject)
145            available_planets = get_available_astrological_points_list(subject)
146
147            ephemeris_data_list.append({"date": date.isoformat(), "planets": available_planets, "houses": houses_list})
148
149        if as_model:
150            return [EphemerisDictModel(**data) for data in ephemeris_data_list]
151
152        return ephemeris_data_list
153
154
155if "__main__" == __name__:
156    start_date = datetime.fromisoformat("2020-01-01")
157    end_date = datetime.fromisoformat("2020-01-03")
158
159    factory = EphemerisDataFactory(
160        start_datetime=start_date,
161        end_datetime=end_date,
162        step_type="minutes",
163        step=1,
164        lat=37.9838,
165        lng=23.7275,
166        tz_str="Europe/Athens",
167        is_dst=False,
168        max_hours=None,
169        max_minutes=None,
170        max_days=None,
171    )
172
173    ephemeris_data = factory.get_ephemeris_data(as_model=True)
174    print(ephemeris_data[0])
175    print(len(ephemeris_data))
176
177    for ephe in ephemeris_data:
178        print(ephe.planets[0]["abs_pos"])
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) for i in range((self.end_datetime - self.start_datetime).days)]
 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            self.dates_list = [self.start_datetime + timedelta(hours=i) for i in range((self.end_datetime - self.start_datetime).days * 24)]
 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            self.dates_list = [self.start_datetime + timedelta(minutes=i) for i in range((self.end_datetime - self.start_datetime).days * 24 * 60)]
 91            if max_minutes and (len(self.dates_list) > max_minutes):
 92                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.")
 93
 94        else:
 95            raise ValueError(f"Invalid step type: {self.step_type}")
 96
 97        if not self.dates_list:
 98            raise ValueError("No dates found. Check the date range and step values.")
 99
100        if len(self.dates_list) > 1000:
101            logging.warning(f"Large number of dates: {len(self.dates_list)}. The calculation may take a while.")
102
103    def get_ephemeris_data(self, as_model: bool = False) -> list:
104        """
105        Generate ephemeris data for the specified date range.
106        The data is structured as a list of dictionaries, where each dictionary contains the date, planets, and houses data.
107        Example:
108        [
109            {
110                "date": "2020-01-01T00:00:00",
111                "planets": [{...}, {...}, ...],
112                "houses": [{...}, {...}, ...]
113            },
114            ...
115        ]
116
117        Args:
118        - as_model (bool): If True, the ephemeris data will be returned as model instances. Default is False.
119
120        Returns:
121        - list: A list of dictionaries representing the ephemeris data. If as_model is True, a list of EphemerisDictModel instances is returned.
122        """
123        ephemeris_data_list = []
124        for date in self.dates_list:
125            subject = AstrologicalSubject(
126                year=date.year,
127                month=date.month,
128                day=date.day,
129                hour=date.hour,
130                minute=date.minute,
131                lng=self.lng,
132                lat=self.lat,
133                tz_str=self.tz_str,
134                city="Placeholder",
135                nation="Placeholder",
136                online=False,
137                disable_chiron_and_lilith=self.disable_chiron_and_lilith,
138                zodiac_type=self.zodiac_type,
139                sidereal_mode=self.sidereal_mode,
140                houses_system_identifier=self.houses_system_identifier,
141                perspective_type=self.perspective_type,
142                is_dst=self.is_dst,
143            )
144
145            houses_list = get_houses_list(subject)
146            available_planets = get_available_astrological_points_list(subject)
147
148            ephemeris_data_list.append({"date": date.isoformat(), "planets": available_planets, "houses": houses_list})
149
150        if as_model:
151            return [EphemerisDictModel(**data) for data in ephemeris_data_list]
152
153        return ephemeris_data_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) for i in range((self.end_datetime - self.start_datetime).days)]
 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            self.dates_list = [self.start_datetime + timedelta(hours=i) for i in range((self.end_datetime - self.start_datetime).days * 24)]
 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            self.dates_list = [self.start_datetime + timedelta(minutes=i) for i in range((self.end_datetime - self.start_datetime).days * 24 * 60)]
 91            if max_minutes and (len(self.dates_list) > max_minutes):
 92                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.")
 93
 94        else:
 95            raise ValueError(f"Invalid step type: {self.step_type}")
 96
 97        if not self.dates_list:
 98            raise ValueError("No dates found. Check the date range and step values.")
 99
100        if len(self.dates_list) > 1000:
101            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:
103    def get_ephemeris_data(self, as_model: bool = False) -> list:
104        """
105        Generate ephemeris data for the specified date range.
106        The data is structured as a list of dictionaries, where each dictionary contains the date, planets, and houses data.
107        Example:
108        [
109            {
110                "date": "2020-01-01T00:00:00",
111                "planets": [{...}, {...}, ...],
112                "houses": [{...}, {...}, ...]
113            },
114            ...
115        ]
116
117        Args:
118        - as_model (bool): If True, the ephemeris data will be returned as model instances. Default is False.
119
120        Returns:
121        - list: A list of dictionaries representing the ephemeris data. If as_model is True, a list of EphemerisDictModel instances is returned.
122        """
123        ephemeris_data_list = []
124        for date in self.dates_list:
125            subject = AstrologicalSubject(
126                year=date.year,
127                month=date.month,
128                day=date.day,
129                hour=date.hour,
130                minute=date.minute,
131                lng=self.lng,
132                lat=self.lat,
133                tz_str=self.tz_str,
134                city="Placeholder",
135                nation="Placeholder",
136                online=False,
137                disable_chiron_and_lilith=self.disable_chiron_and_lilith,
138                zodiac_type=self.zodiac_type,
139                sidereal_mode=self.sidereal_mode,
140                houses_system_identifier=self.houses_system_identifier,
141                perspective_type=self.perspective_type,
142                is_dst=self.is_dst,
143            )
144
145            houses_list = get_houses_list(subject)
146            available_planets = get_available_astrological_points_list(subject)
147
148            ephemeris_data_list.append({"date": date.isoformat(), "planets": available_planets, "houses": houses_list})
149
150        if as_model:
151            return [EphemerisDictModel(**data) for data in ephemeris_data_list]
152
153        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.