kerykeion 4.26.3__py3-none-any.whl → 5.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kerykeion might be problematic. Click here for more details.

Files changed (76) hide show
  1. kerykeion/__init__.py +54 -11
  2. kerykeion/aspects/__init__.py +5 -2
  3. kerykeion/aspects/aspects_factory.py +569 -0
  4. kerykeion/aspects/aspects_utils.py +81 -8
  5. kerykeion/astrological_subject_factory.py +1897 -0
  6. kerykeion/backword.py +773 -0
  7. kerykeion/chart_data_factory.py +549 -0
  8. kerykeion/charts/chart_drawer.py +2601 -0
  9. kerykeion/charts/charts_utils.py +948 -177
  10. kerykeion/charts/draw_planets.py +602 -351
  11. kerykeion/charts/templates/aspect_grid_only.xml +328 -202
  12. kerykeion/charts/templates/chart.xml +432 -272
  13. kerykeion/charts/templates/wheel_only.xml +350 -214
  14. kerykeion/charts/themes/black-and-white.css +148 -0
  15. kerykeion/charts/themes/classic.css +107 -76
  16. kerykeion/charts/themes/dark-high-contrast.css +145 -107
  17. kerykeion/charts/themes/dark.css +146 -107
  18. kerykeion/charts/themes/light.css +146 -103
  19. kerykeion/charts/themes/strawberry.css +158 -0
  20. kerykeion/composite_subject_factory.py +253 -51
  21. kerykeion/ephemeris_data_factory.py +434 -0
  22. kerykeion/fetch_geonames.py +27 -8
  23. kerykeion/house_comparison/__init__.py +6 -0
  24. kerykeion/house_comparison/house_comparison_factory.py +103 -0
  25. kerykeion/house_comparison/house_comparison_utils.py +126 -0
  26. kerykeion/kr_types/__init__.py +66 -6
  27. kerykeion/kr_types/chart_template_model.py +20 -0
  28. kerykeion/kr_types/kerykeion_exception.py +15 -9
  29. kerykeion/kr_types/kr_literals.py +14 -132
  30. kerykeion/kr_types/kr_models.py +14 -318
  31. kerykeion/kr_types/settings_models.py +15 -203
  32. kerykeion/planetary_return_factory.py +805 -0
  33. kerykeion/relationship_score_factory.py +301 -0
  34. kerykeion/report.py +751 -64
  35. kerykeion/schemas/__init__.py +106 -0
  36. kerykeion/schemas/chart_template_model.py +367 -0
  37. kerykeion/schemas/kerykeion_exception.py +20 -0
  38. kerykeion/schemas/kr_literals.py +181 -0
  39. kerykeion/schemas/kr_models.py +605 -0
  40. kerykeion/schemas/settings_models.py +180 -0
  41. kerykeion/settings/__init__.py +20 -1
  42. kerykeion/settings/chart_defaults.py +444 -0
  43. kerykeion/settings/config_constants.py +117 -12
  44. kerykeion/settings/kerykeion_settings.py +31 -73
  45. kerykeion/settings/translation_strings.py +1479 -0
  46. kerykeion/settings/translations.py +74 -0
  47. kerykeion/sweph/ast136/s136108s.se1 +0 -0
  48. kerykeion/sweph/ast136/s136199s.se1 +0 -0
  49. kerykeion/sweph/ast136/s136472s.se1 +0 -0
  50. kerykeion/sweph/ast28/se28978s.se1 +0 -0
  51. kerykeion/sweph/ast50/se50000s.se1 +0 -0
  52. kerykeion/sweph/ast90/se90377s.se1 +0 -0
  53. kerykeion/sweph/ast90/se90482s.se1 +0 -0
  54. kerykeion/sweph/sefstars.txt +1602 -0
  55. kerykeion/transits_time_range_factory.py +302 -0
  56. kerykeion/utilities.py +393 -114
  57. kerykeion-5.0.0.dist-info/METADATA +1176 -0
  58. kerykeion-5.0.0.dist-info/RECORD +63 -0
  59. {kerykeion-4.26.3.dist-info → kerykeion-5.0.0.dist-info}/WHEEL +1 -1
  60. kerykeion/aspects/natal_aspects.py +0 -172
  61. kerykeion/aspects/synastry_aspects.py +0 -124
  62. kerykeion/aspects/transits_time_range.py +0 -41
  63. kerykeion/astrological_subject.py +0 -841
  64. kerykeion/charts/kerykeion_chart_svg.py +0 -1219
  65. kerykeion/enums.py +0 -57
  66. kerykeion/ephemeris_data.py +0 -242
  67. kerykeion/kr_types/chart_types.py +0 -95
  68. kerykeion/relationship_score/__init__.py +0 -2
  69. kerykeion/relationship_score/relationship_score.py +0 -175
  70. kerykeion/relationship_score/relationship_score_factory.py +0 -230
  71. kerykeion/settings/kr.config.json +0 -1258
  72. kerykeion/transits_time_range.py +0 -124
  73. kerykeion-4.26.3.dist-info/METADATA +0 -634
  74. kerykeion-4.26.3.dist-info/RECORD +0 -45
  75. kerykeion-4.26.3.dist-info/entry_points.txt +0 -3
  76. {kerykeion-4.26.3.dist-info → kerykeion-5.0.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,605 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ This is part of Kerykeion (C) 2025 Giacomo Battaglia
4
+ """
5
+
6
+ from typing import Union, Optional, List, Literal
7
+ from typing_extensions import TypedDict
8
+ from pydantic import BaseModel, Field
9
+ from kerykeion.schemas.kr_literals import AspectName
10
+
11
+ from kerykeion.schemas import (
12
+ LunarPhaseEmoji,
13
+ LunarPhaseName,
14
+ AstrologicalPoint,
15
+ Houses,
16
+ Quality,
17
+ Element,
18
+ Sign,
19
+ ZodiacType,
20
+ SignNumbers,
21
+ PointType,
22
+ SiderealMode,
23
+ HousesSystemIdentifier,
24
+ SignsEmoji,
25
+ RelationshipScoreDescription,
26
+ PerspectiveType,
27
+ AspectMovementType
28
+ )
29
+ from kerykeion.schemas.kr_literals import ReturnType
30
+
31
+
32
+ class SubscriptableBaseModel(BaseModel):
33
+ """
34
+ Pydantic BaseModel with subscriptable support, so you can access the fields as if they were a dictionary.
35
+ """
36
+
37
+ def __getitem__(self, key):
38
+ """Get an attribute using dictionary-style access."""
39
+ return getattr(self, key)
40
+
41
+ def __setitem__(self, key, value):
42
+ """Set an attribute using dictionary-style access."""
43
+ setattr(self, key, value)
44
+
45
+ def __delitem__(self, key):
46
+ """Delete an attribute using dictionary-style access."""
47
+ delattr(self, key)
48
+
49
+ def get(self, key, default = None):
50
+ """Get an attribute with a default value if not found."""
51
+ return getattr(self, key, default)
52
+
53
+
54
+ class LunarPhaseModel(SubscriptableBaseModel):
55
+ """
56
+ Model representing lunar phase information.
57
+
58
+ Attributes:
59
+ degrees_between_s_m: Angular separation between Sun and Moon in degrees.
60
+ moon_phase: Numerical phase identifier for the Moon.
61
+ moon_emoji: Emoji representation of the lunar phase.
62
+ moon_phase_name: Text name of the lunar phase.
63
+ """
64
+ degrees_between_s_m: Union[float, int]
65
+ moon_phase: int
66
+ moon_emoji: LunarPhaseEmoji
67
+ moon_phase_name: LunarPhaseName
68
+
69
+
70
+ class KerykeionPointModel(SubscriptableBaseModel):
71
+ """
72
+ Model representing an astrological celestial point or house cusp.
73
+
74
+ This model contains comprehensive information about celestial objects
75
+ (planets, points) or house cusps including their zodiacal position,
76
+ sign placement, and metadata.
77
+
78
+ Attributes:
79
+ name: The name of the celestial point or house.
80
+ quality: Astrological quality (Cardinal, Fixed, Mutable).
81
+ element: Astrological element (Fire, Earth, Air, Water).
82
+ sign: The zodiac sign the point is located in.
83
+ sign_num: Numerical identifier for the zodiac sign (0-11).
84
+ position: Position within the sign (0-30 degrees).
85
+ abs_pos: Absolute position in the zodiac (0-360 degrees).
86
+ emoji: Unicode emoji representing the point or sign.
87
+ point_type: Type of the celestial point (Planet, House, etc.).
88
+ house: House placement of the point (optional).
89
+ retrograde: Whether the point is in retrograde motion (optional).
90
+ """
91
+
92
+ name: Union[AstrologicalPoint, Houses]
93
+ quality: Quality
94
+ element: Element
95
+ sign: Sign
96
+ sign_num: SignNumbers
97
+ position: float
98
+ abs_pos: float
99
+ emoji: str
100
+ point_type: PointType
101
+ house: Optional[Houses] = None
102
+ retrograde: Optional[bool] = None
103
+ speed: Optional[float] = None
104
+ declination: Optional[float] = None
105
+
106
+
107
+ class AstrologicalBaseModel(SubscriptableBaseModel):
108
+ """
109
+ Base model containing common fields for all astrological subjects.
110
+
111
+ This model serves as the foundation for all astrological chart types,
112
+ providing standard location, time, and configuration data. It supports
113
+ both complete charts (with full location/time data) and composite charts
114
+ (where some fields may be optional).
115
+
116
+ Attributes:
117
+ name: Subject identifier or name.
118
+ city: Location city (optional for composite charts).
119
+ nation: Country code (optional for composite charts).
120
+ lng: Longitude coordinate (optional for composite charts).
121
+ lat: Latitude coordinate (optional for composite charts).
122
+ tz_str: Timezone string (optional for composite charts).
123
+ iso_formatted_local_datetime: Local datetime in ISO format (optional).
124
+ iso_formatted_utc_datetime: UTC datetime in ISO format (optional).
125
+ julian_day: Julian day number for astronomical calculations (optional).
126
+ day_of_week: Day of the week (optional).
127
+ zodiac_type: Type of zodiac system used (Tropical or Sidereal).
128
+ sidereal_mode: Sidereal calculation mode (if applicable).
129
+ houses_system_identifier: House system used for calculations.
130
+ perspective_type: Astrological perspective (geocentric, heliocentric, etc.).
131
+ active_points: List of celestial points included in calculations.
132
+ """
133
+ # Common identification data
134
+ name: str
135
+
136
+ # Common location data (optional for composite charts)
137
+ city: Optional[str] = None
138
+ nation: Optional[str] = None
139
+ lng: Optional[float] = None
140
+ lat: Optional[float] = None
141
+ tz_str: Optional[str] = None
142
+
143
+ # Common time data (optional for composite charts)
144
+ iso_formatted_local_datetime: Optional[str] = None
145
+ iso_formatted_utc_datetime: Optional[str] = None
146
+ julian_day: Optional[float] = None
147
+ day_of_week: Optional[str] = None
148
+
149
+ # Common configuration
150
+ zodiac_type: ZodiacType
151
+ sidereal_mode: Union[SiderealMode, None]
152
+ houses_system_identifier: HousesSystemIdentifier
153
+ houses_system_name: str
154
+ perspective_type: PerspectiveType
155
+
156
+ # Common celestial points
157
+ # Main planets (all optional to support selective calculations)
158
+ sun: Optional[KerykeionPointModel] = None
159
+ moon: Optional[KerykeionPointModel] = None
160
+ mercury: Optional[KerykeionPointModel] = None
161
+ venus: Optional[KerykeionPointModel] = None
162
+ mars: Optional[KerykeionPointModel] = None
163
+ jupiter: Optional[KerykeionPointModel] = None
164
+ saturn: Optional[KerykeionPointModel] = None
165
+ uranus: Optional[KerykeionPointModel] = None
166
+ neptune: Optional[KerykeionPointModel] = None
167
+ pluto: Optional[KerykeionPointModel] = None
168
+
169
+ # Common axes
170
+ ascendant: Optional[KerykeionPointModel] = None
171
+ descendant: Optional[KerykeionPointModel] = None
172
+ medium_coeli: Optional[KerykeionPointModel] = None
173
+ imum_coeli: Optional[KerykeionPointModel] = None
174
+
175
+ # Common optional planets
176
+ chiron: Optional[KerykeionPointModel] = None
177
+ earth: Optional[KerykeionPointModel] = None
178
+ pholus: Optional[KerykeionPointModel] = None
179
+
180
+ # Lilith Points
181
+ mean_lilith: Optional[KerykeionPointModel] = None
182
+ true_lilith: Optional[KerykeionPointModel] = None
183
+
184
+ # Asteroids
185
+ ceres: Optional[KerykeionPointModel] = None
186
+ pallas: Optional[KerykeionPointModel] = None
187
+ juno: Optional[KerykeionPointModel] = None
188
+ vesta: Optional[KerykeionPointModel] = None
189
+
190
+ # Trans-Neptunian Objects
191
+ eris: Optional[KerykeionPointModel] = None
192
+ sedna: Optional[KerykeionPointModel] = None
193
+ haumea: Optional[KerykeionPointModel] = None
194
+ makemake: Optional[KerykeionPointModel] = None
195
+ ixion: Optional[KerykeionPointModel] = None
196
+ orcus: Optional[KerykeionPointModel] = None
197
+ quaoar: Optional[KerykeionPointModel] = None
198
+
199
+ # Fixed Stars
200
+ regulus: Optional[KerykeionPointModel] = None
201
+ spica: Optional[KerykeionPointModel] = None
202
+
203
+ # Arabic Parts
204
+ pars_fortunae: Optional[KerykeionPointModel] = None
205
+ pars_spiritus: Optional[KerykeionPointModel] = None
206
+ pars_amoris: Optional[KerykeionPointModel] = None
207
+ pars_fidei: Optional[KerykeionPointModel] = None
208
+
209
+ # Special Points
210
+ vertex: Optional[KerykeionPointModel] = None
211
+ anti_vertex: Optional[KerykeionPointModel] = None
212
+
213
+ # Common houses
214
+ first_house: KerykeionPointModel
215
+ second_house: KerykeionPointModel
216
+ third_house: KerykeionPointModel
217
+ fourth_house: KerykeionPointModel
218
+ fifth_house: KerykeionPointModel
219
+ sixth_house: KerykeionPointModel
220
+ seventh_house: KerykeionPointModel
221
+ eighth_house: KerykeionPointModel
222
+ ninth_house: KerykeionPointModel
223
+ tenth_house: KerykeionPointModel
224
+ eleventh_house: KerykeionPointModel
225
+ twelfth_house: KerykeionPointModel
226
+
227
+ # Lunar Nodes
228
+ mean_north_lunar_node: Optional[KerykeionPointModel] = None
229
+ true_north_lunar_node: Optional[KerykeionPointModel] = None
230
+ mean_south_lunar_node: Optional[KerykeionPointModel] = None
231
+ true_south_lunar_node: Optional[KerykeionPointModel] = None
232
+
233
+ # Common lists and settings
234
+ houses_names_list: List[Houses] = Field(description="Ordered list of houses names")
235
+ active_points: List[AstrologicalPoint] = Field(description="List of active points in the chart or aspects calculations.")
236
+
237
+ # Common lunar phase data (optional)
238
+ lunar_phase: Optional[LunarPhaseModel] = Field(default=None, description="Lunar phase model")
239
+
240
+
241
+ class AstrologicalSubjectModel(AstrologicalBaseModel):
242
+ """
243
+ Pydantic Model for Astrological Subject
244
+ """
245
+ # Override base model to make location and time data required for subjects
246
+ city: str
247
+ nation: str
248
+ lng: float
249
+ lat: float
250
+ tz_str: str
251
+ iso_formatted_local_datetime: str
252
+ iso_formatted_utc_datetime: str
253
+ julian_day: float
254
+ day_of_week: str
255
+
256
+ # Specific birth/event data
257
+ year: int
258
+ month: int
259
+ day: int
260
+ hour: int
261
+ minute: int
262
+
263
+
264
+ class CompositeSubjectModel(AstrologicalBaseModel):
265
+ """
266
+ Pydantic Model for Composite Subject
267
+ """
268
+ # Specific composite data
269
+ first_subject: AstrologicalSubjectModel
270
+ second_subject: AstrologicalSubjectModel
271
+ composite_chart_type: str
272
+
273
+
274
+ class PlanetReturnModel(AstrologicalBaseModel):
275
+ """
276
+ Pydantic Model for Planet Return
277
+ """
278
+ # Specific return data
279
+ return_type: ReturnType = Field(description="Type of return: Solar or Lunar")
280
+
281
+
282
+ class EphemerisDictModel(SubscriptableBaseModel):
283
+ date: str
284
+ planets: List[KerykeionPointModel]
285
+ houses: List[KerykeionPointModel]
286
+
287
+
288
+ class AspectModel(SubscriptableBaseModel):
289
+ p1_name: str
290
+ p1_owner: str
291
+ p1_abs_pos: float
292
+ p2_name: str
293
+ p2_owner: str
294
+ p2_abs_pos: float
295
+ aspect: str
296
+ orbit: float
297
+ aspect_degrees: int
298
+ diff: float
299
+ p1: int
300
+ p2: int
301
+ aspect_movement: AspectMovementType = Field(
302
+ description="Indicates whether the aspect is applying (planets moving toward exact aspect), "
303
+ "separating (planets moving away from exact aspect), or exact (within tight orb)."
304
+ )
305
+
306
+
307
+ class ZodiacSignModel(SubscriptableBaseModel):
308
+ sign: Sign
309
+ quality: Quality
310
+ element: Element
311
+ emoji: SignsEmoji
312
+ sign_num: SignNumbers
313
+
314
+
315
+ class RelationshipScoreAspectModel(SubscriptableBaseModel):
316
+ p1_name: str
317
+ p2_name: str
318
+ aspect: str
319
+ orbit: float
320
+
321
+
322
+ class RelationshipScoreModel(SubscriptableBaseModel):
323
+ score_value: int
324
+ score_description: RelationshipScoreDescription
325
+ is_destiny_sign: bool
326
+ aspects: List[RelationshipScoreAspectModel]
327
+ subjects: List[AstrologicalSubjectModel]
328
+
329
+
330
+ class ActiveAspect(TypedDict):
331
+ name: AspectName
332
+ orb: int
333
+
334
+
335
+ class TransitMomentModel(SubscriptableBaseModel):
336
+ """
337
+ Model representing a snapshot of astrological transits at a specific moment in time.
338
+
339
+ Captures all active aspects between moving celestial bodies and
340
+ the fixed positions in a person's natal chart at a specific date and time.
341
+ """
342
+ date: str = Field(description="ISO 8601 formatted date and time of the transit moment.")
343
+ aspects: List[AspectModel] = Field(description="List of aspects active at this specific moment.")
344
+
345
+
346
+ class SingleChartAspectsModel(SubscriptableBaseModel):
347
+ """
348
+ Model representing all aspects within a single astrological chart.
349
+
350
+ This model can be used for any type of single chart analysis including:
351
+ - Natal charts
352
+ - Planetary return charts
353
+ - Composite charts
354
+ - Any other single chart type
355
+
356
+ Contains both all calculated aspects and the filtered relevant aspects
357
+ for the astrological subject.
358
+ """
359
+ subject: Union["AstrologicalSubjectModel", "CompositeSubjectModel", "PlanetReturnModel"] = Field(description="The astrological subject for which aspects were calculated.")
360
+ all_aspects: List[AspectModel] = Field(description="Complete list of all calculated aspects within the chart.")
361
+ relevant_aspects: List[AspectModel] = Field(description="Filtered list of relevant aspects based on orb settings.")
362
+ active_points: List[AstrologicalPoint] = Field(description="List of active points used in the calculation.")
363
+ active_aspects: List["ActiveAspect"] = Field(description="List of active aspects with their orb settings.")
364
+
365
+
366
+ class DualChartAspectsModel(SubscriptableBaseModel):
367
+ """
368
+ Model representing all aspects between two astrological charts.
369
+
370
+ This model can be used for any type of dual chart analysis including:
371
+ - Synastry (relationship compatibility)
372
+ - Transit comparisons
373
+ - Composite vs natal comparisons
374
+ - Any other dual chart comparison
375
+
376
+ Contains both all calculated aspects and the filtered relevant aspects
377
+ between the two charts.
378
+ """
379
+ first_subject: Union["AstrologicalSubjectModel", "CompositeSubjectModel", "PlanetReturnModel"] = Field(description="The first astrological subject.")
380
+ second_subject: Union["AstrologicalSubjectModel", "CompositeSubjectModel", "PlanetReturnModel"] = Field(description="The second astrological subject.")
381
+ all_aspects: List[AspectModel] = Field(description="Complete list of all calculated aspects between the two charts.")
382
+ relevant_aspects: List[AspectModel] = Field(description="Filtered list of relevant aspects based on orb settings.")
383
+ active_points: List[AstrologicalPoint] = Field(description="List of active points used in the calculation.")
384
+ active_aspects: List["ActiveAspect"] = Field(description="List of active aspects with their orb settings.")
385
+
386
+
387
+ # Legacy aliases for backward compatibility
388
+ NatalAspectsModel = SingleChartAspectsModel
389
+ SynastryAspectsModel = DualChartAspectsModel
390
+
391
+
392
+ class TransitsTimeRangeModel(SubscriptableBaseModel):
393
+ """
394
+ Model representing a collection of transit moments for an astrological subject.
395
+
396
+ This model holds a time series of transit snapshots, allowing analysis of
397
+ planetary movements and their aspects to a natal chart over a period of time.
398
+ """
399
+ transits: List[TransitMomentModel] = Field(description="List of transit moments.")
400
+ subject: Optional[AstrologicalSubjectModel] = Field(description="Astrological subject data.")
401
+ dates: Optional[List[str]] = Field(description="ISO 8601 formatted dates of all transit moments.")
402
+
403
+
404
+ class PointInHouseModel(SubscriptableBaseModel):
405
+ """
406
+ Represents an astrological point from one subject positioned within another subject's house.
407
+
408
+ Captures point characteristics and its placement within the target subject's house system
409
+ for house comparison analysis.
410
+
411
+ Attributes:
412
+ point_name: Name of the astrological point
413
+ point_degree: Degree position within its sign
414
+ point_sign: Zodiacal sign containing the point
415
+ point_owner_name: Name of the subject who owns this point
416
+ point_owner_house_number: House number in owner's chart
417
+ point_owner_house_name: House name in owner's chart
418
+ projected_house_number: House number in target subject's chart
419
+ projected_house_name: House name in target subject's chart
420
+ projected_house_owner_name: Name of the target subject
421
+ """
422
+
423
+ point_name: str
424
+ """Name of the astrological point"""
425
+ point_degree: float
426
+ """Degree position of the point within its zodiacal sign"""
427
+ point_sign: str
428
+ """Zodiacal sign containing the point"""
429
+ point_owner_name: str
430
+ """Name of the subject who owns this point"""
431
+ point_owner_house_number: Optional[int]
432
+ """House number in owner's chart"""
433
+ point_owner_house_name: Optional[str]
434
+ """House name in owner's chart"""
435
+ projected_house_number: int
436
+ """House number in target subject's chart"""
437
+ projected_house_name: str
438
+ """House name in target subject's chart"""
439
+ projected_house_owner_name: str
440
+ """Name of the target subject"""
441
+
442
+
443
+ class HouseComparisonModel(SubscriptableBaseModel):
444
+ """
445
+ Bidirectional house comparison analysis between two astrological subjects.
446
+
447
+ Contains results of how astrological points from each subject interact with
448
+ the house system of the other subject.
449
+
450
+ Attributes:
451
+ first_subject_name: Name of the first subject
452
+ second_subject_name: Name of the second subject
453
+ first_points_in_second_houses: First subject's points in second subject's houses
454
+ second_points_in_first_houses: Second subject's points in first subject's houses
455
+ """
456
+
457
+ first_subject_name: str
458
+ """Name of the first subject"""
459
+ second_subject_name: str
460
+ """Name of the second subject"""
461
+ first_points_in_second_houses: List[PointInHouseModel]
462
+ """First subject's points positioned in second subject's houses"""
463
+ second_points_in_first_houses: List[PointInHouseModel]
464
+ """Second subject's points positioned in first subject's houses"""
465
+
466
+
467
+ class ElementDistributionModel(SubscriptableBaseModel):
468
+ """
469
+ Model representing element distribution in a chart.
470
+
471
+ Attributes:
472
+ fire: Fire element points total
473
+ earth: Earth element points total
474
+ air: Air element points total
475
+ water: Water element points total
476
+ fire_percentage: Fire element percentage
477
+ earth_percentage: Earth element percentage
478
+ air_percentage: Air element percentage
479
+ water_percentage: Water element percentage
480
+ """
481
+ fire: float
482
+ earth: float
483
+ air: float
484
+ water: float
485
+ fire_percentage: int
486
+ earth_percentage: int
487
+ air_percentage: int
488
+ water_percentage: int
489
+
490
+
491
+ class QualityDistributionModel(SubscriptableBaseModel):
492
+ """
493
+ Model representing quality distribution in a chart.
494
+
495
+ Attributes:
496
+ cardinal: Cardinal quality points total
497
+ fixed: Fixed quality points total
498
+ mutable: Mutable quality points total
499
+ cardinal_percentage: Cardinal quality percentage
500
+ fixed_percentage: Fixed quality percentage
501
+ mutable_percentage: Mutable quality percentage
502
+ """
503
+ cardinal: float
504
+ fixed: float
505
+ mutable: float
506
+ cardinal_percentage: int
507
+ fixed_percentage: int
508
+ mutable_percentage: int
509
+
510
+
511
+ class SingleChartDataModel(SubscriptableBaseModel):
512
+ """
513
+ Chart data model for single-subject astrological charts.
514
+
515
+ This model contains all pure data from single-subject charts including planetary
516
+ positions, internal aspects, element/quality distributions, and location data.
517
+ Used for chart types that analyze a single astrological subject.
518
+
519
+ Supported chart types:
520
+ - Natal: Birth chart with internal planetary aspects
521
+ - Composite: Midpoint relationship chart with internal aspects
522
+ - SingleReturnChart: Single planetary return with internal aspects
523
+
524
+ Attributes:
525
+ chart_type: Type of single chart (Natal, Composite, SingleReturnChart)
526
+ subject: The astrological subject being analyzed
527
+ aspects: Internal aspects within the chart
528
+ element_distribution: Distribution of elemental energies
529
+ quality_distribution: Distribution of modal qualities
530
+ active_points: Celestial points included in calculations
531
+ active_aspects: Aspect types and orb settings used
532
+ """
533
+
534
+ # Chart identification
535
+ chart_type: Literal["Natal", "Composite", "SingleReturnChart"]
536
+
537
+ # Single chart subject
538
+ subject: Union["AstrologicalSubjectModel", "CompositeSubjectModel", "PlanetReturnModel"]
539
+
540
+ # Internal aspects analysis
541
+ aspects: "SingleChartAspectsModel"
542
+
543
+ # Element and quality distributions
544
+ element_distribution: "ElementDistributionModel"
545
+ quality_distribution: "QualityDistributionModel"
546
+
547
+ # Configuration and metadata
548
+ active_points: List[AstrologicalPoint]
549
+ active_aspects: List["ActiveAspect"]
550
+
551
+
552
+ class DualChartDataModel(SubscriptableBaseModel):
553
+ """
554
+ Chart data model for dual-subject astrological charts.
555
+
556
+ This model contains all pure data from dual-subject charts including both subjects,
557
+ inter-chart aspects, house comparisons, relationship analysis, and combined
558
+ element/quality distributions. Used for chart types that compare or overlay
559
+ two astrological subjects.
560
+
561
+ Supported chart types:
562
+ - Transit: Natal chart with current planetary transits
563
+ - Synastry: Relationship compatibility between two people
564
+ - Return: Natal chart with planetary return comparison
565
+
566
+ Attributes:
567
+ chart_type: Type of dual chart (Transit, Synastry, Return)
568
+ first_subject: Primary astrological subject (natal, base chart)
569
+ second_subject: Secondary astrological subject (transit, partner, return)
570
+ aspects: Inter-chart aspects between the two subjects
571
+ house_comparison: House overlay analysis between subjects
572
+ relationship_score: Compatibility scoring (synastry only)
573
+ element_distribution: Combined elemental distribution
574
+ quality_distribution: Combined modal distribution
575
+ active_points: Celestial points included in calculations
576
+ active_aspects: Aspect types and orb settings used
577
+ """
578
+
579
+ # Chart identification
580
+ chart_type: Literal["Transit", "Synastry", "DualReturnChart"]
581
+
582
+ # Dual chart subjects
583
+ first_subject: Union["AstrologicalSubjectModel", "CompositeSubjectModel", "PlanetReturnModel"]
584
+ second_subject: Union["AstrologicalSubjectModel", "PlanetReturnModel"]
585
+
586
+ # Inter-chart aspects analysis
587
+ aspects: "DualChartAspectsModel"
588
+
589
+ # House comparison analysis
590
+ house_comparison: Optional["HouseComparisonModel"] = None
591
+
592
+ # Relationship analysis (synastry only)
593
+ relationship_score: Optional["RelationshipScoreModel"] = None
594
+
595
+ # Combined element and quality distributions
596
+ element_distribution: "ElementDistributionModel"
597
+ quality_distribution: "QualityDistributionModel"
598
+
599
+ # Configuration and metadata
600
+ active_points: List[AstrologicalPoint]
601
+ active_aspects: List["ActiveAspect"]
602
+
603
+
604
+ # Union type for all chart data models
605
+ ChartDataModel = Union[SingleChartDataModel, DualChartDataModel]