kerykeion 4.14.2__py3-none-any.whl → 4.18.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 (34) hide show
  1. kerykeion/__init__.py +2 -1
  2. kerykeion/aspects/aspects_utils.py +33 -117
  3. kerykeion/aspects/natal_aspects.py +26 -25
  4. kerykeion/aspects/synastry_aspects.py +25 -27
  5. kerykeion/astrological_subject.py +145 -189
  6. kerykeion/charts/charts_utils.py +400 -126
  7. kerykeion/charts/draw_planets.py +407 -0
  8. kerykeion/charts/kerykeion_chart_svg.py +502 -770
  9. kerykeion/charts/templates/aspect_grid_only.xml +452 -0
  10. kerykeion/charts/templates/chart.xml +39 -39
  11. kerykeion/charts/templates/wheel_only.xml +499 -0
  12. kerykeion/charts/themes/classic.css +82 -0
  13. kerykeion/charts/themes/dark-high-contrast.css +121 -0
  14. kerykeion/charts/themes/dark.css +121 -0
  15. kerykeion/charts/themes/light.css +117 -0
  16. kerykeion/ephemeris_data.py +22 -18
  17. kerykeion/kr_types/chart_types.py +3 -7
  18. kerykeion/kr_types/kr_literals.py +10 -1
  19. kerykeion/kr_types/kr_models.py +33 -8
  20. kerykeion/kr_types/settings_models.py +1 -10
  21. kerykeion/relationship_score/__init__.py +2 -0
  22. kerykeion/relationship_score/relationship_score.py +175 -0
  23. kerykeion/relationship_score/relationship_score_factory.py +275 -0
  24. kerykeion/report.py +6 -3
  25. kerykeion/settings/kerykeion_settings.py +6 -1
  26. kerykeion/settings/kr.config.json +238 -98
  27. kerykeion/utilities.py +116 -215
  28. {kerykeion-4.14.2.dist-info → kerykeion-4.18.0.dist-info}/METADATA +40 -10
  29. kerykeion-4.18.0.dist-info/RECORD +42 -0
  30. kerykeion/relationship_score.py +0 -205
  31. kerykeion-4.14.2.dist-info/RECORD +0 -33
  32. {kerykeion-4.14.2.dist-info → kerykeion-4.18.0.dist-info}/LICENSE +0 -0
  33. {kerykeion-4.14.2.dist-info → kerykeion-4.18.0.dist-info}/WHEEL +0 -0
  34. {kerykeion-4.14.2.dist-info → kerykeion-4.18.0.dist-info}/entry_points.txt +0 -0
kerykeion/utilities.py CHANGED
@@ -1,9 +1,11 @@
1
- from kerykeion.kr_types import KerykeionPointModel, KerykeionException, KerykeionSettingsModel, AstrologicalSubjectModel
2
- from kerykeion.kr_types.kr_literals import LunarPhaseEmoji, LunarPhaseName, PointType, Planet
3
- from typing import Union
1
+ from kerykeion.kr_types import KerykeionPointModel, KerykeionException, ZodiacSignModel, AstrologicalSubjectModel
2
+ from kerykeion.kr_types.kr_literals import LunarPhaseEmoji, LunarPhaseName, PointType, Planet, Houses
3
+ from typing import Union, get_args, TYPE_CHECKING
4
4
  import logging
5
5
  import math
6
6
 
7
+ if TYPE_CHECKING:
8
+ from kerykeion import AstrologicalSubject
7
9
 
8
10
 
9
11
  def get_number_from_name(name: Planet) -> int:
@@ -41,172 +43,57 @@ def get_number_from_name(name: Planet) -> int:
41
43
  raise KerykeionException(f"Error in getting number from name! Name: {name}")
42
44
 
43
45
 
