divineapi 1.2.0__tar.gz → 1.4.0__tar.gz
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.
- {divineapi-1.2.0 → divineapi-1.4.0}/PKG-INFO +26 -12
- {divineapi-1.2.0 → divineapi-1.4.0}/README.md +25 -11
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/__init__.py +6 -4
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/calculators.py +2 -2
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/horoscope.py +27 -11
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/indian/kundli.py +33 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/pdf.py +23 -16
- divineapi-1.4.0/divineapi/western/_house_system.py +52 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/western/composite.py +2 -1
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/western/natal.py +5 -4
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/western/planet_returns.py +5 -3
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/western/prenatal.py +2 -1
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/western/progressions.py +16 -5
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/western/synastry.py +2 -1
- divineapi-1.4.0/divineapi/western/transit.py +218 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi.egg-info/PKG-INFO +26 -12
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi.egg-info/SOURCES.txt +1 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/pyproject.toml +1 -1
- divineapi-1.2.0/divineapi/western/transit.py +0 -110
- {divineapi-1.2.0 → divineapi-1.4.0}/LICENSE +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/client.py +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/exceptions.py +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/indian/__init__.py +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/indian/festival.py +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/indian/match_making.py +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/indian/panchang.py +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/lifestyle.py +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/numerology.py +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/py.typed +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi/western/__init__.py +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi.egg-info/dependency_links.txt +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi.egg-info/requires.txt +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/divineapi.egg-info/top_level.txt +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/setup.cfg +0 -0
- {divineapi-1.2.0 → divineapi-1.4.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: divineapi
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Official Python SDK for the Divine API - Astrology, Numerology, Tarot & more
|
|
5
5
|
Author-email: Divine API <support@divineapi.com>
|
|
6
6
|
License: MIT
|
|
@@ -51,9 +51,9 @@ from divineapi import DivineApi
|
|
|
51
51
|
|
|
52
52
|
client = DivineApi(api_key="your-api-key", auth_token="your-bearer-token")
|
|
53
53
|
|
|
54
|
-
# Daily Horoscope
|
|
54
|
+
# Daily Horoscope (h_day = today, tomorrow, or yesterday)
|
|
55
55
|
result = client.horoscope.daily(
|
|
56
|
-
sign="aries",
|
|
56
|
+
sign="aries", h_day="today", tzone=5.5
|
|
57
57
|
)
|
|
58
58
|
print(result)
|
|
59
59
|
```
|
|
@@ -64,10 +64,11 @@ print(result)
|
|
|
64
64
|
|
|
65
65
|
```python
|
|
66
66
|
# Daily / Weekly / Monthly / Yearly Horoscope
|
|
67
|
-
|
|
68
|
-
client.horoscope.
|
|
69
|
-
client.horoscope.
|
|
70
|
-
client.horoscope.
|
|
67
|
+
# daily h_day = today / tomorrow / yesterday; weekly/monthly/yearly = current / prev / next
|
|
68
|
+
client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
69
|
+
client.horoscope.weekly(sign="leo", week="current", tzone=5.5)
|
|
70
|
+
client.horoscope.monthly(sign="cancer", month="current", tzone=5.5)
|
|
71
|
+
client.horoscope.yearly(sign="virgo", year="current", tzone=5.5)
|
|
71
72
|
|
|
72
73
|
# Chinese & Numerology Horoscope
|
|
73
74
|
client.horoscope.chinese(sign="rat", h_day="today", tzone=5.5)
|
|
@@ -140,6 +141,14 @@ client.indian.kundli.lal_kitab_varshphal_chart(2026, **birth)
|
|
|
140
141
|
# Lal Kitab dasha content (no birth data needed)
|
|
141
142
|
client.indian.kundli.lal_kitab_mahadasha_content(maha_dasha="saturn")
|
|
142
143
|
client.indian.kundli.lal_kitab_antardasha_content(maha_dasha="saturn", antar_dasha="mercury")
|
|
144
|
+
|
|
145
|
+
# Additional kundli analysis
|
|
146
|
+
client.indian.kundli.vargottama_planets(**birth)
|
|
147
|
+
client.indian.kundli.bhav_bala(**birth)
|
|
148
|
+
client.indian.kundli.shani_ashtam_shani(**birth)
|
|
149
|
+
client.indian.kundli.bhava_analysis(**birth)
|
|
150
|
+
client.indian.kundli.bhava_group_predictions(**birth)
|
|
151
|
+
client.indian.kundli.planet_remedies("sun", **birth) # analysis_planet + birth
|
|
143
152
|
```
|
|
144
153
|
|
|
145
154
|
### Indian Astrology - Match Making
|
|
@@ -164,8 +173,9 @@ client.indian.festival.chaitra_festivals(
|
|
|
164
173
|
client.indian.festival.english_calendar(
|
|
165
174
|
year=2024, month=3, place="Delhi", lat=28.6, lon=77.2, tzone=5.5
|
|
166
175
|
)
|
|
176
|
+
# festival is a lowercase snake_case slug from the Divine festival list
|
|
167
177
|
client.indian.festival.find_festival(
|
|
168
|
-
festival="
|
|
178
|
+
festival="maha_shivratri", year=2024,
|
|
169
179
|
place="Delhi", lat=28.6, lon=77.2, tzone=5.5
|
|
170
180
|
)
|
|
171
181
|
client.indian.festival.malayalam_festivals(
|
|
@@ -193,7 +203,7 @@ client.western.natal.house_cusps(**birth_w)
|
|
|
193
203
|
client.western.natal.aspect_table(**birth_w)
|
|
194
204
|
client.western.natal.natal_wheel_chart(**birth_w)
|
|
195
205
|
client.western.natal.natal_insights(**birth_w)
|
|
196
|
-
client.western.natal.dominants(method="
|
|
206
|
+
client.western.natal.dominants(method="TRADITIONAL", **birth_w)
|
|
197
207
|
```
|
|
198
208
|
|
|
199
209
|
### Western Astrology - Synastry
|
|
@@ -252,7 +262,7 @@ client.lifestyle.astro_chic_picks(sign="virgo", h_day="today", tzone=5.5)
|
|
|
252
262
|
### Calculators
|
|
253
263
|
|
|
254
264
|
```python
|
|
255
|
-
client.calculators.flames(
|
|
265
|
+
client.calculators.flames(your_name="John", partner_name="Jane")
|
|
256
266
|
client.calculators.love_calculator(
|
|
257
267
|
your_name="John", partner_name="Jane",
|
|
258
268
|
your_gender="male", partner_gender="female",
|
|
@@ -262,11 +272,15 @@ client.calculators.love_calculator(
|
|
|
262
272
|
### PDF Reports
|
|
263
273
|
|
|
264
274
|
```python
|
|
275
|
+
# The six branding fields (company_url, logo_url, footer_text, company_name,
|
|
276
|
+
# company_email, company_bio) are REQUIRED by the PDF backend.
|
|
265
277
|
client.pdf.kundali_sampoorna(
|
|
266
278
|
full_name="John", day=1, month=1, year=1990,
|
|
267
279
|
hour=10, min=30, sec=0, gender="male",
|
|
268
280
|
place="Mumbai", lat=19.07, lon=72.87, tzone=5.5,
|
|
269
281
|
company_name="AstroCo", company_url="https://example.com",
|
|
282
|
+
company_email="hello@example.com", company_bio="We do astrology.",
|
|
283
|
+
logo_url="https://example.com/logo.png", footer_text="(c) AstroCo",
|
|
270
284
|
)
|
|
271
285
|
```
|
|
272
286
|
|
|
@@ -278,7 +292,7 @@ from divineapi import DivineApi, AuthenticationError, ValidationError, RateLimit
|
|
|
278
292
|
client = DivineApi(api_key="...", auth_token="...")
|
|
279
293
|
|
|
280
294
|
try:
|
|
281
|
-
result = client.horoscope.daily(sign="aries",
|
|
295
|
+
result = client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
282
296
|
except AuthenticationError as e:
|
|
283
297
|
print(f"Auth failed: {e}")
|
|
284
298
|
except ValidationError as e:
|
|
@@ -291,7 +305,7 @@ except RateLimitError as e:
|
|
|
291
305
|
|
|
292
306
|
```python
|
|
293
307
|
with DivineApi(api_key="...", auth_token="...") as client:
|
|
294
|
-
result = client.horoscope.daily(sign="aries",
|
|
308
|
+
result = client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
295
309
|
```
|
|
296
310
|
|
|
297
311
|
## Configuration
|
|
@@ -23,9 +23,9 @@ from divineapi import DivineApi
|
|
|
23
23
|
|
|
24
24
|
client = DivineApi(api_key="your-api-key", auth_token="your-bearer-token")
|
|
25
25
|
|
|
26
|
-
# Daily Horoscope
|
|
26
|
+
# Daily Horoscope (h_day = today, tomorrow, or yesterday)
|
|
27
27
|
result = client.horoscope.daily(
|
|
28
|
-
sign="aries",
|
|
28
|
+
sign="aries", h_day="today", tzone=5.5
|
|
29
29
|
)
|
|
30
30
|
print(result)
|
|
31
31
|
```
|
|
@@ -36,10 +36,11 @@ print(result)
|
|
|
36
36
|
|
|
37
37
|
```python
|
|
38
38
|
# Daily / Weekly / Monthly / Yearly Horoscope
|
|
39
|
-
|
|
40
|
-
client.horoscope.
|
|
41
|
-
client.horoscope.
|
|
42
|
-
client.horoscope.
|
|
39
|
+
# daily h_day = today / tomorrow / yesterday; weekly/monthly/yearly = current / prev / next
|
|
40
|
+
client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
41
|
+
client.horoscope.weekly(sign="leo", week="current", tzone=5.5)
|
|
42
|
+
client.horoscope.monthly(sign="cancer", month="current", tzone=5.5)
|
|
43
|
+
client.horoscope.yearly(sign="virgo", year="current", tzone=5.5)
|
|
43
44
|
|
|
44
45
|
# Chinese & Numerology Horoscope
|
|
45
46
|
client.horoscope.chinese(sign="rat", h_day="today", tzone=5.5)
|
|
@@ -112,6 +113,14 @@ client.indian.kundli.lal_kitab_varshphal_chart(2026, **birth)
|
|
|
112
113
|
# Lal Kitab dasha content (no birth data needed)
|
|
113
114
|
client.indian.kundli.lal_kitab_mahadasha_content(maha_dasha="saturn")
|
|
114
115
|
client.indian.kundli.lal_kitab_antardasha_content(maha_dasha="saturn", antar_dasha="mercury")
|
|
116
|
+
|
|
117
|
+
# Additional kundli analysis
|
|
118
|
+
client.indian.kundli.vargottama_planets(**birth)
|
|
119
|
+
client.indian.kundli.bhav_bala(**birth)
|
|
120
|
+
client.indian.kundli.shani_ashtam_shani(**birth)
|
|
121
|
+
client.indian.kundli.bhava_analysis(**birth)
|
|
122
|
+
client.indian.kundli.bhava_group_predictions(**birth)
|
|
123
|
+
client.indian.kundli.planet_remedies("sun", **birth) # analysis_planet + birth
|
|
115
124
|
```
|
|
116
125
|
|
|
117
126
|
### Indian Astrology - Match Making
|
|
@@ -136,8 +145,9 @@ client.indian.festival.chaitra_festivals(
|
|
|
136
145
|
client.indian.festival.english_calendar(
|
|
137
146
|
year=2024, month=3, place="Delhi", lat=28.6, lon=77.2, tzone=5.5
|
|
138
147
|
)
|
|
148
|
+
# festival is a lowercase snake_case slug from the Divine festival list
|
|
139
149
|
client.indian.festival.find_festival(
|
|
140
|
-
festival="
|
|
150
|
+
festival="maha_shivratri", year=2024,
|
|
141
151
|
place="Delhi", lat=28.6, lon=77.2, tzone=5.5
|
|
142
152
|
)
|
|
143
153
|
client.indian.festival.malayalam_festivals(
|
|
@@ -165,7 +175,7 @@ client.western.natal.house_cusps(**birth_w)
|
|
|
165
175
|
client.western.natal.aspect_table(**birth_w)
|
|
166
176
|
client.western.natal.natal_wheel_chart(**birth_w)
|
|
167
177
|
client.western.natal.natal_insights(**birth_w)
|
|
168
|
-
client.western.natal.dominants(method="
|
|
178
|
+
client.western.natal.dominants(method="TRADITIONAL", **birth_w)
|
|
169
179
|
```
|
|
170
180
|
|
|
171
181
|
### Western Astrology - Synastry
|
|
@@ -224,7 +234,7 @@ client.lifestyle.astro_chic_picks(sign="virgo", h_day="today", tzone=5.5)
|
|
|
224
234
|
### Calculators
|
|
225
235
|
|
|
226
236
|
```python
|
|
227
|
-
client.calculators.flames(
|
|
237
|
+
client.calculators.flames(your_name="John", partner_name="Jane")
|
|
228
238
|
client.calculators.love_calculator(
|
|
229
239
|
your_name="John", partner_name="Jane",
|
|
230
240
|
your_gender="male", partner_gender="female",
|
|
@@ -234,11 +244,15 @@ client.calculators.love_calculator(
|
|
|
234
244
|
### PDF Reports
|
|
235
245
|
|
|
236
246
|
```python
|
|
247
|
+
# The six branding fields (company_url, logo_url, footer_text, company_name,
|
|
248
|
+
# company_email, company_bio) are REQUIRED by the PDF backend.
|
|
237
249
|
client.pdf.kundali_sampoorna(
|
|
238
250
|
full_name="John", day=1, month=1, year=1990,
|
|
239
251
|
hour=10, min=30, sec=0, gender="male",
|
|
240
252
|
place="Mumbai", lat=19.07, lon=72.87, tzone=5.5,
|
|
241
253
|
company_name="AstroCo", company_url="https://example.com",
|
|
254
|
+
company_email="hello@example.com", company_bio="We do astrology.",
|
|
255
|
+
logo_url="https://example.com/logo.png", footer_text="(c) AstroCo",
|
|
242
256
|
)
|
|
243
257
|
```
|
|
244
258
|
|
|
@@ -250,7 +264,7 @@ from divineapi import DivineApi, AuthenticationError, ValidationError, RateLimit
|
|
|
250
264
|
client = DivineApi(api_key="...", auth_token="...")
|
|
251
265
|
|
|
252
266
|
try:
|
|
253
|
-
result = client.horoscope.daily(sign="aries",
|
|
267
|
+
result = client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
254
268
|
except AuthenticationError as e:
|
|
255
269
|
print(f"Auth failed: {e}")
|
|
256
270
|
except ValidationError as e:
|
|
@@ -263,7 +277,7 @@ except RateLimitError as e:
|
|
|
263
277
|
|
|
264
278
|
```python
|
|
265
279
|
with DivineApi(api_key="...", auth_token="...") as client:
|
|
266
|
-
result = client.horoscope.daily(sign="aries",
|
|
280
|
+
result = client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
267
281
|
```
|
|
268
282
|
|
|
269
283
|
## Configuration
|
|
@@ -5,7 +5,7 @@ Usage::
|
|
|
5
5
|
from divineapi import DivineApi
|
|
6
6
|
|
|
7
7
|
client = DivineApi(api_key="your-api-key", auth_token="your-bearer-token")
|
|
8
|
-
result = client.horoscope.daily(sign="aries",
|
|
8
|
+
result = client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
9
9
|
print(result)
|
|
10
10
|
"""
|
|
11
11
|
|
|
@@ -29,7 +29,7 @@ from .numerology import NumerologyApi
|
|
|
29
29
|
from .pdf import PdfReportApi
|
|
30
30
|
from .western import WesternApi
|
|
31
31
|
|
|
32
|
-
__version__ = "1.
|
|
32
|
+
__version__ = "1.4.0"
|
|
33
33
|
|
|
34
34
|
__all__ = [
|
|
35
35
|
"DivineApi",
|
|
@@ -57,7 +57,7 @@ class DivineApi:
|
|
|
57
57
|
client = DivineApi(api_key="...", auth_token="...")
|
|
58
58
|
|
|
59
59
|
# Horoscope & Tarot
|
|
60
|
-
client.horoscope.daily(sign="aries",
|
|
60
|
+
client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
61
61
|
|
|
62
62
|
# Indian Panchang
|
|
63
63
|
client.indian.panchang.find_panchang(
|
|
@@ -100,7 +100,9 @@ class DivineApi:
|
|
|
100
100
|
full_name="John", day=1, month=1, year=1990,
|
|
101
101
|
hour=10, min=30, sec=0, gender="male",
|
|
102
102
|
place="Mumbai", lat=19.07, lon=72.87, tzone=5.5,
|
|
103
|
-
company_name="MyCompany",
|
|
103
|
+
company_name="MyCompany", company_url="https://example.com",
|
|
104
|
+
company_email="hello@example.com", company_bio="We do astrology.",
|
|
105
|
+
logo_url="https://example.com/logo.png", footer_text="(c) MyCompany",
|
|
104
106
|
)
|
|
105
107
|
"""
|
|
106
108
|
|
|
@@ -13,10 +13,10 @@ class CalculatorApi:
|
|
|
13
13
|
def __init__(self, client: BaseClient) -> None:
|
|
14
14
|
self._c = client
|
|
15
15
|
|
|
16
|
-
def flames(self,
|
|
16
|
+
def flames(self, your_name: str, partner_name: str) -> Dict[str, Any]:
|
|
17
17
|
"""FLAMES Calculator."""
|
|
18
18
|
return self._c.post(HOST, "/calculator/v1/flames-calculator", {
|
|
19
|
-
"
|
|
19
|
+
"your_name": your_name, "partner_name": partner_name,
|
|
20
20
|
})
|
|
21
21
|
|
|
22
22
|
def love_calculator(
|
|
@@ -20,16 +20,21 @@ class HoroscopeApi:
|
|
|
20
20
|
def daily(
|
|
21
21
|
self,
|
|
22
22
|
sign: str,
|
|
23
|
-
|
|
24
|
-
month: int,
|
|
25
|
-
year: int,
|
|
23
|
+
h_day: str,
|
|
26
24
|
tzone: float,
|
|
27
25
|
lan: str = "en",
|
|
26
|
+
day: Optional[int] = None,
|
|
27
|
+
month: Optional[int] = None,
|
|
28
|
+
year: Optional[int] = None,
|
|
28
29
|
) -> Dict[str, Any]:
|
|
29
|
-
"""Daily Horoscope.
|
|
30
|
+
"""Daily Horoscope.
|
|
31
|
+
|
|
32
|
+
The reading is selected with ``h_day`` ('today', 'tomorrow', or
|
|
33
|
+
'yesterday'). ``day``/``month``/``year`` are deprecated: the API
|
|
34
|
+
ignores them and they are accepted only for backward compatibility.
|
|
35
|
+
"""
|
|
30
36
|
return self._c.post(HOST, "/api/v5/daily-horoscope", {
|
|
31
|
-
"sign": sign, "
|
|
32
|
-
"tzone": tzone, "lan": lan,
|
|
37
|
+
"sign": sign, "h_day": h_day, "tzone": tzone, "lan": lan,
|
|
33
38
|
})
|
|
34
39
|
|
|
35
40
|
def weekly(
|
|
@@ -39,7 +44,10 @@ class HoroscopeApi:
|
|
|
39
44
|
tzone: float,
|
|
40
45
|
lan: str = "en",
|
|
41
46
|
) -> Dict[str, Any]:
|
|
42
|
-
"""Weekly Horoscope.
|
|
47
|
+
"""Weekly Horoscope.
|
|
48
|
+
|
|
49
|
+
``week`` is a selector: 'current', 'prev', or 'next' (not a date).
|
|
50
|
+
"""
|
|
43
51
|
return self._c.post(HOST, "/api/v5/weekly-horoscope", {
|
|
44
52
|
"sign": sign, "week": week, "tzone": tzone, "lan": lan,
|
|
45
53
|
})
|
|
@@ -47,11 +55,15 @@ class HoroscopeApi:
|
|
|
47
55
|
def monthly(
|
|
48
56
|
self,
|
|
49
57
|
sign: str,
|
|
50
|
-
month:
|
|
58
|
+
month: str,
|
|
51
59
|
tzone: float,
|
|
52
60
|
lan: str = "en",
|
|
53
61
|
) -> Dict[str, Any]:
|
|
54
|
-
"""Monthly Horoscope.
|
|
62
|
+
"""Monthly Horoscope.
|
|
63
|
+
|
|
64
|
+
``month`` is a selector: 'current', 'prev', or 'next' (not a calendar
|
|
65
|
+
month number).
|
|
66
|
+
"""
|
|
55
67
|
return self._c.post(HOST, "/api/v5/monthly-horoscope", {
|
|
56
68
|
"sign": sign, "month": month, "tzone": tzone, "lan": lan,
|
|
57
69
|
})
|
|
@@ -59,11 +71,15 @@ class HoroscopeApi:
|
|
|
59
71
|
def yearly(
|
|
60
72
|
self,
|
|
61
73
|
sign: str,
|
|
62
|
-
year:
|
|
74
|
+
year: str,
|
|
63
75
|
tzone: float,
|
|
64
76
|
lan: str = "en",
|
|
65
77
|
) -> Dict[str, Any]:
|
|
66
|
-
"""Yearly Horoscope.
|
|
78
|
+
"""Yearly Horoscope.
|
|
79
|
+
|
|
80
|
+
``year`` is a selector: 'current', 'prev', or 'next' (not a calendar
|
|
81
|
+
year number).
|
|
82
|
+
"""
|
|
67
83
|
return self._c.post(HOST, "/api/v5/yearly-horoscope", {
|
|
68
84
|
"sign": sign, "year": year, "tzone": tzone, "lan": lan,
|
|
69
85
|
})
|
|
@@ -323,3 +323,36 @@ class KundliApi:
|
|
|
323
323
|
"""Lal Kitab Varshphal Chart for the given year."""
|
|
324
324
|
kw["varshphal_year"] = varshphal_year
|
|
325
325
|
return self._post_birth("/indian-api/v1/lal-kitab/varshphal/chart", **kw)
|
|
326
|
+
|
|
327
|
+
# ------------------------------------------------------------------ #
|
|
328
|
+
# Additional Kundli Analysis (6 endpoints)
|
|
329
|
+
# ------------------------------------------------------------------ #
|
|
330
|
+
|
|
331
|
+
def vargottama_planets(self, **kw: Any) -> Dict[str, Any]:
|
|
332
|
+
"""Vargottama Planets."""
|
|
333
|
+
return self._post_birth("/indian-api/v1/vargottama-planets", **kw)
|
|
334
|
+
|
|
335
|
+
def bhav_bala(self, **kw: Any) -> Dict[str, Any]:
|
|
336
|
+
"""Bhav Bala."""
|
|
337
|
+
return self._post_birth("/indian-api/v1/bhav-bala", **kw)
|
|
338
|
+
|
|
339
|
+
def shani_ashtam_shani(self, **kw: Any) -> Dict[str, Any]:
|
|
340
|
+
"""Shani Ashtam Shani."""
|
|
341
|
+
return self._post_birth("/indian-api/v1/shani-ashtam-shani", **kw)
|
|
342
|
+
|
|
343
|
+
def bhava_analysis(self, **kw: Any) -> Dict[str, Any]:
|
|
344
|
+
"""Bhava Analysis."""
|
|
345
|
+
return self._post_birth("/indian-api/v1/bhava-analysis", **kw)
|
|
346
|
+
|
|
347
|
+
def bhava_group_predictions(self, **kw: Any) -> Dict[str, Any]:
|
|
348
|
+
"""Bhava Group Predictions."""
|
|
349
|
+
return self._post_birth("/indian-api/v1/bhava-group-predictions", **kw)
|
|
350
|
+
|
|
351
|
+
def planet_remedies(self, analysis_planet: str, **kw: Any) -> Dict[str, Any]:
|
|
352
|
+
"""Planet Remedies for a given planet.
|
|
353
|
+
|
|
354
|
+
analysis_planet: sun, moon, mars, mercury, jupiter, venus, saturn,
|
|
355
|
+
rahu or ketu.
|
|
356
|
+
"""
|
|
357
|
+
kw["analysis_planet"] = analysis_planet
|
|
358
|
+
return self._post_birth("/indian-api/v1/planet-remedies", **kw)
|
|
@@ -22,23 +22,26 @@ class PdfReportApi:
|
|
|
22
22
|
full_name: str, day: int, month: int, year: int,
|
|
23
23
|
hour: int, min: int, sec: int, gender: str,
|
|
24
24
|
place: str, lat: float, lon: float, tzone: float,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
company_bio: str = "", logo_url: str = "",
|
|
29
|
-
footer_text: str = "",
|
|
25
|
+
company_name: str, company_url: str, company_email: str,
|
|
26
|
+
company_bio: str, logo_url: str, footer_text: str,
|
|
27
|
+
lan: str = "en", company_mobile: str = "",
|
|
30
28
|
**extra: Any,
|
|
31
29
|
) -> Dict[str, Any]:
|
|
30
|
+
# The six branding fields are REQUIRED by the PDF backend (it rejects
|
|
31
|
+
# requests without them). company_mobile is optional and sent only when
|
|
32
|
+
# provided.
|
|
32
33
|
d: Dict[str, Any] = {
|
|
33
34
|
"full_name": full_name, "day": day, "month": month, "year": year,
|
|
34
35
|
"hour": hour, "min": min, "sec": sec, "gender": gender,
|
|
35
36
|
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
36
37
|
"lan": lan,
|
|
37
38
|
"company_name": company_name, "company_url": company_url,
|
|
38
|
-
"company_email": company_email,
|
|
39
|
+
"company_email": company_email,
|
|
39
40
|
"company_bio": company_bio, "logo_url": logo_url,
|
|
40
41
|
"footer_text": footer_text,
|
|
41
42
|
}
|
|
43
|
+
if company_mobile:
|
|
44
|
+
d["company_mobile"] = company_mobile
|
|
42
45
|
d.update(extra)
|
|
43
46
|
return d
|
|
44
47
|
|
|
@@ -50,13 +53,12 @@ class PdfReportApi:
|
|
|
50
53
|
p2_full_name: str, p2_day: int, p2_month: int, p2_year: int,
|
|
51
54
|
p2_hour: int, p2_min: int, p2_sec: int, p2_gender: str,
|
|
52
55
|
p2_place: str, p2_lat: float, p2_lon: float, p2_tzone: float,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
company_bio: str = "", logo_url: str = "",
|
|
57
|
-
footer_text: str = "",
|
|
56
|
+
company_name: str, company_url: str, company_email: str,
|
|
57
|
+
company_bio: str, logo_url: str, footer_text: str,
|
|
58
|
+
lan: str = "en", company_mobile: str = "",
|
|
58
59
|
**extra: Any,
|
|
59
60
|
) -> Dict[str, Any]:
|
|
61
|
+
# The six branding fields are REQUIRED by the PDF backend.
|
|
60
62
|
d: Dict[str, Any] = {
|
|
61
63
|
"p1_full_name": p1_full_name, "p1_day": p1_day, "p1_month": p1_month,
|
|
62
64
|
"p1_year": p1_year, "p1_hour": p1_hour, "p1_min": p1_min,
|
|
@@ -68,10 +70,12 @@ class PdfReportApi:
|
|
|
68
70
|
"p2_lat": p2_lat, "p2_lon": p2_lon, "p2_tzone": p2_tzone,
|
|
69
71
|
"lan": lan,
|
|
70
72
|
"company_name": company_name, "company_url": company_url,
|
|
71
|
-
"company_email": company_email,
|
|
73
|
+
"company_email": company_email,
|
|
72
74
|
"company_bio": company_bio, "logo_url": logo_url,
|
|
73
75
|
"footer_text": footer_text,
|
|
74
76
|
}
|
|
77
|
+
if company_mobile:
|
|
78
|
+
d["company_mobile"] = company_mobile
|
|
75
79
|
d.update(extra)
|
|
76
80
|
return d
|
|
77
81
|
|
|
@@ -133,11 +137,14 @@ class PdfReportApi:
|
|
|
133
137
|
# Astrology / Numerology reports with report_code
|
|
134
138
|
# ------------------------------------------------------------------ #
|
|
135
139
|
|
|
136
|
-
def natal_report(self, report_code: str, theme: str
|
|
137
|
-
"""Natal Report PDF.
|
|
140
|
+
def natal_report(self, report_code: str, theme: str, **kw: Any) -> Dict[str, Any]:
|
|
141
|
+
"""Natal Report PDF.
|
|
142
|
+
|
|
143
|
+
Both ``report_code`` (e.g. 'CAREER-REPORT') and ``theme`` (e.g. '001')
|
|
144
|
+
are required by the API, along with the six company branding fields.
|
|
145
|
+
"""
|
|
138
146
|
kw["report_code"] = report_code
|
|
139
|
-
|
|
140
|
-
kw["theme"] = theme
|
|
147
|
+
kw["theme"] = theme
|
|
141
148
|
return self._post_birth("/astrology/v2/report", **kw)
|
|
142
149
|
|
|
143
150
|
def natal_couple_report(self, report_code: str, **kw: Any) -> Dict[str, Any]:
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""House-system name resolution for the Western API.
|
|
2
|
+
|
|
3
|
+
The live Western API accepts ONLY single-letter Swiss Ephemeris house-system
|
|
4
|
+
codes. Word values like ``placidus`` are rejected on astroapi-4 and silently
|
|
5
|
+
ignored on astroapi-8, so every payload must send the letter code. This mirrors
|
|
6
|
+
the mapping used by the Divine Western MCP server.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
# Friendly house-system names mapped to the single-letter API codes.
|
|
12
|
+
HOUSE_SYSTEM_MAP = {
|
|
13
|
+
"placidus": "P",
|
|
14
|
+
"koch": "K",
|
|
15
|
+
"porphyry": "O",
|
|
16
|
+
"regiomontanus": "R",
|
|
17
|
+
"campanus": "C",
|
|
18
|
+
"equal": "E",
|
|
19
|
+
"whole-sign": "W",
|
|
20
|
+
"whole_sign": "W",
|
|
21
|
+
"wholesign": "W",
|
|
22
|
+
"morinus": "M",
|
|
23
|
+
"alcabitius": "B",
|
|
24
|
+
}
|
|
25
|
+
VALID_HOUSE_SYSTEM_LETTERS = set(HOUSE_SYSTEM_MAP.values())
|
|
26
|
+
HOUSE_SYSTEM_FRIENDLY_NAMES = (
|
|
27
|
+
"placidus, koch, porphyry, regiomontanus, campanus, equal, "
|
|
28
|
+
"whole-sign, morinus, alcabitius"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def resolve_house_system(value: Optional[str]) -> str:
|
|
33
|
+
"""Map a friendly house-system name to its single-letter API code.
|
|
34
|
+
|
|
35
|
+
Accepts friendly names case-insensitively (e.g. ``placidus``, ``Whole-Sign``)
|
|
36
|
+
and already-valid single letters (passed through unchanged, upper-cased).
|
|
37
|
+
An empty value defaults to ``P`` (Placidus). Raises ``ValueError`` for
|
|
38
|
+
anything else.
|
|
39
|
+
"""
|
|
40
|
+
hs = (value or "").strip()
|
|
41
|
+
if not hs:
|
|
42
|
+
return "P"
|
|
43
|
+
if hs.upper() in VALID_HOUSE_SYSTEM_LETTERS:
|
|
44
|
+
return hs.upper()
|
|
45
|
+
mapped = HOUSE_SYSTEM_MAP.get(hs.lower())
|
|
46
|
+
if mapped:
|
|
47
|
+
return mapped
|
|
48
|
+
raise ValueError(
|
|
49
|
+
f"Invalid house_system '{value}'. Must be one of: "
|
|
50
|
+
f"{HOUSE_SYSTEM_FRIENDLY_NAMES} (or a single-letter code: "
|
|
51
|
+
f"{', '.join(sorted(VALID_HOUSE_SYSTEM_LETTERS))})"
|
|
52
|
+
)
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from typing import Any, Dict
|
|
4
4
|
|
|
5
5
|
from ..client import BaseClient
|
|
6
|
+
from ._house_system import resolve_house_system
|
|
6
7
|
|
|
7
8
|
HOST = "astroapi-8"
|
|
8
9
|
|
|
@@ -33,7 +34,7 @@ class CompositeApi:
|
|
|
33
34
|
"p2_year": p2_year, "p2_hour": p2_hour, "p2_min": p2_min,
|
|
34
35
|
"p2_sec": p2_sec, "p2_gender": p2_gender, "p2_place": p2_place,
|
|
35
36
|
"p2_lat": p2_lat, "p2_lon": p2_lon, "p2_tzone": p2_tzone,
|
|
36
|
-
"lan": lan, "house_system": house_system,
|
|
37
|
+
"lan": lan, "house_system": resolve_house_system(house_system),
|
|
37
38
|
}
|
|
38
39
|
d.update(extra)
|
|
39
40
|
return d
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"""Western API - Natal endpoints (astroapi-4 and astroapi-8)."""
|
|
2
2
|
|
|
3
|
-
from typing import Any, Dict
|
|
3
|
+
from typing import Any, Dict
|
|
4
4
|
|
|
5
5
|
from ..client import BaseClient
|
|
6
|
+
from ._house_system import resolve_house_system
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class NatalApi:
|
|
@@ -27,7 +28,7 @@ class NatalApi:
|
|
|
27
28
|
"full_name": full_name, "day": day, "month": month, "year": year,
|
|
28
29
|
"hour": hour, "min": min, "sec": sec, "gender": gender,
|
|
29
30
|
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
30
|
-
"lan": lan, "house_system": house_system,
|
|
31
|
+
"lan": lan, "house_system": resolve_house_system(house_system),
|
|
31
32
|
}
|
|
32
33
|
d.update(extra)
|
|
33
34
|
return d
|
|
@@ -44,11 +45,11 @@ class NatalApi:
|
|
|
44
45
|
|
|
45
46
|
def planetary_positions(self, **kw: Any) -> Dict[str, Any]:
|
|
46
47
|
"""Natal Planetary Positions."""
|
|
47
|
-
return self._post4("/western-api/
|
|
48
|
+
return self._post4("/western-api/v1/planetary-positions", **kw)
|
|
48
49
|
|
|
49
50
|
def house_cusps(self, **kw: Any) -> Dict[str, Any]:
|
|
50
51
|
"""Natal House Cusps."""
|
|
51
|
-
return self._post4("/western-api/
|
|
52
|
+
return self._post4("/western-api/v1/house-cusps", **kw)
|
|
52
53
|
|
|
53
54
|
def aspect_table(self, **kw: Any) -> Dict[str, Any]:
|
|
54
55
|
"""Natal Aspect Table."""
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from typing import Any, Dict
|
|
4
4
|
|
|
5
5
|
from ..client import BaseClient
|
|
6
|
+
from ._house_system import resolve_house_system
|
|
6
7
|
|
|
7
8
|
HOST = "astroapi-8"
|
|
8
9
|
|
|
@@ -25,7 +26,7 @@ class PlanetReturnsApi:
|
|
|
25
26
|
"full_name": full_name, "day": day, "month": month, "year": year,
|
|
26
27
|
"hour": hour, "min": min, "sec": sec, "gender": gender,
|
|
27
28
|
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
28
|
-
"lan": lan, "house_system": house_system,
|
|
29
|
+
"lan": lan, "house_system": resolve_house_system(house_system),
|
|
29
30
|
}
|
|
30
31
|
d.update(extra)
|
|
31
32
|
return d
|
|
@@ -46,14 +47,15 @@ class PlanetReturnsApi:
|
|
|
46
47
|
return self._c.post(HOST, "/western-api/v1/planet-returns-list", self._birth(**kw))
|
|
47
48
|
|
|
48
49
|
def planet_return_details(
|
|
49
|
-
self, planet: str, return_key: str,
|
|
50
|
+
self, planet: str, return_key: str, return_year: int,
|
|
50
51
|
return_lat: float, return_lon: float,
|
|
51
52
|
return_tzone: float, return_place: str,
|
|
52
53
|
**kw: Any,
|
|
53
54
|
) -> Dict[str, Any]:
|
|
54
|
-
"""Planet Return Details."""
|
|
55
|
+
"""Planet Return Details (``return_key`` comes from ``planet_return_list``)."""
|
|
55
56
|
kw["planet"] = planet
|
|
56
57
|
kw["return_key"] = return_key
|
|
58
|
+
kw["return_year"] = return_year
|
|
57
59
|
kw["return_lat"] = return_lat
|
|
58
60
|
kw["return_lon"] = return_lon
|
|
59
61
|
kw["return_tzone"] = return_tzone
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from typing import Any, Dict
|
|
4
4
|
|
|
5
5
|
from ..client import BaseClient
|
|
6
|
+
from ._house_system import resolve_house_system
|
|
6
7
|
|
|
7
8
|
HOST = "astroapi-8"
|
|
8
9
|
|
|
@@ -25,7 +26,7 @@ class PrenatalApi:
|
|
|
25
26
|
"full_name": full_name, "day": day, "month": month, "year": year,
|
|
26
27
|
"hour": hour, "min": min, "sec": sec, "gender": gender,
|
|
27
28
|
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
28
|
-
"lan": lan, "house_system": house_system,
|
|
29
|
+
"lan": lan, "house_system": resolve_house_system(house_system),
|
|
29
30
|
}
|
|
30
31
|
d.update(extra)
|
|
31
32
|
return d
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"""Western API - Progressions endpoints (astroapi-8)."""
|
|
2
2
|
|
|
3
|
-
from typing import Any, Dict
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
4
|
|
|
5
5
|
from ..client import BaseClient
|
|
6
|
+
from ._house_system import resolve_house_system
|
|
6
7
|
|
|
7
8
|
HOST = "astroapi-8"
|
|
8
9
|
|
|
@@ -25,7 +26,7 @@ class ProgressionsApi:
|
|
|
25
26
|
"full_name": full_name, "day": day, "month": month, "year": year,
|
|
26
27
|
"hour": hour, "min": min, "sec": sec, "gender": gender,
|
|
27
28
|
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
28
|
-
"lan": lan, "house_system": house_system,
|
|
29
|
+
"lan": lan, "house_system": resolve_house_system(house_system),
|
|
29
30
|
}
|
|
30
31
|
d.update(extra)
|
|
31
32
|
return d
|
|
@@ -48,15 +49,25 @@ class ProgressionsApi:
|
|
|
48
49
|
return self._c.post(HOST, "/western-api/v1/planetary-arc-directions", self._birth(**kw))
|
|
49
50
|
|
|
50
51
|
def secondary_progressions(
|
|
51
|
-
self,
|
|
52
|
+
self,
|
|
52
53
|
progressed_day: int, progressed_month: int, progressed_year: int,
|
|
54
|
+
progressed_hour: int, progressed_min: int, progressed_sec: int,
|
|
53
55
|
progressed_type: str,
|
|
56
|
+
planet: Optional[str] = None,
|
|
54
57
|
**kw: Any,
|
|
55
58
|
) -> Dict[str, Any]:
|
|
56
|
-
"""Secondary Progressions.
|
|
57
|
-
|
|
59
|
+
"""Secondary Progressions.
|
|
60
|
+
|
|
61
|
+
``progressed_day/month/year/hour/min/sec`` and ``progressed_type`` are
|
|
62
|
+
required by the API; ``planet`` is optional.
|
|
63
|
+
"""
|
|
58
64
|
kw["progressed_day"] = progressed_day
|
|
59
65
|
kw["progressed_month"] = progressed_month
|
|
60
66
|
kw["progressed_year"] = progressed_year
|
|
67
|
+
kw["progressed_hour"] = progressed_hour
|
|
68
|
+
kw["progressed_min"] = progressed_min
|
|
69
|
+
kw["progressed_sec"] = progressed_sec
|
|
61
70
|
kw["progressed_type"] = progressed_type
|
|
71
|
+
if planet is not None:
|
|
72
|
+
kw["planet"] = planet
|
|
62
73
|
return self._c.post(HOST, "/western-api/v1/secondary-progressions", self._birth(**kw))
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from typing import Any, Dict
|
|
4
4
|
|
|
5
5
|
from ..client import BaseClient
|
|
6
|
+
from ._house_system import resolve_house_system
|
|
6
7
|
|
|
7
8
|
HOST = "astroapi-4"
|
|
8
9
|
HOST8 = "astroapi-8"
|
|
@@ -38,7 +39,7 @@ class SynastryApi:
|
|
|
38
39
|
"p2_year": p2_year, "p2_hour": p2_hour, "p2_min": p2_min,
|
|
39
40
|
"p2_sec": p2_sec, "p2_gender": p2_gender, "p2_place": p2_place,
|
|
40
41
|
"p2_lat": p2_lat, "p2_lon": p2_lon, "p2_tzone": p2_tzone,
|
|
41
|
-
"lan": lan, "house_system": house_system,
|
|
42
|
+
"lan": lan, "house_system": resolve_house_system(house_system),
|
|
42
43
|
}
|
|
43
44
|
d.update(extra)
|
|
44
45
|
return d
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"""Western API - Transit endpoints (astroapi-4 and astroapi-8)."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
|
|
5
|
+
from ..client import BaseClient
|
|
6
|
+
from ._house_system import resolve_house_system
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TransitApi:
|
|
10
|
+
"""Transit endpoints for Western astrology."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, client: BaseClient) -> None:
|
|
13
|
+
self._c = client
|
|
14
|
+
|
|
15
|
+
# ------------------------------------------------------------------ #
|
|
16
|
+
# Payload helpers
|
|
17
|
+
# ------------------------------------------------------------------ #
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def _birth(
|
|
21
|
+
full_name: str, day: int, month: int, year: int,
|
|
22
|
+
hour: int, min: int, sec: int, gender: str,
|
|
23
|
+
place: str, lat: float, lon: float, tzone: float,
|
|
24
|
+
lan: str = "en", house_system: str = "placidus",
|
|
25
|
+
**extra: Any,
|
|
26
|
+
) -> Dict[str, Any]:
|
|
27
|
+
d: Dict[str, Any] = {
|
|
28
|
+
"full_name": full_name, "day": day, "month": month, "year": year,
|
|
29
|
+
"hour": hour, "min": min, "sec": sec, "gender": gender,
|
|
30
|
+
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
31
|
+
"lan": lan, "house_system": resolve_house_system(house_system),
|
|
32
|
+
}
|
|
33
|
+
d.update(extra)
|
|
34
|
+
return d
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def _transit_dt(
|
|
38
|
+
transit_day: int, transit_month: int, transit_year: int,
|
|
39
|
+
transit_hour: int = 0, transit_min: int = 0, transit_sec: int = 0,
|
|
40
|
+
) -> Dict[str, Any]:
|
|
41
|
+
return {
|
|
42
|
+
"transit_day": transit_day, "transit_month": transit_month,
|
|
43
|
+
"transit_year": transit_year, "transit_hour": transit_hour,
|
|
44
|
+
"transit_min": transit_min, "transit_sec": transit_sec,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def _transit_loc(
|
|
49
|
+
transit_lat: float, transit_lon: float,
|
|
50
|
+
transit_tzone: float, transit_place: str,
|
|
51
|
+
) -> Dict[str, Any]:
|
|
52
|
+
return {
|
|
53
|
+
"transit_lat": transit_lat, "transit_lon": transit_lon,
|
|
54
|
+
"transit_tzone": transit_tzone, "transit_place": transit_place,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
def _post4(self, path: str, **kw: Any) -> Dict[str, Any]:
|
|
58
|
+
return self._c.post("astroapi-4", path, self._birth(**kw))
|
|
59
|
+
|
|
60
|
+
def _post8(self, path: str, **kw: Any) -> Dict[str, Any]:
|
|
61
|
+
return self._c.post("astroapi-8", path, self._birth(**kw))
|
|
62
|
+
|
|
63
|
+
# ------------------------------------------------------------------ #
|
|
64
|
+
# astroapi-4 transit endpoints
|
|
65
|
+
# ------------------------------------------------------------------ #
|
|
66
|
+
|
|
67
|
+
def basic(
|
|
68
|
+
self,
|
|
69
|
+
transit_day: int, transit_month: int, transit_year: int,
|
|
70
|
+
transit_hour: int = 0, transit_min: int = 0, transit_sec: int = 0,
|
|
71
|
+
**kw: Any,
|
|
72
|
+
) -> Dict[str, Any]:
|
|
73
|
+
"""Transit Basic. Requires the transit date; time defaults to 00:00:00."""
|
|
74
|
+
payload = self._birth(**kw)
|
|
75
|
+
payload.update(self._transit_dt(
|
|
76
|
+
transit_day, transit_month, transit_year,
|
|
77
|
+
transit_hour, transit_min, transit_sec,
|
|
78
|
+
))
|
|
79
|
+
return self._c.post("astroapi-4", "/western-api/v1/transit/basic", payload)
|
|
80
|
+
|
|
81
|
+
def daily(self, **kw: Any) -> Dict[str, Any]:
|
|
82
|
+
"""Transit Daily."""
|
|
83
|
+
return self._post4("/western-api/v1/transit/daily", **kw)
|
|
84
|
+
|
|
85
|
+
def weekly(self, transit_planet: str, **kw: Any) -> Dict[str, Any]:
|
|
86
|
+
"""Transit Weekly. Requires the transiting planet (e.g. 'moon')."""
|
|
87
|
+
kw["transit_planet"] = transit_planet
|
|
88
|
+
return self._post4("/western-api/v1/transit/weekly", **kw)
|
|
89
|
+
|
|
90
|
+
def house(
|
|
91
|
+
self,
|
|
92
|
+
transit_day: int, transit_month: int, transit_year: int,
|
|
93
|
+
transit_lat: float, transit_lon: float,
|
|
94
|
+
transit_tzone: float, transit_place: str,
|
|
95
|
+
transit_hour: int = 0, transit_min: int = 0, transit_sec: int = 0,
|
|
96
|
+
**kw: Any,
|
|
97
|
+
) -> Dict[str, Any]:
|
|
98
|
+
"""Transit House. Requires transit date + location; time defaults to 00:00:00."""
|
|
99
|
+
payload = self._birth(**kw)
|
|
100
|
+
payload.update(self._transit_dt(
|
|
101
|
+
transit_day, transit_month, transit_year,
|
|
102
|
+
transit_hour, transit_min, transit_sec,
|
|
103
|
+
))
|
|
104
|
+
payload.update(self._transit_loc(
|
|
105
|
+
transit_lat, transit_lon, transit_tzone, transit_place,
|
|
106
|
+
))
|
|
107
|
+
return self._c.post("astroapi-4", "/western-api/v1/transit/house", payload)
|
|
108
|
+
|
|
109
|
+
# ------------------------------------------------------------------ #
|
|
110
|
+
# astroapi-8 transit endpoints
|
|
111
|
+
# ------------------------------------------------------------------ #
|
|
112
|
+
|
|
113
|
+
def monthly(
|
|
114
|
+
self,
|
|
115
|
+
transit_planet: str, transit_month: int, transit_year: int,
|
|
116
|
+
transit_lat: float, transit_lon: float,
|
|
117
|
+
transit_tzone: float, transit_place: str,
|
|
118
|
+
**kw: Any,
|
|
119
|
+
) -> Dict[str, Any]:
|
|
120
|
+
"""Transit Monthly. Requires the transiting planet, month, year and location."""
|
|
121
|
+
payload = self._birth(**kw)
|
|
122
|
+
payload.update({
|
|
123
|
+
"transit_planet": transit_planet,
|
|
124
|
+
"transit_month": transit_month, "transit_year": transit_year,
|
|
125
|
+
})
|
|
126
|
+
payload.update(self._transit_loc(
|
|
127
|
+
transit_lat, transit_lon, transit_tzone, transit_place,
|
|
128
|
+
))
|
|
129
|
+
return self._c.post("astroapi-8", "/western-api/v2/transit/monthly", payload)
|
|
130
|
+
|
|
131
|
+
def full(
|
|
132
|
+
self,
|
|
133
|
+
transit_planet: str,
|
|
134
|
+
transit_day: int, transit_month: int, transit_year: int,
|
|
135
|
+
transit_lat: float, transit_lon: float,
|
|
136
|
+
transit_tzone: float, transit_place: str,
|
|
137
|
+
transit_hour: int = 0, transit_min: int = 0, transit_sec: int = 0,
|
|
138
|
+
**kw: Any,
|
|
139
|
+
) -> Dict[str, Any]:
|
|
140
|
+
"""Full Transit. Requires the transiting planet, transit date and location."""
|
|
141
|
+
payload = self._birth(**kw)
|
|
142
|
+
payload["transit_planet"] = transit_planet
|
|
143
|
+
payload.update(self._transit_dt(
|
|
144
|
+
transit_day, transit_month, transit_year,
|
|
145
|
+
transit_hour, transit_min, transit_sec,
|
|
146
|
+
))
|
|
147
|
+
payload.update(self._transit_loc(
|
|
148
|
+
transit_lat, transit_lon, transit_tzone, transit_place,
|
|
149
|
+
))
|
|
150
|
+
return self._c.post("astroapi-8", "/western-api/v1/full-transit", payload)
|
|
151
|
+
|
|
152
|
+
def planet_retrograde(
|
|
153
|
+
self, planet: str, month: int, year: int,
|
|
154
|
+
place: str, lat: float, lon: float, tzone: float,
|
|
155
|
+
) -> Dict[str, Any]:
|
|
156
|
+
"""Planet Retrograde Transit."""
|
|
157
|
+
return self._c.post("astroapi-8", "/western-api/v1/planet-retrograde-transit", {
|
|
158
|
+
"planet": planet, "month": month, "year": year,
|
|
159
|
+
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
def planetary_ingress(
|
|
163
|
+
self, planet: str, month: int, year: int,
|
|
164
|
+
place: str, lat: float, lon: float, tzone: float,
|
|
165
|
+
) -> Dict[str, Any]:
|
|
166
|
+
"""Planetary Ingress."""
|
|
167
|
+
return self._c.post("astroapi-8", "/western-api/v1/planetary-ingress", {
|
|
168
|
+
"planet": planet, "month": month, "year": year,
|
|
169
|
+
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
def planet_combustion(
|
|
173
|
+
self, planet: str, month: int, year: int,
|
|
174
|
+
place: str, lat: float, lon: float, tzone: float,
|
|
175
|
+
) -> Dict[str, Any]:
|
|
176
|
+
"""Planet Combustion Transit."""
|
|
177
|
+
return self._c.post("astroapi-8", "/western-api/v1/planet-combustion-transit", {
|
|
178
|
+
"planet": planet, "month": month, "year": year,
|
|
179
|
+
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
def wheel_chart(
|
|
183
|
+
self,
|
|
184
|
+
transit_day: int, transit_month: int, transit_year: int,
|
|
185
|
+
transit_lat: float, transit_lon: float,
|
|
186
|
+
transit_tzone: float, transit_place: str,
|
|
187
|
+
transit_hour: int = 0, transit_min: int = 0, transit_sec: int = 0,
|
|
188
|
+
**kw: Any,
|
|
189
|
+
) -> Dict[str, Any]:
|
|
190
|
+
"""Transit Wheel Chart. Requires transit date + location."""
|
|
191
|
+
payload = self._birth(**kw)
|
|
192
|
+
payload.update(self._transit_dt(
|
|
193
|
+
transit_day, transit_month, transit_year,
|
|
194
|
+
transit_hour, transit_min, transit_sec,
|
|
195
|
+
))
|
|
196
|
+
payload.update(self._transit_loc(
|
|
197
|
+
transit_lat, transit_lon, transit_tzone, transit_place,
|
|
198
|
+
))
|
|
199
|
+
return self._c.post("astroapi-8", "/western-api/v1/transit/wheel-chart", payload)
|
|
200
|
+
|
|
201
|
+
def planetary_positions(
|
|
202
|
+
self,
|
|
203
|
+
transit_day: int, transit_month: int, transit_year: int,
|
|
204
|
+
transit_lat: float, transit_lon: float,
|
|
205
|
+
transit_tzone: float, transit_place: str,
|
|
206
|
+
transit_hour: int = 0, transit_min: int = 0, transit_sec: int = 0,
|
|
207
|
+
**kw: Any,
|
|
208
|
+
) -> Dict[str, Any]:
|
|
209
|
+
"""Transit Planetary Positions. Requires transit date + location."""
|
|
210
|
+
payload = self._birth(**kw)
|
|
211
|
+
payload.update(self._transit_dt(
|
|
212
|
+
transit_day, transit_month, transit_year,
|
|
213
|
+
transit_hour, transit_min, transit_sec,
|
|
214
|
+
))
|
|
215
|
+
payload.update(self._transit_loc(
|
|
216
|
+
transit_lat, transit_lon, transit_tzone, transit_place,
|
|
217
|
+
))
|
|
218
|
+
return self._c.post("astroapi-8", "/western-api/v1/transit/planetary-positions", payload)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: divineapi
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Official Python SDK for the Divine API - Astrology, Numerology, Tarot & more
|
|
5
5
|
Author-email: Divine API <support@divineapi.com>
|
|
6
6
|
License: MIT
|
|
@@ -51,9 +51,9 @@ from divineapi import DivineApi
|
|
|
51
51
|
|
|
52
52
|
client = DivineApi(api_key="your-api-key", auth_token="your-bearer-token")
|
|
53
53
|
|
|
54
|
-
# Daily Horoscope
|
|
54
|
+
# Daily Horoscope (h_day = today, tomorrow, or yesterday)
|
|
55
55
|
result = client.horoscope.daily(
|
|
56
|
-
sign="aries",
|
|
56
|
+
sign="aries", h_day="today", tzone=5.5
|
|
57
57
|
)
|
|
58
58
|
print(result)
|
|
59
59
|
```
|
|
@@ -64,10 +64,11 @@ print(result)
|
|
|
64
64
|
|
|
65
65
|
```python
|
|
66
66
|
# Daily / Weekly / Monthly / Yearly Horoscope
|
|
67
|
-
|
|
68
|
-
client.horoscope.
|
|
69
|
-
client.horoscope.
|
|
70
|
-
client.horoscope.
|
|
67
|
+
# daily h_day = today / tomorrow / yesterday; weekly/monthly/yearly = current / prev / next
|
|
68
|
+
client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
69
|
+
client.horoscope.weekly(sign="leo", week="current", tzone=5.5)
|
|
70
|
+
client.horoscope.monthly(sign="cancer", month="current", tzone=5.5)
|
|
71
|
+
client.horoscope.yearly(sign="virgo", year="current", tzone=5.5)
|
|
71
72
|
|
|
72
73
|
# Chinese & Numerology Horoscope
|
|
73
74
|
client.horoscope.chinese(sign="rat", h_day="today", tzone=5.5)
|
|
@@ -140,6 +141,14 @@ client.indian.kundli.lal_kitab_varshphal_chart(2026, **birth)
|
|
|
140
141
|
# Lal Kitab dasha content (no birth data needed)
|
|
141
142
|
client.indian.kundli.lal_kitab_mahadasha_content(maha_dasha="saturn")
|
|
142
143
|
client.indian.kundli.lal_kitab_antardasha_content(maha_dasha="saturn", antar_dasha="mercury")
|
|
144
|
+
|
|
145
|
+
# Additional kundli analysis
|
|
146
|
+
client.indian.kundli.vargottama_planets(**birth)
|
|
147
|
+
client.indian.kundli.bhav_bala(**birth)
|
|
148
|
+
client.indian.kundli.shani_ashtam_shani(**birth)
|
|
149
|
+
client.indian.kundli.bhava_analysis(**birth)
|
|
150
|
+
client.indian.kundli.bhava_group_predictions(**birth)
|
|
151
|
+
client.indian.kundli.planet_remedies("sun", **birth) # analysis_planet + birth
|
|
143
152
|
```
|
|
144
153
|
|
|
145
154
|
### Indian Astrology - Match Making
|
|
@@ -164,8 +173,9 @@ client.indian.festival.chaitra_festivals(
|
|
|
164
173
|
client.indian.festival.english_calendar(
|
|
165
174
|
year=2024, month=3, place="Delhi", lat=28.6, lon=77.2, tzone=5.5
|
|
166
175
|
)
|
|
176
|
+
# festival is a lowercase snake_case slug from the Divine festival list
|
|
167
177
|
client.indian.festival.find_festival(
|
|
168
|
-
festival="
|
|
178
|
+
festival="maha_shivratri", year=2024,
|
|
169
179
|
place="Delhi", lat=28.6, lon=77.2, tzone=5.5
|
|
170
180
|
)
|
|
171
181
|
client.indian.festival.malayalam_festivals(
|
|
@@ -193,7 +203,7 @@ client.western.natal.house_cusps(**birth_w)
|
|
|
193
203
|
client.western.natal.aspect_table(**birth_w)
|
|
194
204
|
client.western.natal.natal_wheel_chart(**birth_w)
|
|
195
205
|
client.western.natal.natal_insights(**birth_w)
|
|
196
|
-
client.western.natal.dominants(method="
|
|
206
|
+
client.western.natal.dominants(method="TRADITIONAL", **birth_w)
|
|
197
207
|
```
|
|
198
208
|
|
|
199
209
|
### Western Astrology - Synastry
|
|
@@ -252,7 +262,7 @@ client.lifestyle.astro_chic_picks(sign="virgo", h_day="today", tzone=5.5)
|
|
|
252
262
|
### Calculators
|
|
253
263
|
|
|
254
264
|
```python
|
|
255
|
-
client.calculators.flames(
|
|
265
|
+
client.calculators.flames(your_name="John", partner_name="Jane")
|
|
256
266
|
client.calculators.love_calculator(
|
|
257
267
|
your_name="John", partner_name="Jane",
|
|
258
268
|
your_gender="male", partner_gender="female",
|
|
@@ -262,11 +272,15 @@ client.calculators.love_calculator(
|
|
|
262
272
|
### PDF Reports
|
|
263
273
|
|
|
264
274
|
```python
|
|
275
|
+
# The six branding fields (company_url, logo_url, footer_text, company_name,
|
|
276
|
+
# company_email, company_bio) are REQUIRED by the PDF backend.
|
|
265
277
|
client.pdf.kundali_sampoorna(
|
|
266
278
|
full_name="John", day=1, month=1, year=1990,
|
|
267
279
|
hour=10, min=30, sec=0, gender="male",
|
|
268
280
|
place="Mumbai", lat=19.07, lon=72.87, tzone=5.5,
|
|
269
281
|
company_name="AstroCo", company_url="https://example.com",
|
|
282
|
+
company_email="hello@example.com", company_bio="We do astrology.",
|
|
283
|
+
logo_url="https://example.com/logo.png", footer_text="(c) AstroCo",
|
|
270
284
|
)
|
|
271
285
|
```
|
|
272
286
|
|
|
@@ -278,7 +292,7 @@ from divineapi import DivineApi, AuthenticationError, ValidationError, RateLimit
|
|
|
278
292
|
client = DivineApi(api_key="...", auth_token="...")
|
|
279
293
|
|
|
280
294
|
try:
|
|
281
|
-
result = client.horoscope.daily(sign="aries",
|
|
295
|
+
result = client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
282
296
|
except AuthenticationError as e:
|
|
283
297
|
print(f"Auth failed: {e}")
|
|
284
298
|
except ValidationError as e:
|
|
@@ -291,7 +305,7 @@ except RateLimitError as e:
|
|
|
291
305
|
|
|
292
306
|
```python
|
|
293
307
|
with DivineApi(api_key="...", auth_token="...") as client:
|
|
294
|
-
result = client.horoscope.daily(sign="aries",
|
|
308
|
+
result = client.horoscope.daily(sign="aries", h_day="today", tzone=5.5)
|
|
295
309
|
```
|
|
296
310
|
|
|
297
311
|
## Configuration
|
|
@@ -22,6 +22,7 @@ divineapi/indian/kundli.py
|
|
|
22
22
|
divineapi/indian/match_making.py
|
|
23
23
|
divineapi/indian/panchang.py
|
|
24
24
|
divineapi/western/__init__.py
|
|
25
|
+
divineapi/western/_house_system.py
|
|
25
26
|
divineapi/western/composite.py
|
|
26
27
|
divineapi/western/natal.py
|
|
27
28
|
divineapi/western/planet_returns.py
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
"""Western API - Transit endpoints (astroapi-4 and astroapi-8)."""
|
|
2
|
-
|
|
3
|
-
from typing import Any, Dict
|
|
4
|
-
|
|
5
|
-
from ..client import BaseClient
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class TransitApi:
|
|
9
|
-
"""Transit endpoints for Western astrology."""
|
|
10
|
-
|
|
11
|
-
def __init__(self, client: BaseClient) -> None:
|
|
12
|
-
self._c = client
|
|
13
|
-
|
|
14
|
-
# ------------------------------------------------------------------ #
|
|
15
|
-
# Birth-data helper
|
|
16
|
-
# ------------------------------------------------------------------ #
|
|
17
|
-
|
|
18
|
-
@staticmethod
|
|
19
|
-
def _birth(
|
|
20
|
-
full_name: str, day: int, month: int, year: int,
|
|
21
|
-
hour: int, min: int, sec: int, gender: str,
|
|
22
|
-
place: str, lat: float, lon: float, tzone: float,
|
|
23
|
-
lan: str = "en", house_system: str = "placidus",
|
|
24
|
-
**extra: Any,
|
|
25
|
-
) -> Dict[str, Any]:
|
|
26
|
-
d: Dict[str, Any] = {
|
|
27
|
-
"full_name": full_name, "day": day, "month": month, "year": year,
|
|
28
|
-
"hour": hour, "min": min, "sec": sec, "gender": gender,
|
|
29
|
-
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
30
|
-
"lan": lan, "house_system": house_system,
|
|
31
|
-
}
|
|
32
|
-
d.update(extra)
|
|
33
|
-
return d
|
|
34
|
-
|
|
35
|
-
def _post4(self, path: str, **kw: Any) -> Dict[str, Any]:
|
|
36
|
-
return self._c.post("astroapi-4", path, self._birth(**kw))
|
|
37
|
-
|
|
38
|
-
def _post8(self, path: str, **kw: Any) -> Dict[str, Any]:
|
|
39
|
-
return self._c.post("astroapi-8", path, self._birth(**kw))
|
|
40
|
-
|
|
41
|
-
# ------------------------------------------------------------------ #
|
|
42
|
-
# astroapi-4 transit endpoints
|
|
43
|
-
# ------------------------------------------------------------------ #
|
|
44
|
-
|
|
45
|
-
def basic(self, **kw: Any) -> Dict[str, Any]:
|
|
46
|
-
"""Transit Basic (pass transit_day/month/year/hour/min/sec via **kw)."""
|
|
47
|
-
return self._post4("/western-api/v1/transit/basic", **kw)
|
|
48
|
-
|
|
49
|
-
def daily(self, **kw: Any) -> Dict[str, Any]:
|
|
50
|
-
"""Transit Daily."""
|
|
51
|
-
return self._post4("/western-api/v1/transit/daily", **kw)
|
|
52
|
-
|
|
53
|
-
def weekly(self, transit_planet: str, **kw: Any) -> Dict[str, Any]:
|
|
54
|
-
"""Transit Weekly."""
|
|
55
|
-
kw["transit_planet"] = transit_planet
|
|
56
|
-
return self._post4("/western-api/v1/transit/weekly", **kw)
|
|
57
|
-
|
|
58
|
-
def house(self, **kw: Any) -> Dict[str, Any]:
|
|
59
|
-
"""Transit House (pass full transit params via **kw)."""
|
|
60
|
-
return self._post4("/western-api/v1/transit/house", **kw)
|
|
61
|
-
|
|
62
|
-
# ------------------------------------------------------------------ #
|
|
63
|
-
# astroapi-8 transit endpoints
|
|
64
|
-
# ------------------------------------------------------------------ #
|
|
65
|
-
|
|
66
|
-
def monthly(self, **kw: Any) -> Dict[str, Any]:
|
|
67
|
-
"""Transit Monthly (pass extensive transit params via **kw)."""
|
|
68
|
-
return self._post8("/western-api/v2/transit/monthly", **kw)
|
|
69
|
-
|
|
70
|
-
def full(self, **kw: Any) -> Dict[str, Any]:
|
|
71
|
-
"""Full Transit (pass extensive transit params via **kw)."""
|
|
72
|
-
return self._post8("/western-api/v1/full-transit", **kw)
|
|
73
|
-
|
|
74
|
-
def planet_retrograde(
|
|
75
|
-
self, planet: str, month: int, year: int,
|
|
76
|
-
place: str, lat: float, lon: float, tzone: float,
|
|
77
|
-
) -> Dict[str, Any]:
|
|
78
|
-
"""Planet Retrograde Transit."""
|
|
79
|
-
return self._c.post("astroapi-8", "/western-api/v1/planet-retrograde-transit", {
|
|
80
|
-
"planet": planet, "month": month, "year": year,
|
|
81
|
-
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
def planetary_ingress(
|
|
85
|
-
self, planet: str, month: int, year: int,
|
|
86
|
-
place: str, lat: float, lon: float, tzone: float,
|
|
87
|
-
) -> Dict[str, Any]:
|
|
88
|
-
"""Planetary Ingress."""
|
|
89
|
-
return self._c.post("astroapi-8", "/western-api/v1/planetary-ingress", {
|
|
90
|
-
"planet": planet, "month": month, "year": year,
|
|
91
|
-
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
def planet_combustion(
|
|
95
|
-
self, planet: str, month: int, year: int,
|
|
96
|
-
place: str, lat: float, lon: float, tzone: float,
|
|
97
|
-
) -> Dict[str, Any]:
|
|
98
|
-
"""Planet Combustion Transit."""
|
|
99
|
-
return self._c.post("astroapi-8", "/western-api/v1/planet-combustion-transit", {
|
|
100
|
-
"planet": planet, "month": month, "year": year,
|
|
101
|
-
"place": place, "lat": lat, "lon": lon, "tzone": tzone,
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
def wheel_chart(self, **kw: Any) -> Dict[str, Any]:
|
|
105
|
-
"""Transit Wheel Chart."""
|
|
106
|
-
return self._post8("/western-api/v1/transit/wheel-chart", **kw)
|
|
107
|
-
|
|
108
|
-
def planetary_positions(self, **kw: Any) -> Dict[str, Any]:
|
|
109
|
-
"""Transit Planetary Positions."""
|
|
110
|
-
return self._post8("/western-api/v1/transit/planetary-positions", **kw)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|