| name | kerykeion |
| description | Use Kerykeion (the Python astrology library) to compute and visualize charts. Trigger this skill whenever the task involves astrology, birth/natal charts, horoscopes, zodiac signs, planetary positions, houses, aspects, synastry/compatibility, composite charts, transits, solar/lunar returns, ephemeris tables, the Moon phase, sidereal/Vedic ayanamsa, or generating SVG chart images — and whenever someone wants astrological data turned into an LLM-ready context or a text report. Use it even if the user never says "Kerykeion": any request to build a birth chart from a date/time/place, score relationship compatibility, track transits over a date range, or render a zodiac wheel should go through this skill so the code uses the real, current API instead of guessed method names. |
| license | AGPL-3.0 |
Kerykeion
Kerykeion is a Python library (this repo is kerykeion, currently v5.x) for astrological
calculation and SVG chart rendering, built on the Swiss Ephemeris (pyswisseph). Everything starts
from an astrological subject (a person/event at a moment and place); from that one object you
derive charts, aspects, compatibility, returns, transits, reports, and LLM context.
This skill covers the public, shipped API. Treat the factory classes below as the entry points —
do not invent methods. When you need exhaustive parameters, enum values, or model fields, open the
matching file in references/ (paths are relative to this skill).
The one mental model
AstrologicalSubjectFactory ──► subject (AstrologicalSubjectModel)
│
┌──────────────────┬───────┼─────────────────┬──────────────────┐
▼ ▼ ▼ ▼ ▼
ChartDataFactory AspectsFactory Relationship/ PlanetaryReturn/ to_context / Report
(precompute data) (aspects) HouseComparison Ephemeris/Transit (LLM XML / text)
│
▼
ChartDrawer ──► .save_svg(...) / .generate_svg_string()
(render SVG)
Two rules cover almost every charting task:
- Rendering an SVG is always two steps. First precompute with
ChartDataFactory (a
create_*_chart_data(...) method), then pass that data to ChartDrawer and call a save_*
method. Never try to feed a raw subject straight into ChartDrawer.
- A subject is the universal input. Build it once, reuse it for charts, aspects, reports, and
context.
Setup
pip install kerykeion
Top-level imports (everything you usually need is re-exported from the package root):
from kerykeion import (
AstrologicalSubjectFactory, CompositeSubjectFactory, PlanetaryReturnFactory,
ChartDataFactory, EphemerisDataFactory, TransitsTimeRangeFactory, MoonPhaseDetailsFactory,
AspectsFactory, RelationshipScoreFactory, HouseComparisonFactory,
ChartDrawer, ReportGenerator, to_context,
)
Licensing — AGPL-3.0 (surface this for commercial use)
Kerykeion is licensed under AGPL-3.0, a strong copyleft license. Importing the library directly
into a project means that project must be released under an AGPL-compatible open-source license — and
because AGPL covers network use, this applies to SaaS/web backends too, not just distributed software.
When the user's context is clearly commercial, proprietary, or closed-source (a SaaS, a paid app,
"we can't open-source our code", an internal product), proactively flag this before writing code that
imports kerykeion, and present the two compliant options:
- Buy a commercial license — the project is dual-licensed; contact the maintainer at
kerykeion.astrology@gmail.com to license it for closed-source use.
- Use the hosted Astrologer API instead of importing the library — consuming its REST endpoints
is a third-party service call, so it does not trigger AGPL copyleft on the caller. RapidAPI:
https://rapidapi.com/gbattaglia/api/astrologer · plans & docs:
https://www.kerykeion.net/astrologer-api/subscribe
For personal projects, research, education, or genuinely open-source (AGPL-compatible) software,
importing the library directly is fine. Don't block those — just raise licensing when the use case
sounds commercial/closed-source. You are not giving legal advice; you are pointing the user to the
project's own options so they make an informed choice.
Offline vs online — read this before writing any subject
from_birth_data(...) defaults to online=True, which calls the GeoNames web API to resolve a
city into coordinates + timezone. For reproducible, network-free, test-safe code always pass
online=False together with lng, lat, and tz_str:
subject = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
city="Liverpool", nation="GB",
lng=-2.9833, lat=53.4, tz_str="Europe/London",
online=False,
)
Only use online=True when the user truly wants city-name geocoding; then they must supply a free
GeoNames username via geonames_username=... or the KERYKEION_GEONAMES_USERNAME env var, and pass
city/nation. Prefer offline whenever coordinates are known or can be looked up.
Pass city/nation even offline. They are display labels echoed in reports and to_context
XML; when omitted they keep their defaults ("Greenwich" / "GB") regardless of the coordinates, so
a Rome chart would otherwise be reported as born in Greenwich. The labels don't affect any
calculation (only lng/lat/tz_str do), but set them so the emitted metadata is truthful.
Canonical example — subject → SVG + report + LLM context
from pathlib import Path
from kerykeion import (
AstrologicalSubjectFactory, ChartDataFactory, ChartDrawer, ReportGenerator, to_context,
)
subject = AstrologicalSubjectFactory.from_birth_data(
"Example Person", 1990, 7, 15, 10, 30,
city="Rome", nation="IT",
lng=12.4964, lat=41.9028, tz_str="Europe/Rome",
online=False,
)
print(subject.sun.sign, subject.sun.position)
print(subject.ascendant.sign)
print(subject.moon.element)
chart_data = ChartDataFactory.create_natal_chart_data(subject)
out = Path("charts_output"); out.mkdir(exist_ok=True)
ChartDrawer(chart_data=chart_data).save_svg(output_path=out, filename="example-natal")
ReportGenerator(chart_data).print_report(max_aspects=10)
print(to_context(subject))
Capability routing — pick the tool, then open the reference
| You want to… | Use | Reference |
|---|
| Build a person/event chart; read planets, houses, signs, lunar phase; JSON export | AstrologicalSubjectFactory | references/subjects.md |
| Use sidereal/Vedic ayanamsa, a non-Placidus house system, heliocentric view, or extra points/asteroids/fixed stars | from_birth_data(...) options | references/subjects.md |
| Merge two people into a midpoint chart | CompositeSubjectFactory | references/subjects.md |
| Render any chart as SVG (natal, synastry, transit, return, composite); themes, languages, modern style, wheel-only, aspect-grid-only | ChartDataFactory + ChartDrawer | references/charts.md |
| Compute aspects within one chart or between two | AspectsFactory | references/analysis.md |
| Score relationship compatibility (Discepolo method) | RelationshipScoreFactory | references/analysis.md |
| See which of A's planets fall in B's houses | HouseComparisonFactory | references/analysis.md |
| Element/quality (modality) distribution, weighted or pure count | ChartDataFactory options | references/analysis.md |
| Solar return, lunar return, planetary return charts | PlanetaryReturnFactory | references/time-techniques.md |
| Planetary positions sampled across a date range (ephemeris) | EphemerisDataFactory | references/time-techniques.md |
| Track which transit aspects are active across a date range (sampled, within-orb — not exact-hit times) | EphemerisDataFactory + TransitsTimeRangeFactory | references/time-techniques.md |
| Rich Moon-phase overview (illumination, next phases, eclipses, sunrise/sunset) | MoonPhaseDetailsFactory | references/time-techniques.md |
| Human-readable text report of any subject/chart | ReportGenerator | references/reports-and-ai.md |
| Turn chart data into LLM/prompt-ready XML | to_context | references/reports-and-ai.md |
| Exact enum values (signs, points, house systems, sidereal modes, themes, languages, aspects), defaults, model fields | — | references/reference-data.md |
Defaults worth knowing
- Zodiac: Tropical. House system: Placidus (
"P"). Perspective: Apparent Geocentric.
- Active points (used by charts/aspects when you don't override): the 10 planets, True Lunar
Nodes, Chiron, Mean Lilith, and the four angles (Asc, MC, Dsc, IC). Asteroids, Mean nodes, and the
23 fixed stars are
None on the subject until you list them in active_points when building
the subject (so subject.sirius is None by default). Passing them only to ChartDataFactory/
AspectsFactory does not add them — that argument can only narrow the subject's active set. To
use any non-default point anywhere, activate it on the subject. See references/subjects.md.
- Active aspects: conjunction (orb 10°), opposition (10°), trine (8°), sextile (6°), square
(5°), quintile (1°). Minor aspects exist but are off by default.
- Themes:
classic (default), dark, light, dark-high-contrast, strawberry,
black-and-white. Styles: classic (default) and modern.
Common pitfalls (avoid these)
- Forgetting
online=False with explicit coordinates → silent network call / wrong/failed geocoding.
- Passing a subject directly to
ChartDrawer → it needs a ChartDataModel from ChartDataFactory.
- Guessing point names — they are exact strings like
"True_North_Lunar_Node", "Medium_Coeli",
"Mean_Lilith". See the full list in references/reference-data.md.
- Transits over time come from the
EphemerisDataFactory → TransitsTimeRangeFactory pipeline, and
even then you get within-orb aspects at sampled timestamps, not interpolated exact-hit times —
narrow the step and watch orbit→0 / aspect_movement flip to pin the exact instant
(references/time-techniques.md).
month/day are 1-based; hour is 24h local time at the birth place (the timezone handles UTC).
Scope note
This skill targets the open-source Kerykeion package available on PyPI (the git-tracked source). Some
experimental/commercial modules may exist as compiled artifacts in a working tree but are not part
of the importable public API and are intentionally excluded here. If you hit an ImportError for a
module not described in these references, it is not part of the shipped library — do not work around it
by inventing APIs; tell the user.