44
- def calculate_position(
45
- degree: Union[int, float], number_name: str, point_type: PointType
46
+ def get_kerykeion_point_from_degree(
47
+ degree: Union[int, float], name: Union[Planet, Houses], point_type: PointType
46
48
  ) -> KerykeionPointModel:
47
- """Utility function to create a dictionary dividing the houses or the planets list."""
48
-
49
- if degree < 30:
50
- dictionary = {
51
- "name": number_name,
52
- "quality": "Cardinal",
53
- "element": "Fire",
54
- "sign": "Ari",
55
- "sign_num": 0,
56
- "position": degree,
57
- "abs_pos": degree,
58
- "emoji": "♈️",
59
- "point_type": point_type,
60
- }
61
-
62
- elif degree < 60:
63
- result = degree - 30
64
- dictionary = {
65
- "name": number_name,
66
- "quality": "Fixed",
67
- "element": "Earth",
68
- "sign": "Tau",
69
- "sign_num": 1,
70
- "position": result,
71
- "abs_pos": degree,
72
- "emoji": "♉️",
73
- "point_type": point_type,
74
- }
75
- elif degree < 90:
76
- result = degree - 60
77
- dictionary = {
78
- "name": number_name,
79
- "quality": "Mutable",
80
- "element": "Air",
81
- "sign": "Gem",
82
- "sign_num": 2,
83
- "position": result,
84
- "abs_pos": degree,
85
- "emoji": "♊️",
86
- "point_type": point_type,
87
- }
88
- elif degree < 120:
89
- result = degree - 90
90
- dictionary = {
91
- "name": number_name,
92
- "quality": "Cardinal",
93
- "element": "Water",
94
- "sign": "Can",
95
- "sign_num": 3,
96
- "position": result,
97
- "abs_pos": degree,
98
- "emoji": "♋️",
99
- "point_type": point_type,
100
- }
101
- elif degree < 150:
102
- result = degree - 120
103
- dictionary = {
104
- "name": number_name,
105
- "quality": "Fixed",
106
- "element": "Fire",
107
- "sign": "Leo",
108
- "sign_num": 4,
109
- "position": result,
110
- "abs_pos": degree,
111
- "emoji": "♌️",
112
- "point_type": point_type,
113
- }
114
- elif degree < 180:
115
- result = degree - 150
116
- dictionary = {
117
- "name": number_name,
118
- "quality": "Mutable",
119
- "element": "Earth",
120
- "sign": "Vir",
121
- "sign_num": 5,
122
- "position": result,
123
- "abs_pos": degree,
124
- "emoji": "♍️",
125
- "point_type": point_type,
126
- }
127
- elif degree < 210:
128
- result = degree - 180
129
- dictionary = {
130
- "name": number_name,
131
- "quality": "Cardinal",
132
- "element": "Air",
133
- "sign": "Lib",
134
- "sign_num": 6,
135
- "position": result,
136
- "abs_pos": degree,
137
- "emoji": "♎️",
138
- "point_type": point_type,
139
- }
140
- elif degree < 240:
141
- result = degree - 210
142
- dictionary = {
143
- "name": number_name,
144
- "quality": "Fixed",
145
- "element": "Water",
146
- "sign": "Sco",
147
- "sign_num": 7,
148
- "position": result,
149
- "abs_pos": degree,
150
- "emoji": "♏️",
151
- "point_type": point_type,
152
- }
153
- elif degree < 270:
154
- result = degree - 240
155
- dictionary = {
156
- "name": number_name,
157
- "quality": "Mutable",
158
- "element": "Fire",
159
- "sign": "Sag",
160
- "sign_num": 8,
161
- "position": result,
162
- "abs_pos": degree,
163
- "emoji": "♐️",
164
- "point_type": point_type,
165
- }
166
- elif degree < 300:
167
- result = degree - 270
168
- dictionary = {
169
- "name": number_name,
170
- "quality": "Cardinal",
171
- "element": "Earth",
172
- "sign": "Cap",
173
- "sign_num": 9,
174
- "position": result,
175
- "abs_pos": degree,
176
- "emoji": "♑️",
177
- "point_type": point_type,
178
- }
179
- elif degree < 330:
180
- result = degree - 300
181
- dictionary = {
182
- "name": number_name,
183
- "quality": "Fixed",
184
- "element": "Air",
185
- "sign": "Aqu",
186
- "sign_num": 10,
187
- "position": result,
188
- "abs_pos": degree,
189
- "emoji": "♒️",
190
- "point_type": point_type,
191
- }
192
- elif degree < 360:
193
- result = degree - 330
194
- dictionary = {
195
- "name": number_name,
196
- "quality": "Mutable",
197
- "element": "Water",
198
- "sign": "Pis",
199
- "sign_num": 11,
200
- "position": result,
201
- "abs_pos": degree,
202
- "emoji": "♓️",
203
- "point_type": point_type,
204
- }
205
- else:
49
+ """
50
+ Returns a KerykeionPointModel object based on the given degree.
51
+
52
+ Args:
53
+ degree (Union[int, float]): The degree of the celestial point.
54
+ name (str): The name of the celestial point.
55
+ point_type (PointType): The type of the celestial point.
56
+
57
+ Raises:
58
+ KerykeionException: If the degree is not within the valid range (0-360).
59
+
60
+ Returns:
61
+ KerykeionPointModel: The model representing the celestial point.
62
+ """
63
+
64
+ if degree < 0 or degree >= 360:
206
65
  raise KerykeionException(f"Error in calculating positions! Degrees: {degree}")
207
66
 
208
- return KerykeionPointModel(**dictionary)
67
+ ZODIAC_SIGNS = {
68
+ 0: ZodiacSignModel(sign="Ari", quality="Cardinal", element="Fire", emoji="♈️", sign_num=0),
69
+ 1: ZodiacSignModel(sign="Tau", quality="Fixed", element="Earth", emoji="♉️", sign_num=1),
70
+ 2: ZodiacSignModel(sign="Gem", quality="Mutable", element="Air", emoji="♊️", sign_num=2),
71
+ 3: ZodiacSignModel(sign="Can", quality="Cardinal", element="Water", emoji="♋️", sign_num=3),
72
+ 4: ZodiacSignModel(sign="Leo", quality="Fixed", element="Fire", emoji="♌️", sign_num=4),
73
+ 5: ZodiacSignModel(sign="Vir", quality="Mutable", element="Earth", emoji="♍️", sign_num=5),
74
+ 6: ZodiacSignModel(sign="Lib", quality="Cardinal", element="Air", emoji="♎️", sign_num=6),
75
+ 7: ZodiacSignModel(sign="Sco", quality="Fixed", element="Water", emoji="♏️", sign_num=7),
76
+ 8: ZodiacSignModel(sign="Sag", quality="Mutable", element="Fire", emoji="♐️", sign_num=8),
77
+ 9: ZodiacSignModel(sign="Cap", quality="Cardinal", element="Earth", emoji="♑️", sign_num=9),
78
+ 10: ZodiacSignModel(sign="Aqu", quality="Fixed", element="Air", emoji="♒️", sign_num=10),
79
+ 11: ZodiacSignModel(sign="Pis", quality="Mutable", element="Water", emoji="♓️", sign_num=11),
80
+ }
209
81
 
82
+ sign_index = int(degree // 30)
83
+ sign_degree = degree % 30
84
+ zodiac_sign = ZODIAC_SIGNS[sign_index]
85
+
86
+ return KerykeionPointModel(
87
+ name=name,
88
+ quality=zodiac_sign.quality,
89
+ element=zodiac_sign.element,
90
+ sign=zodiac_sign.sign,
91
+ sign_num=zodiac_sign.sign_num,
92
+ position=sign_degree,
93
+ abs_pos=degree,
94
+ emoji=zodiac_sign.emoji,
95
+ point_type=point_type,
96
+ )
210
97
 
211
98
  def setup_logging(level: str) -> None:
212
99
  """
@@ -220,6 +107,7 @@ def setup_logging(level: str) -> None:
220
107
  "info": logging.INFO,
221
108
  "warning": logging.WARNING,
222
109
  "error": logging.ERROR,
110
+ "critical": logging.CRITICAL,
223
111
  }
224
112
  format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
225
113
  loglevel: int = logging_options.get(level, logging.INFO)
@@ -249,47 +137,33 @@ def check_if_point_between(
249
137
  return False
250
138
 
251
139
 
252
- def get_planet_house(planet_position_degree: Union[int, float], houses_degree_ut_list: list) -> str:
140
+ def get_planet_house(planet_position_degree: Union[int, float], houses_degree_ut_list: list) -> Houses:
253
141
  """
254
- Returns the house in which a planet is located.
142
+ Determines the house in which a planet is located based on its position in degrees.
255
143
 
256
144
  Args:
257
- - planet_position_degree: The position of the planet in degrees
258
- - houses_degree_ut_list: A list of the houses in degrees (0-360)
145
+ planet_position_degree (Union[int, float]): The position of the planet in degrees.
146
+ houses_degree_ut_list (list): A list of the houses in degrees (0-360).
259
147
 
260
148
  Returns:
261
- - The house in which the planet is located
149
+ str: The house in which the planet is located.
150
+
151
+ Raises:
152
+ ValueError: If the planet's position does not fall within any house range.
262
153
  """
263
154
 
264
- house = None
265
- if check_if_point_between(houses_degree_ut_list[0], houses_degree_ut_list[1], planet_position_degree) == True:
266
- house = "First_House"
267
- elif check_if_point_between(houses_degree_ut_list[1], houses_degree_ut_list[2], planet_position_degree) == True:
268
- house = "Second_House"
269
- elif check_if_point_between(houses_degree_ut_list[2], houses_degree_ut_list[3], planet_position_degree) == True:
270
- house = "Third_House"
271
- elif check_if_point_between(houses_degree_ut_list[3], houses_degree_ut_list[4], planet_position_degree) == True:
272
- house = "Fourth_House"
273
- elif check_if_point_between(houses_degree_ut_list[4], houses_degree_ut_list[5], planet_position_degree) == True:
274
- house = "Fifth_House"
275
- elif check_if_point_between(houses_degree_ut_list[5], houses_degree_ut_list[6], planet_position_degree) == True:
276
- house = "Sixth_House"
277
- elif check_if_point_between(houses_degree_ut_list[6], houses_degree_ut_list[7], planet_position_degree) == True:
278
- house = "Seventh_House"
279
- elif check_if_point_between(houses_degree_ut_list[7], houses_degree_ut_list[8], planet_position_degree) == True:
280
- house = "Eighth_House"
281
- elif check_if_point_between(houses_degree_ut_list[8], houses_degree_ut_list[9], planet_position_degree) == True:
282
- house = "Ninth_House"
283
- elif check_if_point_between(houses_degree_ut_list[9], houses_degree_ut_list[10], planet_position_degree) == True:
284
- house = "Tenth_House"
285
- elif check_if_point_between(houses_degree_ut_list[10], houses_degree_ut_list[11], planet_position_degree) == True:
286
- house = "Eleventh_House"
287
- elif check_if_point_between(houses_degree_ut_list[11], houses_degree_ut_list[0], planet_position_degree) == True:
288
- house = "Twelfth_House"
289
- else:
290
- raise ValueError("Error in house calculation, planet: ", planet_position_degree, "houses: ", houses_degree_ut_list)
155
+ house_names = get_args(Houses)
156
+
157
+ # Iterate through the house boundaries to find the correct house
158
+ for i in range(len(house_names)):
159
+ start_degree = houses_degree_ut_list[i]
160
+ end_degree = houses_degree_ut_list[(i + 1) % len(houses_degree_ut_list)]
161
+ if check_if_point_between(start_degree, end_degree, planet_position_degree):
162
+ return house_names[i]
163
+
164
+ # If no house is found, raise an error
165
+ raise ValueError(f"Error in house calculation, planet: {planet_position_degree}, houses: {houses_degree_ut_list}")
291
166
 
292
- return house
293
167
 
294
168
  def get_moon_emoji_from_phase_int(phase: int) -> LunarPhaseEmoji:
295
169
  """
@@ -301,23 +175,25 @@ def get_moon_emoji_from_phase_int(phase: int) -> LunarPhaseEmoji:
301
175
  Returns:
302
176
  - The emoji of the moon phase
303
177
  """
178
+
179
+ lunar_phase_emojis = get_args(LunarPhaseEmoji)
304
180
 
305
181
  if phase == 1:
306
- result = "🌑"
182
+ result = lunar_phase_emojis[0]
307
183
  elif phase < 7:
308
- result = "🌒"
184
+ result = lunar_phase_emojis[1]
309
185
  elif 7 <= phase <= 9:
310
- result = "🌓"
186
+ result = lunar_phase_emojis[2]
311
187
  elif phase < 14:
312
- result = "🌔"
188
+ result = lunar_phase_emojis[3]
313
189
  elif phase == 14:
314
- result = "🌕"
190
+ result = lunar_phase_emojis[4]
315
191
  elif phase < 20:
316
- result = "🌖"
192
+ result = lunar_phase_emojis[5]
317
193
  elif 20 <= phase <= 22:
318
- result = "🌗"
194
+ result = lunar_phase_emojis[6]
319
195
  elif phase <= 28:
320
- result = "🌘"
196
+ result = lunar_phase_emojis[7]
321
197
 
322
198
  else:
323
199
  raise KerykeionException(f"Error in moon emoji calculation! Phase: {phase}")
@@ -334,23 +210,25 @@ def get_moon_phase_name_from_phase_int(phase: int) -> LunarPhaseName:
334
210
  Returns:
335
211
  - The name of the moon phase
336
212
  """
337
-
213
+ lunar_phase_names = get_args(LunarPhaseName)
214
+
215
+
338
216
  if phase == 1:
339
- result = "New Moon"
217
+ result = lunar_phase_names[0]
340
218
  elif phase < 7:
341
- result = "Waxing Crescent"
219
+ result = lunar_phase_names[1]
342
220
  elif 7 <= phase <= 9:
343
- result = "First Quarter"
221
+ result = lunar_phase_names[2]
344
222
  elif phase < 14:
345
- result = "Waxing Gibbous"
223
+ result = lunar_phase_names[3]
346
224
  elif phase == 14:
347
- result = "Full Moon"
225
+ result = lunar_phase_names[4]
348
226
  elif phase < 20:
349
- result = "Waning Gibbous"
227
+ result = lunar_phase_names[5]
350
228
  elif 20 <= phase <= 22:
351
- result = "Last Quarter"
229
+ result = lunar_phase_names[6]
352
230
  elif phase <= 28:
353
- result = "Waning Crescent"
231
+ result = lunar_phase_names[7]
354
232
 
355
233
  else:
356
234
  raise KerykeionException(f"Error in moon name calculation! Phase: {phase}")
@@ -372,3 +250,26 @@ def check_and_adjust_polar_latitude(latitude: float) -> float:
372
250
  logging.info("Polar circle override for houses, using -66 degrees")
373
251
 
374
252
  return latitude
253
+
254
+
255
+ def get_houses_list(subject: Union["AstrologicalSubject", AstrologicalSubjectModel]) -> list[KerykeionPointModel]:
256
+ """
257
+ Return the names of the houses in the order of the houses.
258
+ """
259
+ houses_absolute_position_list = []
260
+ for house in subject.houses_names_list:
261
+ houses_absolute_position_list.append(subject[house.lower()])
262
+
263
+ return houses_absolute_position_list
264
+
265
+
266
+ def get_available_planets_list(subject: Union["AstrologicalSubject", AstrologicalSubjectModel]) -> list[KerykeionPointModel]:
267
+ """
268
+ Return the names of the planets in the order of the planets.
269
+ The names can be used to access the planets from the AstrologicalSubject object with the __getitem__ method or the [] operator.
270
+ """
271
+ planets_absolute_position_list = []
272
+ for planet in subject.planets_names_list:
273
+ planets_absolute_position_list.append(subject[planet.lower()])
274
+
275
+ return planets_absolute_position_list
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kerykeion
3
- Version: 4.14.2
3
+ Version: 4.18.0
4
4
  Summary: A python library for astrology.
5
5
  Home-page: https://www.kerykeion.net/
6
6
  License: AGPL-3.0
7
7
  Keywords: astrology,ephemeris,astrology library,birtchart,svg,zodiac,zodiac-sing,astronomical-algorithms,synastry,astrology-calculator
8
8
  Author: Giacomo Battaglia
9
- Author-email: battaglia.giacomo@yahoo.it
9
+ Author-email: kerykeion.astrology@gmail.com
10
10
  Requires-Python: >=3.9,<4.0
11
11
  Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Intended Audience :: Developers
@@ -69,7 +69,7 @@ The core goal of this project is to provide a simple and easy approach to astrol
69
69
 
70
70
  Here's an example of a birthchart:
71
71
 
72
- ![Kanye Birth Chart](https://www.kerykeion.net/assets/img/examples/birth-chart.svg)
72
+ ![Kanye Birth Chart](https://www.kerykeion.net/docs/assets/img/examples/birth-chart.svg)
73
73
 
74
74
  ## Web API
75
75
 
@@ -154,7 +154,7 @@ birth_chart_svg.makeSVG()
154
154
  ```
155
155
 
156
156
  The SVG file will be saved in the home directory.
157
- ![John Lennon Birth Chart](https://www.kerykeion.net/assets/img/examples/birth-chart.svg)
157
+ ![John Lennon Birth Chart](https://www.kerykeion.net/docs/assets/img/examples/birth-chart.svg)
158
158
 
159
159
  ### Synastry Chart
160
160
 
@@ -170,7 +170,7 @@ synastry_chart.makeSVG()
170
170
 
171
171
  ```
172
172
 
173
- ![John Lennon and Paul McCartney Synastry](https://www.kerykeion.net/assets/img/examples/synastry-chart.svg)
173
+ ![John Lennon and Paul McCartney Synastry](https://www.kerykeion.net/docs/assets/img/examples/synastry-chart.svg)
174
174
 
175
175
  ### Change the output directory
176
176
 
@@ -189,9 +189,12 @@ synastry_chart.makeSVG()
189
189
 
190
190
  ### Change Language
191
191
 
192
- To change the language of the chart you should create a new kr.config.js file and pass it to the BirthChartSVG class. So far the available languages are English, Portuguese, Italian, Spanish, French and Chinese.
192
+ You can change the language of the SVG by passing the `chart_language` parameter to the KerykeionChartSVG class:
193
193
 
194
- Some examples [here](https://www.kerykeion.net/docs/examples/change-language).
194
+ ```python
195
+ first = AstrologicalSubject("John Lennon", 1940, 10, 9, 18, 30, "Liverpool", "GB", chart_language="ES")
196
+ ```
197
+ More details [here](https://www.kerykeion.net/docs/examples/chart-language).
195
198
 
196
199
  ## Report
197
200
 
@@ -318,6 +321,29 @@ More examples [here](https://www.kerykeion.net/docs/examples/perspective-type/).
318
321
 
319
322
  Full list of supported perspective types [here](https://www.kerykeion.net/pydocs/kerykeion/kr_types/kr_literals.html#PerspectiveType).
320
323
 
324
+ ## Themes
325
+
326
+ You can now personalize your astrological charts with different themes! Four themes are available:
327
+
328
+ - **Classic** (default)
329
+ - **Dark**
330
+ - **Dark High Contrast**
331
+ - **Light**
332
+
333
+ Each theme offers a distinct visual style, allowing you to choose the one that best suits your preferences or presentation needs. If you prefer more control over the appearance, you can opt not to set any theme, making it easier to customize the chart by overriding the default CSS variables. For more detailed instructions on how to apply themes, check the [documentation](https://www.kerykeion.net/docs/examples/theming)
334
+
335
+ Here's an example of how to set the theme:
336
+
337
+ ```python
338
+ from kerykeion import AstrologicalSubject, KerykeionChartSVG
339
+
340
+ dark_theme_subject = AstrologicalSubject("John Lennon - Dark Theme", 1940, 10, 9, 18, 30, "Liverpool", "GB")
341
+ dark_theme_natal_chart = KerykeionChartSVG(dark_high_contrast_theme_subject, theme="dark_high_contrast")
342
+ dark_theme_natal_chart.makeSVG()
343
+ ```
344
+
345
+ ![John Lennon](https://www.kerykeion.net/assets/img/showcase/John%20Lennon%20-%20Dark%20-%20Natal%20Chart.svg)
346
+
321
347
  ## Alternative Initialization
322
348
 
323
349
  You can initialize the AstrologicalSubject from a **UTC** ISO 8601 string:
@@ -351,16 +377,20 @@ Sooner or later I'll try to write an extensive documentation.
351
377
 
352
378
  You can clone this repository or download a zip file using the right side buttons.
353
379
 
354
- ## Contributing
380
+ ## Integrate Kerykeion Functionalities in Your Project
355
381
 
356
- Feel free to contribute to the code!
382
+ If you are interested in integrating Kerykeion's astrological functionalities into your project, I would be happy to collaborate with you. Whether you need custom features, support, or consultation, feel free to reach out to me at my [email](mailto:kerykeion.astrology@gmail.com?subject=Integration%20Request) address.
357
383
 
358
384
  ## License
359
385
 
360
386
  This project is licensed under the AGPL-3.0 License.
361
387
  To understand how this impacts your use of the software, please see the [LICENSE](LICENSE) file for details.
362
- If you have questions, you can reach out to me at my [email](mailto:battaglia.giacomo@yahoo.it?subject=Kerykeion) address.
388
+ If you have questions, you can reach out to me at my [email](mailto:kerykeion.astrology@gmail.com?subject=Kerykeion) address.
363
389
  As a rule of thumb, if you are using this library in a project, you should open source the code of the project with a compatible license.
364
390
 
365
391
  You can implement the logic of kerykeion in your project and also keep it closed source by using a third party API, like the [AstrologerAPI](https://rapidapi.com/gbattaglia/api/astrologer/). The AstrologerAPI is AGPL-3.0 compliant. Subscribing to the API is also, currently, the best way to support the project.
366
392
 
393
+ ## Contributing
394
+
395
+ Feel free to contribute to the code!
396
+
@@ -0,0 +1,42 @@
1
+ LICENSE,sha256=UTLH8EdbAsgQei4PA2PnBCPGLSZkq5J-dhkyJuXgWQU,34273
2
+ kerykeion/__init__.py,sha256=2NnLOl-3f7L7x_8vXFKV7mgExlJBmsNIBenZNsR1Seo,639
3
+ kerykeion/aspects/__init__.py,sha256=9FlDVI1ndCJga0-chNIhcLitjU_x3kbtAFfFqVp2ejc,293
4
+ kerykeion/aspects/aspects_utils.py,sha256=kwH_FpReN8rMstyHthE_fWD6doltAVzXkKFcNfo-hLw,2977
5
+ kerykeion/aspects/natal_aspects.py,sha256=ESWKPiVUW6vjNgwEHjIkckwqS1y_vZ8_OAaWxUgfcdQ,4973
6
+ kerykeion/aspects/synastry_aspects.py,sha256=xe28zmrsYU5mxHf6vloEPu-FdJF9x-v7xEGVFkRUSF8,4334
7
+ kerykeion/astrological_subject.py,sha256=YkEHyge_S6FTsAsLNuSMBR-4XdNMFhRo6lHqYdp-u6Y,35045
8
+ kerykeion/charts/__init__.py,sha256=Juxkduy2TaagWblh_7CE8Acrg3dHL27-WEddJhau_eQ,127
9
+ kerykeion/charts/charts_utils.py,sha256=IMvYy6jt6HmZZqpE1FIMhpL3eIqdxq2_aaF1RrpgzpE,42148
10
+ kerykeion/charts/draw_planets.py,sha256=Uty3zpWYMQZvvK7ZHhlmynCHeL8DIN3qL2ifnBXVciM,17393
11
+ kerykeion/charts/kerykeion_chart_svg.py,sha256=1jBMLQ24Mg4EoNZGb7KauH6CpC6830V8lG2tnFZF9MY,42521
12
+ kerykeion/charts/templates/aspect_grid_only.xml,sha256=5CUctWk2wgXV-ev2JHJ5yLlow7gzzFZz1eO744PLu2A,65150
13
+ kerykeion/charts/templates/chart.xml,sha256=ryQao1xDqlSjNUY0HzZiJjdRK__mQoMFA3WV-W6t5Jo,68383
14
+ kerykeion/charts/templates/wheel_only.xml,sha256=xyFlULo1rKZDk8kT9pRWgaEoYyNcmwK40PARKqr30FY,66372
15
+ kerykeion/charts/themes/classic.css,sha256=-b6XllAZmqUDjBwDtIkfzfI3Wtc8AImuGMpfAQ_2wa0,3552
16
+ kerykeion/charts/themes/dark-high-contrast.css,sha256=6Hs_LM3m7xvEuRxWwXjLj6DBvf9W3W_A0hknUimfGCA,6099
17
+ kerykeion/charts/themes/dark.css,sha256=egJbTzqnqMaSk3AQ6KI-PMId-BbT2bqzjpuVds2ffcc,6099
18
+ kerykeion/charts/themes/light.css,sha256=urUXkEQlJ-IymdDO7Hp8hFwwjqka6GB42LkaiWZtpfs,6092
19
+ kerykeion/enums.py,sha256=Xp_0A6jBSW7SZvB5LlKfBObg0xTqB6hTq1IXjz-UWl4,997
20
+ kerykeion/ephemeris_data.py,sha256=H_vpSyRv9685qObfgjJgiqHcFaXT48gAYsqihH0Bixw,8068
21
+ kerykeion/fetch_geonames.py,sha256=NmyTErvKISjJCAxvRB1H35aVZI8_-_U-Cqb_rmqRseA,4563
22
+ kerykeion/kr_types/__init__.py,sha256=-qhGQikurdoHnGtuT1bsaEeZ-IwmZtIHMjGOPC9_oqQ,295
23
+ kerykeion/kr_types/chart_types.py,sha256=OlDvjCra7acaBT--B_gqsqOcAwbuKCXmQQyDTDNfy4o,1983
24
+ kerykeion/kr_types/kerykeion_exception.py,sha256=G-7VFta78qBt10l54JZWvwH-3lUNKmDwuILXaVGVu9A,314
25
+ kerykeion/kr_types/kr_literals.py,sha256=36oJanMtO-1s5Nk4kvlNX3H2eZgoF3ZwTph0lu8wMcE,3505
26
+ kerykeion/kr_types/kr_models.py,sha256=hibUM0HAgL5u2Nx_k6R3wO1VNoKwurzxdj7MJDsrbsg,4235
27
+ kerykeion/kr_types/settings_models.py,sha256=xAIUdJ0vDfS19FiuQdBlwfo6_vCZOZ97K4_vgOD6has,11600
28
+ kerykeion/relationship_score/__init__.py,sha256=cLaEBQXQBfyRkv0OaS3ceLROzvWcvKXWiRq0PS6LDjY,114
29
+ kerykeion/relationship_score/relationship_score.py,sha256=ZUMRjEJdtB5_nRXdx4WJdBbTHu9ACwQTeTGhyeOSsoE,6504
30
+ kerykeion/relationship_score/relationship_score_factory.py,sha256=DL-a-Sb7JLscZl0qlW69SpkETkDmB-akpf5y3Sz8sds,10865
31
+ kerykeion/report.py,sha256=QEZfadIxmqIugoLHMW0KBhOqCwTywGSDDfpX4NJD6qg,2785
32
+ kerykeion/settings/__init__.py,sha256=QQNFCl7sgN27MKaVscqtpPk10HGz4wZS3I_7KEGMaVA,69
33
+ kerykeion/settings/kerykeion_settings.py,sha256=zGLq9vNUQRXs8KY47EyKZ9bHrDl2gNYrvVhwsbh4yas,2578
34
+ kerykeion/settings/kr.config.json,sha256=svjWzo-6kG7pWRgwpL0Rz9aueENu-2k7byUeIdEstLk,18796
35
+ kerykeion/sweph/README.md,sha256=L7FtNAJTWtrZNGKa8MX87SjduFYPYxwWhaI5fmtzNZo,73
36
+ kerykeion/sweph/seas_18.se1,sha256=X9nCqhZU43wJpq61WAdueVQJt9xL2UjrwPqn1Kdoa1s,223002
37
+ kerykeion/utilities.py,sha256=VazaGS8n2p3CD8P2q31A1kSKbmXRNMG8DytLuBwEaU4,9219
38
+ kerykeion-4.18.0.dist-info/LICENSE,sha256=UTLH8EdbAsgQei4PA2PnBCPGLSZkq5J-dhkyJuXgWQU,34273
39
+ kerykeion-4.18.0.dist-info/METADATA,sha256=SK_8wXf0v2Zd6p8x8UMQ3zdMat3qXtx4pv43qv0fb2g,15912
40
+ kerykeion-4.18.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
41
+ kerykeion-4.18.0.dist-info/entry_points.txt,sha256=5SmANYscFDDTdeovHvGQ-cnj0hdFvGoxPaWLCpyDFnQ,49
42
+ kerykeion-4.18.0.dist-info/RECORD,,