Skip to content

Commit 9c797b6

Browse files
committed
fix(docs): verify all Python examples in README + AGENTS against spec, add agent quality guidelines
1 parent 0294092 commit 9c797b6

2 files changed

Lines changed: 25 additions & 12 deletions

File tree

AGENTS.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ roxy = create_roxy("your-api-key")
1616

1717
`create_roxy` sets the base URL (`https://roxyapi.com/api/v2`) and auth header automatically. Returns a `Roxy` instance with namespaced domain properties.
1818

19+
## Quality guidelines for agents
20+
21+
- Every method returns `dict[str, Any]`. Access fields with `result["key"]["subkey"]`, never `result.key.subkey` (Python will raise `AttributeError: 'dict' object has no attribute ...`).
22+
- Method names are snake_case versions of the OpenAPI operationId (e.g. `castThreeCard` -> `cast_three_card`, `analyzeNumberSequence` -> `analyze_number_sequence`). Every sync method has an `_async` variant; use `await` with the async variants.
23+
- Param names are snake_case versions of the spec param names (`fullName` -> `full_name`, `birthDate` -> `birth_date`, `houseSystem` -> `house_system`). All params are keyword-only.
24+
- When in doubt about a method or kwarg, check `roxy_sdk.factory` directly or run `python -c "from roxy_sdk import Roxy; help(Roxy)"` - the generated signatures are the contract.
25+
- Response field names match the OpenAPI spec's response schema exactly. Never invent or pluralize. If a field isn't in the spec, it isn't in the response.
26+
- Strings everywhere: `date` is `"YYYY-MM-DD"`, `time` is `"HH:MM:SS"`, `timezone` is an IANA name (`"Asia/Kolkata"`, `"America/New_York"`) - the server resolves DST for the chart date. `number` (angel) is `"1111"`, `month` (birthstone) is `"4"`, `number` (hexagram) is `"1"`. Numeric kwargs are only `latitude`, `longitude`, `year`, `month` (numerology), `day`, `count` (tarot draw).
27+
- Inside `person1` / `person2` dicts any value type works because the kwarg is typed `dict[str, Any]`; only the top-level `timezone` kwarg needs string form.
28+
1929
## Critical rule: geocode before any chart endpoint
2030

2131
Every chart, horoscope, panchang, dasha, dosha, navamsa, KP, synastry, compatibility, and natal endpoint needs `latitude`, `longitude`, and (for Western) `timezone`. **Never ask the user for coordinates.** Always call `roxy.location.search_cities` first.
@@ -90,7 +100,7 @@ Most valuable endpoints are POST:
90100
```python
91101
natal = roxy.astrology.generate_natal_chart(
92102
date="1990-01-15", time="14:30:00",
93-
latitude=28.6139, longitude=77.209, timezone=5.5,
103+
latitude=28.6139, longitude=77.209, timezone="Asia/Kolkata",
94104
)
95105

96106
kundli = roxy.vedic_astrology.generate_birth_chart(
@@ -175,7 +185,7 @@ Ordered by domain priority (Western, Vedic, Numerology, Tarot, Biorhythm, I Chin
175185
| Biorhythm compatibility | `roxy.biorhythm.calculate_bio_compatibility(person1, person2)` |
176186
| Daily hexagram | `roxy.iching.get_daily_hexagram(seed="user-123")` |
177187
| Cast I Ching reading | `roxy.iching.cast_reading()` |
178-
| Hexagram detail | `roxy.iching.get_hexagram(number=1)` |
188+
| Hexagram detail | `roxy.iching.get_hexagram(number="1")` |
179189
| Crystal by zodiac | `roxy.crystals.get_crystals_by_zodiac(sign="aries")` |
180190
| Crystal by chakra | `roxy.crystals.get_crystals_by_chakra(chakra="heart")` |
181191
| Dream symbol lookup | `roxy.dreams.get_dream_symbol(id="flying")` |
@@ -191,7 +201,7 @@ These are the fields AI agents most often get wrong. Copy the format column exac
191201

192202
| Field | Format | Good | Bad |
193203
|-------|--------|------|-----|
194-
| `timezone` | Decimal hours (float) OR IANA string | `5.5`, `-5`, `0` (decimal) OR `"Asia/Kolkata"`, `"America/New_York"` (IANA, resolved to DST-correct offset for the chart date) | `"5:30"`, `"+0530"`, `"GMT-5"`, partial names |
204+
| `timezone` | IANA string (typed kwarg) OR decimal number (inside a `dict[str, Any]`) | `"Asia/Kolkata"`, `"America/New_York"`, `"Europe/London"` as the top-level `timezone=` kwarg (server resolves to the DST-correct offset for the chart date). Decimal hours (`5.5`, `-5`, `0`) work as JSON numbers and are accepted only inside `person1`/`person2` dicts because the dict is typed `dict[str, Any]` - the top-level `timezone=` kwarg is typed `str`, so a quoted decimal like `"5.5"` is rejected server-side (validation_error). | `"5.5"` as `timezone=` (rejected, server expects IANA string or a JSON number), `"5:30"`, `"+0530"`, `"GMT-5"` |
195205
| `date` | ISO date string | `"1990-01-15"` | `"Jan 15 1990"`, `datetime.now()`, `"15/01/1990"`, `"1990-1-15"` |
196206
| `time` | 24-hour string | `"14:30:00"`, `"09:00:00"` | `"2:30 PM"`, `"14:30"` (no seconds), `"9:0:0"` (no leading zeros) |
197207
| `latitude` | Decimal degrees (float) | `28.6139` (Delhi), `-33.8688` (Sydney), `40.7128` (NYC) | `"28°36'N"`, `"28 36 50"`, strings |
@@ -212,6 +222,9 @@ These are the fields AI agents most often get wrong. Copy the format column exac
212222

213223
### Timezone cheat sheet (most-asked locations)
214224

225+
Values are decimal hours. For the typed top-level `timezone=` kwarg, pass the IANA name from `roxy.location.search_cities` (`timezone="Asia/Kolkata"`) - the server resolves it to the correct DST offset for the chart date. Inside a `person1`/`person2` dict the bare decimal works because the dict is typed `dict[str, Any]`, so the JSON-number form below is accepted.
226+
227+
215228
| Region | Decimal | Region | Decimal |
216229
|--------|---------|--------|---------|
217230
| UTC / London (winter) | `0` | Dubai | `4` |
@@ -260,7 +273,7 @@ Use the SDK for typed Python apps. Use MCP for AI agents (Claude Desktop, Cursor
260273
- **Async methods end with `_async`.** Every sync method has a matching async variant.
261274
- **Do not expose API keys client-side.** Call Roxy from server code only.
262275
- **Date format is `YYYY-MM-DD`, time is `HH:MM:SS`.** Both are strings.
263-
- **Western `timezone` is required** (decimal hours, `-5` for EST, `5.5` for IST, `0` for UTC). Vedic endpoints accept an optional `timezone` that defaults to `5.5` (IST).
276+
- **Western `timezone` is required** as an IANA string (`"Asia/Kolkata"`, `"America/New_York"`, `"Europe/London"`, `"UTC"`); the server resolves it to the DST-correct offset for the chart date. Vedic endpoints accept an optional `timezone` (same form) that defaults to IST when omitted. The decimal-number form (`5.5`) is also accepted by the API, but only inside `person1`/`person2` dicts - the top-level `timezone=` kwarg is typed `str`.
264277
- **Errors raise `RoxyAPIError`.** Catch it and check `e.code`, `e.error`, and `e.status_code`.
265278
- **Switch on `code`, not `error`.** Codes are stable. Messages may change.
266279

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ The global astrology app market is $6.27B and almost entirely Western. These end
114114
# Natal chart. The #1 Western query, called on every onboarding.
115115
natal = roxy.astrology.generate_natal_chart(
116116
date="1990-01-15", time="14:30:00",
117-
latitude=28.6139, longitude=77.209, timezone=5.5,
117+
latitude=28.6139, longitude=77.209, timezone="Asia/Kolkata",
118118
)
119119

120120
# Daily horoscope. Highest per-user call frequency in the catalog, drives DAUs and push.
@@ -126,7 +126,7 @@ synastry = roxy.astrology.calculate_synastry(
126126
person1={"date": "1990-01-15", "time": "14:30:00", "latitude": 28.61, "longitude": 77.20, "timezone": 5.5},
127127
person2={"date": "1992-07-22", "time": "09:00:00", "latitude": 19.07, "longitude": 72.87, "timezone": 5.5},
128128
)
129-
# synastry["compatibilityScore"], synastry["interAspects"], synastry["strengths"]
129+
# synastry["compatibilityScore"], synastry["interAspects"], synastry["analysis"]["strengths"]
130130

131131
# Moon phase. Viral for wellness, cycle-tracking, meditation apps.
132132
moon = roxy.astrology.get_current_moon_phase()
@@ -140,7 +140,7 @@ The depth moat. India astrology market: $163M in 2024, projected $1.8B by 2030 (
140140
# Vedic kundli. Top India astrology keyword. Entry point for every Jyotish product.
141141
kundli = roxy.vedic_astrology.generate_birth_chart(
142142
date="1990-01-15", time="14:30:00",
143-
latitude=28.6139, longitude=77.209, timezone=5.5,
143+
latitude=28.6139, longitude=77.209, timezone="Asia/Kolkata",
144144
)
145145

146146
# Panchang. Tithi, nakshatra, yoga, karana, rahu kaal, abhijit muhurta in one call.
@@ -151,13 +151,13 @@ panchang = roxy.vedic_astrology.get_detailed_panchang(
151151
# Vimshottari dasha. Highest-value single-shot Vedic query.
152152
dasha = roxy.vedic_astrology.get_current_dasha(
153153
date="1990-01-15", time="14:30:00",
154-
latitude=28.6139, longitude=77.209, timezone=5.5,
154+
latitude=28.6139, longitude=77.209, timezone="Asia/Kolkata",
155155
)
156156

157157
# Mangal Dosha. Most-asked matrimonial question in India.
158158
dosha = roxy.vedic_astrology.check_manglik_dosha(
159159
date="1990-01-15", time="14:30:00",
160-
latitude=28.6139, longitude=77.209, timezone=5.5,
160+
latitude=28.6139, longitude=77.209, timezone="Asia/Kolkata",
161161
)
162162

163163
# Guna Milan. 36-point Ashtakoota matrimonial compatibility score.
@@ -168,7 +168,7 @@ milan = roxy.vedic_astrology.calculate_gun_milan(
168168

169169
# KP ruling planets. Horary answers for "will X happen" questions in real time.
170170
kp = roxy.vedic_astrology.get_kp_ruling_planets(
171-
latitude=28.6139, longitude=77.209, timezone=5.5,
171+
latitude=28.6139, longitude=77.209, timezone="Asia/Kolkata",
172172
)
173173
```
174174

@@ -197,7 +197,7 @@ High search volume, evergreen. The tarot card database is the highest per-endpoi
197197
```python
198198
# Daily card. Stickiest tarot feature. Seed per user for deterministic once-per-day behavior.
199199
card = roxy.tarot.get_daily_card(seed="user-42")
200-
# card["card"]["name"], card["card"]["imageUrl"], card["interpretation"]
200+
# card["card"]["name"], card["card"]["imageUrl"], card["dailyMessage"]
201201

202202
# Celtic Cross. Professional-reader spread. Premium-tier, ten positions.
203203
cc = roxy.tarot.cast_celtic_cross(question="What should I focus on?", seed="user-42")
@@ -251,7 +251,7 @@ by_sign = roxy.crystals.get_crystals_by_zodiac(sign="scorpio")
251251
by_chakra = roxy.crystals.get_crystals_by_chakra(chakra="heart")
252252

253253
# Birthstone. Evergreen gift and jewelry SEO.
254-
birthstone = roxy.crystals.get_birthstones(month=4)
254+
birthstone = roxy.crystals.get_birthstones(month="4")
255255
```
256256

257257
### 8. Dream interpretation API (symbol dictionary, search)

0 commit comments

Comments
 (0)