kerykeion 5.0.0a10__py3-none-any.whl → 5.0.0a11__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.

@@ -1,10 +1,71 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- Module for generating Planetary Return charts using the Swiss Ephemeris.
4
-
5
- This module provides the PlanetaryReturnFactory class, which computes
6
- the return times and chart data for solar and lunar returns of a natal
7
- astrological subject.
3
+ Planetary Return Factory Module
4
+
5
+ This module provides the PlanetaryReturnFactory class for calculating and generating
6
+ comprehensive planetary return charts, specifically Solar and Lunar returns. It leverages
7
+ the Swiss Ephemeris library for precise astronomical calculations to determine exact
8
+ return moments and create complete astrological chart data.
9
+
10
+ Key Features:
11
+ - Solar Return calculations (Sun's annual return to natal position)
12
+ - Lunar Return calculations (Moon's monthly return to natal position)
13
+ - Multiple date input formats (ISO datetime, year-based, month/year-based)
14
+ - Flexible location handling (online geocoding or manual coordinates)
15
+ - Complete astrological chart generation for return moments
16
+ - Integration with Geonames service for location data
17
+ - Timezone-aware calculations with UTC precision
18
+
19
+ A planetary return occurs when a planet returns to the exact degree and minute
20
+ it occupied at the time of birth. Solar returns happen approximately once per year
21
+ and are widely used for annual forecasting, while Lunar returns occur roughly
22
+ every 27-29 days and are used for monthly analysis and timing.
23
+
24
+ The factory creates complete AstrologicalSubject instances for the calculated
25
+ return moments, enabling full chart analysis including planetary positions,
26
+ aspects, house cusps, and all other astrological features.
27
+
28
+ Classes:
29
+ PlanetaryReturnFactory: Main factory class for calculating planetary returns
30
+
31
+ Dependencies:
32
+ - swisseph: Swiss Ephemeris library for astronomical calculations
33
+ - kerykeion.AstrologicalSubjectFactory: For creating complete chart data
34
+ - kerykeion.fetch_geonames: For online location data retrieval
35
+ - kerykeion.utilities: For date/time conversions and astronomical functions
36
+ - kerykeion.kr_types: For type definitions and model structures
37
+
38
+ Example:
39
+ Basic Solar Return calculation for a specific year:
40
+
41
+ >>> from kerykeion import AstrologicalSubjectFactory
42
+ >>> from kerykeion.planetary_return_factory import PlanetaryReturnFactory
43
+ >>>
44
+ >>> # Create natal chart
45
+ >>> subject = AstrologicalSubjectFactory.from_birth_data(
46
+ ... name="John Doe",
47
+ ... year=1990, month=6, day=15,
48
+ ... hour=12, minute=30,
49
+ ... lat=40.7128, lng=-74.0060,
50
+ ... tz_str="America/New_York"
51
+ ... )
52
+ >>>
53
+ >>> # Create return calculator for New York location
54
+ >>> calculator = PlanetaryReturnFactory(
55
+ ... subject,
56
+ ... city="New York",
57
+ ... nation="US",
58
+ ... online=True
59
+ ... )
60
+ >>>
61
+ >>> # Calculate Solar Return for 2024
62
+ >>> solar_return = calculator.next_return_from_year(2024, "Solar")
63
+ >>> print(f"Solar Return: {solar_return.iso_formatted_local_datetime}")
64
+ >>> print(f"Sun position: {solar_return.sun.abs_pos}°")
65
+
66
+ Author: Giacomo Battaglia
67
+ Copyright: (C) 2025 Kerykeion Project
68
+ License: AGPL-3.0
8
69
  """
9
70
  import logging
10
71
  import swisseph as swe
@@ -27,7 +88,119 @@ from kerykeion.kr_types.kr_models import PlanetReturnModel, AstrologicalSubjectM
27
88
 
28
89
  class PlanetaryReturnFactory:
29
90
  """
30
- Calculator class to generate Solar and Lunar Return charts.
91
+ A factory class for calculating and generating planetary return charts.
92
+
93
+ This class specializes in computing precise planetary return moments using the Swiss
94
+ Ephemeris library and creating complete astrological charts for those calculated times.
95
+ It supports both Solar Returns (annual) and Lunar Returns (monthly), providing
96
+ comprehensive astrological analysis capabilities for timing and forecasting applications.
97
+
98
+ Planetary returns are fundamental concepts in predictive astrology:
99
+ - Solar Returns: Occur when the Sun returns to its exact natal position (~365.25 days)
100
+ - Lunar Returns: Occur when the Moon returns to its exact natal position (~27-29 days)
101
+
102
+ The factory handles complex astronomical calculations automatically, including:
103
+ - Precise celestial mechanics computations
104
+ - Timezone conversions and UTC coordination
105
+ - Location-based calculations for return chart casting
106
+ - Integration with online geocoding services
107
+ - Complete chart generation with all astrological points
108
+
109
+ Args:
110
+ subject (AstrologicalSubjectModel): The natal astrological subject for whom
111
+ returns are calculated. Must contain complete birth data including
112
+ planetary positions at birth.
113
+ city (Optional[str]): City name for return chart location. Required when
114
+ using online mode for location data retrieval.
115
+ nation (Optional[str]): Nation/country code for return chart location.
116
+ Required when using online mode (e.g., "US", "GB", "FR").
117
+ lng (Optional[Union[int, float]]): Geographic longitude in decimal degrees
118
+ for return chart location. Positive values for East, negative for West.
119
+ Required when using offline mode.
120
+ lat (Optional[Union[int, float]]): Geographic latitude in decimal degrees
121
+ for return chart location. Positive values for North, negative for South.
122
+ Required when using offline mode.
123
+ tz_str (Optional[str]): Timezone identifier for return chart location
124
+ (e.g., "America/New_York", "Europe/London", "Asia/Tokyo").
125
+ Required when using offline mode.
126
+ online (bool, optional): Whether to fetch location data online via Geonames
127
+ service. When True, requires city, nation, and geonames_username.
128
+ When False, requires lng, lat, and tz_str. Defaults to True.
129
+ geonames_username (Optional[str]): Username for Geonames API access.
130
+ Required when online=True and coordinates are not provided.
131
+ Register at http://www.geonames.org/login for free account.
132
+ cache_expire_after_days (int, optional): Number of days to cache Geonames
133
+ location data before refreshing. Defaults to system setting.
134
+ altitude (Optional[Union[float, int]]): Elevation above sea level in meters
135
+ for the return chart location. Reserved for future astronomical
136
+ calculations. Defaults to None.
137
+
138
+ Raises:
139
+ KerykeionException: If required location parameters are missing for the
140
+ chosen mode (online/offline).
141
+ KerykeionException: If Geonames API fails to retrieve location data.
142
+ KerykeionException: If online mode is used without proper API credentials.
143
+
144
+ Attributes:
145
+ subject (AstrologicalSubjectModel): The natal subject for calculations.
146
+ city (Optional[str]): Return chart city name.
147
+ nation (Optional[str]): Return chart nation code.
148
+ lng (float): Return chart longitude coordinate.
149
+ lat (float): Return chart latitude coordinate.
150
+ tz_str (str): Return chart timezone identifier.
151
+ online (bool): Location data retrieval mode.
152
+ city_data (Optional[dict]): Cached location data from Geonames.
153
+
154
+ Examples:
155
+ Online mode with automatic location lookup:
156
+
157
+ >>> subject = AstrologicalSubjectFactory.from_birth_data(
158
+ ... name="Alice", year=1985, month=3, day=21,
159
+ ... hour=14, minute=30, lat=51.5074, lng=-0.1278,
160
+ ... tz_str="Europe/London"
161
+ ... )
162
+ >>> factory = PlanetaryReturnFactory(
163
+ ... subject,
164
+ ... city="London",
165
+ ... nation="GB",
166
+ ... online=True,
167
+ ... geonames_username="your_username"
168
+ ... )
169
+
170
+ Offline mode with manual coordinates:
171
+
172
+ >>> factory = PlanetaryReturnFactory(
173
+ ... subject,
174
+ ... lng=-74.0060,
175
+ ... lat=40.7128,
176
+ ... tz_str="America/New_York",
177
+ ... online=False
178
+ ... )
179
+
180
+ Different location for return chart:
181
+
182
+ >>> # Calculate return as if living in a different city
183
+ >>> factory = PlanetaryReturnFactory(
184
+ ... natal_subject, # Born in London
185
+ ... city="Paris", # But living in Paris
186
+ ... nation="FR",
187
+ ... online=True
188
+ ... )
189
+
190
+ Use Cases:
191
+ - Annual Solar Return charts for yearly forecasting
192
+ - Monthly Lunar Return charts for timing analysis
193
+ - Relocation returns for different geographic locations
194
+ - Research into planetary cycle effects
195
+ - Astrological consultation and chart analysis
196
+ - Educational demonstrations of celestial mechanics
197
+
198
+ Note:
199
+ Return calculations use the exact degree and minute of natal planetary
200
+ positions. The resulting charts are cast for the precise moment when
201
+ the transiting planet reaches this position, which may not align with
202
+ calendar dates (especially for Solar Returns, which can occur on
203
+ different dates depending on leap years and location).
31
204
  """
32
205
 
33
206
  def __init__(
@@ -46,19 +219,99 @@ class PlanetaryReturnFactory:
46
219
  ):
47
220
 
48
221
  """
49
- Initialize a PlanetaryReturnFactory instance.
222
+ Initialize a PlanetaryReturnFactory instance with location and configuration settings.
223
+
224
+ This constructor sets up the factory with all necessary parameters for calculating
225
+ planetary returns at a specified location. It supports both online mode (with
226
+ automatic geocoding via Geonames) and offline mode (with manual coordinates).
227
+
228
+ The factory validates input parameters based on the chosen mode and automatically
229
+ retrieves missing location data when operating online. All location parameters
230
+ are stored and used for casting return charts at the exact calculated moments.
50
231
 
51
232
  Args:
52
- subject (AstrologicalSubject): The natal astrological subject.
53
- city (Optional[str]): City name for return location (online mode).
54
- nation (Optional[str]): Nation code for return location (online mode).
55
- lng (Optional[Union[int, float]]): Longitude for return location.
56
- lat (Optional[Union[int, float]]): Latitude for return location.
57
- tz_str (Optional[str]): Timezone string for return location.
58
- online (bool): Whether to fetch location data online via Geonames.
59
- geonames_username (Optional[str]): Username for Geonames API.
60
- cache_expire_after_days (int): Days to expire Geonames cache.
61
- altitude (Optional[float]): Altitude of the location (reserved for future use).
233
+ subject (AstrologicalSubjectModel): The natal astrological subject containing
234
+ birth data and planetary positions. This subject's natal planetary
235
+ positions serve as reference points for calculating returns.
236
+ city (Optional[str]): City name for the return chart location. Must be a
237
+ recognizable city name for Geonames geocoding when using online mode.
238
+ Examples: "New York", "London", "Tokyo", "Paris".
239
+ nation (Optional[str]): Country or nation code for the return chart location.
240
+ Use ISO country codes for best results (e.g., "US", "GB", "JP", "FR").
241
+ Required when online=True.
242
+ lng (Optional[Union[int, float]]): Geographic longitude coordinate in decimal
243
+ degrees for return chart location. Range: -180.0 to +180.0.
244
+ Positive values represent East longitude, negative values West longitude.
245
+ Required when online=False.
246
+ lat (Optional[Union[int, float]]): Geographic latitude coordinate in decimal
247
+ degrees for return chart location. Range: -90.0 to +90.0.
248
+ Positive values represent North latitude, negative values South latitude.
249
+ Required when online=False.
250
+ tz_str (Optional[str]): Timezone identifier string for return chart location.
251
+ Must be a valid timezone from the IANA Time Zone Database
252
+ (e.g., "America/New_York", "Europe/London", "Asia/Tokyo").
253
+ Required when online=False.
254
+ online (bool, optional): Location data retrieval mode. When True, uses
255
+ Geonames web service to automatically fetch coordinates and timezone
256
+ from city/nation parameters. When False, uses manually provided
257
+ coordinates and timezone. Defaults to True.
258
+ geonames_username (Optional[str]): Username for Geonames API access.
259
+ Required when online=True and coordinates are not manually provided.
260
+ Free accounts available at http://www.geonames.org/login.
261
+ If None and required, uses default username with warning.
262
+ cache_expire_after_days (int, optional): Number of days to cache Geonames
263
+ location data locally before requiring refresh. Helps reduce API
264
+ calls and improve performance for repeated calculations.
265
+ Defaults to system configuration value.
266
+ altitude (Optional[Union[float, int]]): Elevation above sea level in meters
267
+ for the return chart location. Currently reserved for future use in
268
+ advanced astronomical calculations. Defaults to None.
269
+
270
+ Raises:
271
+ KerykeionException: If city is not provided when online=True.
272
+ KerykeionException: If nation is not provided when online=True.
273
+ KerykeionException: If coordinates (lat/lng) are not provided when online=False.
274
+ KerykeionException: If timezone (tz_str) is not provided when online=False.
275
+ KerykeionException: If Geonames API fails to retrieve valid location data.
276
+ KerykeionException: If required parameters are missing for the chosen mode.
277
+
278
+ Examples:
279
+ Initialize with online geocoding:
280
+
281
+ >>> factory = PlanetaryReturnFactory(
282
+ ... subject,
283
+ ... city="San Francisco",
284
+ ... nation="US",
285
+ ... online=True,
286
+ ... geonames_username="your_username"
287
+ ... )
288
+
289
+ Initialize with manual coordinates:
290
+
291
+ >>> factory = PlanetaryReturnFactory(
292
+ ... subject,
293
+ ... lng=-122.4194,
294
+ ... lat=37.7749,
295
+ ... tz_str="America/Los_Angeles",
296
+ ... online=False
297
+ ... )
298
+
299
+ Initialize with mixed parameters (coordinates override online lookup):
300
+
301
+ >>> factory = PlanetaryReturnFactory(
302
+ ... subject,
303
+ ... city="Custom Location",
304
+ ... lng=-74.0060,
305
+ ... lat=40.7128,
306
+ ... tz_str="America/New_York",
307
+ ... online=False
308
+ ... )
309
+
310
+ Note:
311
+ - When both online and manual coordinates are provided, offline mode takes precedence
312
+ - Geonames cache helps reduce API calls for frequently used locations
313
+ - Timezone accuracy is crucial for precise return calculations
314
+ - Location parameters affect house cusps and angular positions in return charts
62
315
  """
63
316
  # Store basic configuration
64
317
  self.subject = subject
@@ -137,13 +390,95 @@ class PlanetaryReturnFactory:
137
390
  return_type: ReturnType
138
391
  ) -> PlanetReturnModel:
139
392
  """
140
- Get the next Return for the provided ISO-formatted time.
393
+ Calculate the next planetary return occurring after a specified ISO-formatted datetime.
394
+
395
+ This method computes the exact moment when the specified planet (Sun or Moon) returns
396
+ to its natal position, starting the search from the provided datetime. It uses precise
397
+ Swiss Ephemeris calculations to determine the exact return moment and generates a
398
+ complete astrological chart for that calculated time.
399
+
400
+ The calculation process:
401
+ 1. Converts the ISO datetime to Julian Day format for astronomical calculations
402
+ 2. Uses Swiss Ephemeris functions (solcross_ut/mooncross_ut) to find the exact
403
+ return moment when the planet reaches its natal degree and minute
404
+ 3. Creates a complete AstrologicalSubject instance for the calculated return time
405
+ 4. Returns a comprehensive PlanetReturnModel with all chart data
141
406
 
142
407
  Args:
143
- iso_formatted_time (str): ISO-formatted datetime string.
408
+ iso_formatted_time (str): Starting datetime in ISO format for the search.
409
+ Must be a valid ISO 8601 datetime string (e.g., "2024-01-15T10:30:00"
410
+ or "2024-01-15T10:30:00+00:00"). The method will find the next return
411
+ occurring after this moment.
412
+ return_type (ReturnType): Type of planetary return to calculate.
413
+ Must be either "Solar" for Sun returns or "Lunar" for Moon returns.
414
+ This determines which planet's return cycle to compute.
144
415
 
145
416
  Returns:
146
- PlanetReturnModel: Pydantic model containing the return chart data.
417
+ PlanetReturnModel: A comprehensive Pydantic model containing complete
418
+ astrological chart data for the calculated return moment, including:
419
+ - Exact return datetime (UTC and local timezone)
420
+ - All planetary positions at the return moment
421
+ - House cusps and angles for the return location
422
+ - Complete astrological subject data with all calculated points
423
+ - Return type identifier and subject name
424
+ - Julian Day Number for the return moment
425
+
426
+ Raises:
427
+ KerykeionException: If return_type is not "Solar" or "Lunar".
428
+ ValueError: If iso_formatted_time is not a valid ISO datetime format.
429
+ SwissEphException: If Swiss Ephemeris calculations fail due to invalid
430
+ date ranges or astronomical calculation errors.
431
+
432
+ Examples:
433
+ Calculate next Solar Return after a specific date:
434
+
435
+ >>> factory = PlanetaryReturnFactory(subject, ...)
436
+ >>> solar_return = factory.next_return_from_iso_formatted_time(
437
+ ... "2024-06-15T12:00:00",
438
+ ... "Solar"
439
+ ... )
440
+ >>> print(f"Solar Return: {solar_return.iso_formatted_local_datetime}")
441
+ >>> print(f"Sun position: {solar_return.sun.abs_pos}°")
442
+
443
+ Calculate next Lunar Return with timezone:
444
+
445
+ >>> lunar_return = factory.next_return_from_iso_formatted_time(
446
+ ... "2024-01-01T00:00:00+00:00",
447
+ ... "Lunar"
448
+ ... )
449
+ >>> print(f"Moon return in {lunar_return.tz_str}")
450
+ >>> print(f"Return occurs: {lunar_return.iso_formatted_local_datetime}")
451
+
452
+ Access complete chart data from return:
453
+
454
+ >>> return_chart = factory.next_return_from_iso_formatted_time(
455
+ ... datetime.now().isoformat(),
456
+ ... "Solar"
457
+ ... )
458
+ >>> # Access all planetary positions
459
+ >>> for planet in return_chart.planets_list:
460
+ ... print(f"{planet.name}: {planet.abs_pos}° in {planet.sign}")
461
+ >>> # Access house cusps
462
+ >>> for house in return_chart.houses_list:
463
+ ... print(f"House {house.number}: {house.abs_pos}°")
464
+
465
+ Technical Notes:
466
+ - Solar returns typically occur within 1-2 days of the natal birthday
467
+ - Lunar returns occur approximately every 27.3 days (sidereal month)
468
+ - Return moments are calculated to the second for maximum precision
469
+ - The method accounts for leap years and varying orbital speeds
470
+ - Return charts use the factory's configured location, not the natal location
471
+
472
+ Use Cases:
473
+ - Annual birthday return chart calculations
474
+ - Monthly lunar return timing for astrological consultation
475
+ - Research into planetary cycle patterns and timing
476
+ - Forecasting and predictive astrology applications
477
+ - Educational demonstrations of astronomical cycles
478
+
479
+ See Also:
480
+ next_return_from_year(): Simplified interface for yearly calculations
481
+ next_return_from_month_and_year(): Monthly calculation interface
147
482
  """
148
483
 
149
484
  date = datetime.fromisoformat(iso_formatted_time)
@@ -193,16 +528,84 @@ class PlanetaryReturnFactory:
193
528
  return_type: ReturnType
194
529
  ) -> PlanetReturnModel:
195
530
  """
196
- Get the next Return for the specified year.
531
+ Calculate the planetary return occurring within a specified year.
532
+
533
+ This is a convenience method that finds the first planetary return (Solar or Lunar)
534
+ that occurs in the given calendar year. It automatically searches from January 1st
535
+ of the specified year and returns the first return found, making it ideal for
536
+ annual forecasting and birthday return calculations.
197
537
 
198
- This method finds the first return that occurs in the given year.
538
+ For Solar Returns, this typically finds the return closest to the natal birthday
539
+ within that year. For Lunar Returns, it finds the first lunar return occurring
540
+ in January of the specified year.
541
+
542
+ The method internally uses next_return_from_iso_formatted_time() with a starting
543
+ point of January 1st at midnight UTC for the specified year.
199
544
 
200
545
  Args:
201
- year (int): The year to search for the return
202
- return_type (ReturnType): The type of return ("Solar" or "Lunar")
546
+ year (int): The calendar year to search for the return. Must be a valid
547
+ year (typically between 1800-2200 for reliable ephemeris data).
548
+ Examples: 2024, 2025, 1990, 2050.
549
+ return_type (ReturnType): The type of planetary return to calculate.
550
+ Must be either "Solar" for Sun returns or "Lunar" for Moon returns.
203
551
 
204
552
  Returns:
205
- PlanetReturnModel: Pydantic model containing the return chart data
553
+ PlanetReturnModel: A comprehensive model containing the return chart data
554
+ for the first return found in the specified year. Includes:
555
+ - Exact return datetime in both UTC and local timezone
556
+ - Complete planetary positions at the return moment
557
+ - House cusps calculated for the factory's configured location
558
+ - All astrological chart features and calculated points
559
+ - Return type and subject identification
560
+
561
+ Raises:
562
+ KerykeionException: If return_type is not "Solar" or "Lunar".
563
+ ValueError: If year is outside the valid range for ephemeris calculations.
564
+ SwissEphException: If astronomical calculations fail for the given year.
565
+
566
+ Examples:
567
+ Calculate Solar Return for 2024:
568
+
569
+ >>> factory = PlanetaryReturnFactory(subject, ...)
570
+ >>> solar_return_2024 = factory.next_return_from_year(2024, "Solar")
571
+ >>> print(f"2024 Solar Return: {solar_return_2024.iso_formatted_local_datetime}")
572
+ >>> print(f"Birthday location: {solar_return_2024.city}, {solar_return_2024.nation}")
573
+
574
+ Calculate first Lunar Return of 2025:
575
+
576
+ >>> lunar_return = factory.next_return_from_year(2025, "Lunar")
577
+ >>> print(f"First 2025 Lunar Return: {lunar_return.iso_formatted_local_datetime}")
578
+
579
+ Compare multiple years:
580
+
581
+ >>> for year in [2023, 2024, 2025]:
582
+ ... solar_return = factory.next_return_from_year(year, "Solar")
583
+ ... print(f"{year}: {solar_return.iso_formatted_local_datetime}")
584
+
585
+ Practical Applications:
586
+ - Annual Solar Return chart casting for birthday forecasting
587
+ - Comparative analysis of return charts across multiple years
588
+ - Research into planetary return timing patterns
589
+ - Automated birthday return calculations for consultation
590
+ - Educational demonstrations of annual astrological cycles
591
+
592
+ Technical Notes:
593
+ - Solar returns in a given year occur near but not exactly on the birthday
594
+ - The exact date can vary by 1-2 days due to leap years and orbital mechanics
595
+ - Lunar returns occur approximately every 27.3 days throughout the year
596
+ - This method finds the chronologically first return in the year
597
+ - Return moment precision is calculated to the second
598
+
599
+ Use Cases:
600
+ - Birthday return chart interpretation
601
+ - Annual astrological forecasting
602
+ - Timing analysis for major life events
603
+ - Comparative return chart studies
604
+ - Astrological consultation preparation
605
+
606
+ See Also:
607
+ next_return_from_month_and_year(): For more specific monthly searches
608
+ next_return_from_iso_formatted_time(): For custom starting dates
206
609
  """
207
610
  # Create datetime for January 1st of the specified year (UTC)
208
611
  start_date = datetime(year, 1, 1, 0, 0, tzinfo=timezone.utc)
@@ -220,18 +623,115 @@ class PlanetaryReturnFactory:
220
623
  return_type: ReturnType
221
624
  ) -> PlanetReturnModel:
222
625
  """
223
- Get the next Return for the specified month and year.
626
+ Calculate the first planetary return occurring in or after a specified month and year.
627
+
628
+ This method provides precise timing control for planetary return calculations by
629
+ searching from the first day of a specific month and year. It's particularly
630
+ useful for finding Lunar Returns in specific months or for Solar Return timing
631
+ when you need to focus on a particular time period within a year.
224
632
 
225
- This method finds the first return that occurs after the first day
226
- of the specified month and year.
633
+ The method searches from the first moment (00:00:00 UTC) of the specified month
634
+ and year, finding the next return that occurs from that point forward. This is
635
+ especially valuable for Lunar Return work, where multiple returns occur per year
636
+ and you need to isolate specific monthly periods.
227
637
 
228
638
  Args:
229
- year (int): The year to search for the return
230
- month (int): The month to search for the return (1-12)
231
- return_type (ReturnType): The type of return ("Solar" or "Lunar")
639
+ year (int): The calendar year to search within. Must be a valid year
640
+ within the ephemeris data range (typically 1800-2200).
641
+ Examples: 2024, 2025, 1990.
642
+ month (int): The month to start the search from. Must be between 1 and 12,
643
+ where 1=January, 2=February, ..., 12=December.
644
+ return_type (ReturnType): The type of planetary return to calculate.
645
+ Must be either "Solar" for Sun returns or "Lunar" for Moon returns.
232
646
 
233
647
  Returns:
234
- PlanetReturnModel: Pydantic model containing the return chart data
648
+ PlanetReturnModel: Comprehensive return chart data for the first return
649
+ found on or after the first day of the specified month and year.
650
+ Contains complete astrological chart information including:
651
+ - Precise return datetime in UTC and local timezone
652
+ - All planetary positions at the return moment
653
+ - House cusps for the factory's configured location
654
+ - Complete astrological subject data with all calculated features
655
+ - Return type identifier and naming information
656
+
657
+ Raises:
658
+ KerykeionException: If month is not between 1 and 12.
659
+ KerykeionException: If return_type is not "Solar" or "Lunar".
660
+ ValueError: If year is outside valid ephemeris calculation range.
661
+ SwissEphException: If astronomical calculations fail.
662
+
663
+ Examples:
664
+ Find Solar Return in birth month:
665
+
666
+ >>> factory = PlanetaryReturnFactory(subject, ...)
667
+ >>> # Subject born in June, find 2024 Solar Return in June
668
+ >>> solar_return = factory.next_return_from_month_and_year(
669
+ ... 2024, 6, "Solar"
670
+ ... )
671
+ >>> print(f"Solar Return: {solar_return.iso_formatted_local_datetime}")
672
+
673
+ Find specific Lunar Return:
674
+
675
+ >>> # Find first Lunar Return in March 2024
676
+ >>> lunar_return = factory.next_return_from_month_and_year(
677
+ ... 2024, 3, "Lunar"
678
+ ... )
679
+ >>> print(f"March 2024 Lunar Return: {lunar_return.iso_formatted_local_datetime}")
680
+
681
+ Monthly Lunar Return tracking:
682
+
683
+ >>> lunar_returns_2024 = []
684
+ >>> for month in range(1, 13):
685
+ ... lunar_return = factory.next_return_from_month_and_year(
686
+ ... 2024, month, "Lunar"
687
+ ... )
688
+ ... lunar_returns_2024.append(lunar_return)
689
+ ... print(f"Month {month}: {lunar_return.iso_formatted_local_datetime}")
690
+
691
+ Seasonal analysis:
692
+
693
+ >>> # Spring Solar Return (if birthday is in spring)
694
+ >>> spring_return = factory.next_return_from_month_and_year(
695
+ ... 2024, 3, "Solar"
696
+ ... )
697
+ >>> # Compare with autumn energy
698
+ >>> autumn_lunar = factory.next_return_from_month_and_year(
699
+ ... 2024, 9, "Lunar"
700
+ ... )
701
+
702
+ Practical Applications:
703
+ - Monthly Lunar Return consultation scheduling
704
+ - Seasonal astrological analysis and timing
705
+ - Comparative study of returns across different months
706
+ - Precise timing for astrological interventions
707
+ - Educational demonstrations of monthly astrological cycles
708
+ - Research into seasonal patterns in planetary returns
709
+
710
+ Technical Notes:
711
+ - Search begins at 00:00:00 UTC on the 1st day of the specified month
712
+ - For Solar Returns, may find the return in a subsequent month if
713
+ the birthday falls late in the specified month of the previous year
714
+ - Lunar Returns typically occur within the specified month due to
715
+ their ~27-day cycle
716
+ - Month validation prevents common input errors
717
+ - All calculations maintain second-level precision
718
+
719
+ Timing Considerations:
720
+ - Solar Returns: Usually occur within 1-2 days of the natal birthday
721
+ - Lunar Returns: Occur approximately every 27.3 days
722
+ - The method finds the chronologically first return from the start date
723
+ - Timezone differences can affect which calendar day the return occurs
724
+
725
+ Use Cases:
726
+ - Monthly return chart consultations
727
+ - Timing specific astrological work or rituals
728
+ - Research into monthly astrological patterns
729
+ - Educational calendar planning for astrological courses
730
+ - Comparative return chart analysis
731
+
732
+ See Also:
733
+ next_return_from_year(): For annual return calculations
734
+ next_return_from_iso_formatted_time(): For custom date searches
235
735
  """
236
736
  # Validate month input
237
737
  if month < 1 or month > 12: