# kerykeion
**Repository Path**: unidream/kerykeion
## Basic Information
- **Project Name**: kerykeion
- **Description**: Kerykeion is a python library for astrology. It can generate SVG charts and extract all data about a birthchart, a composite chart and a transit chart.
- **Primary Language**: Python
- **License**: AGPL-3.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-04-01
- **Last Updated**: 2026-05-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
Kerykeion
β Like this project? Star it on GitHub and help it grow! β
Kerykeion is a Python library for astrology. It computes planetary and house positions, detects aspects, and generates SVG charts, including birth, synastry, transit, and composite charts. You can also customize which planets to include in your calculations.
The main goal of this project is to provide high-precision astrological calculations through a clean, data-driven approach, making them accessible and programmable.
Kerykeion also serves as the engine behind the hosted [Astrologer API](https://www.kerykeion.net/astrologer-api), and it integrates seamlessly with LLM and AI applications.
## Astrology API
If you are building a commercial application, a SaaS, or prefer to keep the codebase closed-source, consider the hosted **[Astrologer API](https://www.kerykeion.net/astrologer-api/subscribe)** on RapidAPI.
Your app consumes Kerykeion as an external service rather than importing the AGPL library directly β no server setup, no copyleft concerns. Subscribing directly supports the ongoing development of this open-source project.
**[Full API Documentation](https://www.kerykeion.net/astrologer-api)**
## Table of Contents
- [**Astrology API**](#astrology-api)
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Basic Usage](#basic-usage)
- [Generate a SVG Chart](#generate-a-svg-chart)
- [Birth Chart](#birth-chart)
- [External Birth Chart](#external-birth-chart)
- [Synastry Chart](#synastry-chart)
- [Transit Chart](#transit-chart)
- [Solar Return Chart (Dual Wheel)](#solar-return-chart-dual-wheel)
- [Solar Return Chart (Single Wheel)](#solar-return-chart-single-wheel)
- [Lunar Return Chart](#lunar-return-chart)
- [Composite Chart](#composite-chart)
- [Wheel Only Charts](#wheel-only-charts)
- [Birth Chart](#birth-chart-1)
- [Wheel Only Birth Chart (External)](#wheel-only-birth-chart-external)
- [Synastry Chart](#synastry-chart-1)
- [Change the Output Directory](#change-the-output-directory)
- [Change Language](#change-language)
- [Minified SVG](#minified-svg)
- [SVG without CSS Variables](#svg-without-css-variables)
- [Grid Only SVG](#grid-only-svg)
- [Modern Chart Style](#modern-chart-style)
- [Modern Birth Chart](#modern-birth-chart)
- [Modern Synastry Chart](#modern-synastry-chart)
- [Modern Transit Chart](#modern-transit-chart)
- [Modern Wheel Only](#modern-wheel-only)
- [Report Generator](#report-generator)
- [Quick Examples](#quick-examples)
- [Section Access](#section-access)
- [AI Context Serializer](#ai-context-serializer)
- [Quick Example](#quick-example)
- [Example: Retrieving Aspects](#example-retrieving-aspects)
- [Relationship Score](#relationship-score)
- [Element \& Quality Distribution Strategies](#element--quality-distribution-strategies)
- [Ayanamsa (Sidereal Modes)](#ayanamsa-sidereal-modes)
- [House Systems](#house-systems)
- [Perspective Type](#perspective-type)
- [Themes](#themes)
- [Alternative Initialization](#alternative-initialization)
- [Lunar Nodes (Rahu \\& Ketu)](#lunar-nodes-rahu--ketu)
- [Fixed Stars](#fixed-stars)
- [JSON Support](#json-support)
- [Moon Phase Details](#moon-phase-details)
- [Documentation](#documentation)
- [Projects built with Kerykeion](#projects-built-with-kerykeion)
- [Development](#development)
- [Integrating Kerykeion into Your Project](#integrating-kerykeion-into-your-project)
- [License](#license)
- [Contributing](#contributing)
- [Citations](#citations)
## Installation
Kerykeion requires **Python 3.9** or higher.
```bash
pip3 install kerykeion
```
For more installation options and environment setup, see the [Getting Started guide](https://www.kerykeion.net/content/docs/).
## Quick Start
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
subject = AstrologicalSubjectFactory.from_birth_data(
name="Example Person",
year=1990, month=7, day=15,
hour=10, minute=30,
lng=12.4964,
lat=41.9028,
tz_str="Europe/Rome",
online=False,
)
chart_data = ChartDataFactory.create_natal_chart_data(subject)
chart_drawer = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
chart_drawer.save_svg(output_path=output_dir, filename="example-natal")
print("Chart saved to", (output_dir / "example-natal.svg").resolve())
```
This script shows the recommended workflow:
1. Create an `AstrologicalSubject` with explicit coordinates and timezone (offline mode).
2. Build a `ChartDataModel` through `ChartDataFactory`.
3. Render the SVG via `ChartDrawer`, saving it to a controlled folder (`charts_output`).
Use the same pattern for synastry, composite, transit, or return charts by swapping the factory method.
**π More examples: [kerykeion.net/examples](https://www.kerykeion.net/content/examples/)**
## Basic Usage
Below is a simple example illustrating the creation of an astrological subject and retrieving astrological details:
```python
from kerykeion import AstrologicalSubjectFactory
# Create an instance of the AstrologicalSubjectFactory class.
# Arguments: Name, year, month, day, hour, minutes, city, nation
john = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Retrieve information about the Sun:
print(john.sun.model_dump_json())
# > {"name":"Sun","quality":"Cardinal","element":"Air","sign":"Lib","sign_num":6,"position":16.26789199474399,"abs_pos":196.267891994744,"emoji":"βοΈ","point_type":"AstrologicalPoint","house":"Sixth_House","retrograde":false}
# Retrieve information about the first house:
print(john.first_house.model_dump_json())
# > {"name":"First_House","quality":"Cardinal","element":"Fire","sign":"Ari","sign_num":0,"position":19.74676624176799,"abs_pos":19.74676624176799,"emoji":"βοΈ","point_type":"House","house":null,"retrograde":null}
# Retrieve the element of the Moon sign:
print(john.moon.element)
# > 'Air'
```
> **Working offline:** pass `online=False` and specify `lng`, `lat`, and `tz_str` as shown above.
> **Working online:** set `online=True` and provide `city`, `nation`, and a valid GeoNames username. Register for free at [geonames.org](https://www.geonames.org/login). You can set the username via the `KERYKEION_GEONAMES_USERNAME` environment variable or the `geonames_username` parameter.
**π Full factory documentation: [AstrologicalSubjectFactory](https://www.kerykeion.net/content/docs/astrological_subject_factory)**
**To avoid GeoNames, provide longitude, latitude, and timezone and set `online=False`:**
```python
john = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
city="Liverpool",
nation="GB",
lng=-2.9833, # Longitude for Liverpool
lat=53.4000, # Latitude for Liverpool
tz_str="Europe/London", # Timezone for Liverpool
online=False,
)
```
## Generate a SVG Chart
All chart-rendering examples below create a local `charts_output/` folder so the tests can write without touching your home directory. Feel free to change the path when integrating into your own projects.
To generate a chart, use the `ChartDataFactory` to pre-compute chart data, then `ChartDrawer` to create the visualization. This two-step process ensures clean separation between astrological calculations and chart rendering.
**π Chart generation docs: [Charts Documentation](https://www.kerykeion.net/content/docs/charts)**
**Tip:**
The optimized way to open the generated SVG files is with a web browser (e.g., Chrome, Firefox).
To improve compatibility across different applications, you can use the `remove_css_variables` parameter when generating the SVG. This will inline all styles and eliminate CSS variables, resulting in an SVG that is more broadly supported.
### Birth Chart
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subject
john = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute chart data
chart_data = ChartDataFactory.create_natal_chart_data(john)
# Step 3: Create visualization
birth_chart_svg = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
birth_chart_svg.save_svg(output_path=output_dir, filename="john-lennon-natal")
```
The SVG file is saved under `charts_output/john-lennon-natal.svg`.
**π More birth chart examples: [Birth Chart Guide](https://www.kerykeion.net/content/examples/birth-chart)**

### External Birth Chart
An "external" birth chart places the zodiac wheel on the outer ring, offering an alternative visualization style:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subject
birth_chart = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute chart data for external natal chart
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
# Step 3: Create visualization with external_view=True
birth_chart_svg = ChartDrawer(chart_data=chart_data, external_view=True)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
birth_chart_svg.save_svg(output_path=output_dir, filename="john-lennon-natal-external")
```

### Synastry Chart
Synastry charts overlay two individuals' planetary positions to analyze relationship compatibility:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subjects
first = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
second = AstrologicalSubjectFactory.from_birth_data(
"Paul McCartney", 1942, 6, 18, 15, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute synastry chart data
chart_data = ChartDataFactory.create_synastry_chart_data(first, second)
# Step 3: Create visualization
synastry_chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
synastry_chart.save_svg(output_path=output_dir, filename="lennon-mccartney-synastry")
```
**π Synastry chart guide: [Synastry Chart Examples](https://www.kerykeion.net/content/examples/synastry-chart)**

### Transit Chart
Transit charts compare current planetary positions against a natal chart:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subjects
transit = AstrologicalSubjectFactory.from_birth_data(
"Transit", 2025, 6, 8, 8, 45,
lng=-84.3880,
lat=33.7490,
tz_str="America/New_York",
online=False,
)
subject = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute transit chart data
chart_data = ChartDataFactory.create_transit_chart_data(subject, transit)
# Step 3: Create visualization
transit_chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
transit_chart.save_svg(output_path=output_dir, filename="john-lennon-transit")
```
**π Transit chart guide: [Transit Chart Examples](https://www.kerykeion.net/content/examples/transit-chart)**

### Solar Return Chart (Dual Wheel)
Solar returns calculate the exact moment the Sun returns to its natal position each year:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.planetary_return_factory import PlanetaryReturnFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create natal subject
john = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Calculate Solar Return subject (offline example with manual coordinates)
return_factory = PlanetaryReturnFactory(
john,
lng=-2.9833,
lat=53.4000,
tz_str="Europe/London",
online=False
)
solar_return_subject = return_factory.next_return_from_date(1964, 10, 1, return_type="Solar")
# Step 3: Pre-compute return chart data (dual wheel: natal + solar return)
chart_data = ChartDataFactory.create_return_chart_data(john, solar_return_subject)
# Step 4: Create visualization
solar_return_chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
solar_return_chart.save_svg(output_path=output_dir, filename="john-lennon-solar-return-dual")
```
**π Return chart guide: [Dual Return Chart Examples](https://www.kerykeion.net/content/examples/dual-return-chart)**

### Solar Return Chart (Single Wheel)
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.planetary_return_factory import PlanetaryReturnFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create natal subject
john = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Calculate Solar Return subject (offline example with manual coordinates)
return_factory = PlanetaryReturnFactory(
john,
lng=-2.9833,
lat=53.4000,
tz_str="Europe/London",
online=False
)
solar_return_subject = return_factory.next_return_from_date(1964, 10, 1, return_type="Solar")
# Step 3: Build a single-wheel return chart
chart_data = ChartDataFactory.create_single_wheel_return_chart_data(solar_return_subject)
# Step 4: Create visualization
single_wheel_chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
single_wheel_chart.save_svg(output_path=output_dir, filename="john-lennon-solar-return-single")
```
**π Planetary return factory docs: [PlanetaryReturnFactory](https://www.kerykeion.net/content/docs/planetary_return_factory)**

### Lunar Return Chart
Lunar returns calculate when the Moon returns to its natal position (approximately monthly):
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.planetary_return_factory import PlanetaryReturnFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create natal subject
john = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Calculate Lunar Return subject
return_factory = PlanetaryReturnFactory(
john,
lng=-2.9833,
lat=53.4000,
tz_str="Europe/London",
online=False
)
lunar_return_subject = return_factory.next_return_from_date(1964, 1, 1, return_type="Lunar")
# Step 3: Build a dual wheel (natal + lunar return)
lunar_return_chart_data = ChartDataFactory.create_return_chart_data(john, lunar_return_subject)
dual_wheel_chart = ChartDrawer(chart_data=lunar_return_chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
dual_wheel_chart.save_svg(output_path=output_dir, filename="john-lennon-lunar-return-dual")
# Optional: create a single-wheel lunar return
single_wheel_data = ChartDataFactory.create_single_wheel_return_chart_data(lunar_return_subject)
single_wheel_chart = ChartDrawer(chart_data=single_wheel_data)
single_wheel_chart.save_svg(output_path=output_dir, filename="john-lennon-lunar-return-single")
```


### Composite Chart
Composite charts create a single chart from two individuals' midpoints to represent the relationship entity:
```python
from pathlib import Path
from kerykeion import CompositeSubjectFactory, AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subjects (offline configuration)
angelina = AstrologicalSubjectFactory.from_birth_data(
"Angelina Jolie", 1975, 6, 4, 9, 9,
lng=-118.2437,
lat=34.0522,
tz_str="America/Los_Angeles",
online=False,
)
brad = AstrologicalSubjectFactory.from_birth_data(
"Brad Pitt", 1963, 12, 18, 6, 31,
lng=-96.7069,
lat=35.3273,
tz_str="America/Chicago",
online=False,
)
# Step 2: Create composite subject
factory = CompositeSubjectFactory(angelina, brad)
composite_model = factory.get_midpoint_composite_subject_model()
# Step 3: Pre-compute composite chart data
chart_data = ChartDataFactory.create_composite_chart_data(composite_model)
# Step 4: Create visualization
composite_chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
composite_chart.save_svg(output_path=output_dir, filename="jolie-pitt-composite")
```
**π Composite factory docs: [CompositeSubjectFactory](https://www.kerykeion.net/content/docs/composite_subject_factory)**

## Wheel Only Charts
For _all_ the charts, you can generate a wheel-only chart by using the method `save_wheel_only_svg_file()`:
**π Minimalist charts guide: [Wheel Only & Aspect Grid Charts](https://www.kerykeion.net/content/examples/minimalist-charts-and-aspect-table)**
### Birth Chart
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subject
birth_chart = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute chart data
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
# Step 3: Create visualization
birth_chart_svg = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
birth_chart_svg.save_wheel_only_svg_file(output_path=output_dir, filename="john-lennon-natal-wheel")
```

### Wheel Only Birth Chart (External)
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subject
birth_chart = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute external natal chart data
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
# Step 3: Create visualization (external wheel view)
birth_chart_svg = ChartDrawer(chart_data=chart_data, external_view=True)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
birth_chart_svg.save_wheel_only_svg_file(output_path=output_dir, filename="john-lennon-natal-wheel-external")
```

### Synastry Chart
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subjects
first = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
second = AstrologicalSubjectFactory.from_birth_data(
"Paul McCartney", 1942, 6, 18, 15, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute synastry chart data
chart_data = ChartDataFactory.create_synastry_chart_data(first, second)
# Step 3: Create visualization
synastry_chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
synastry_chart.save_wheel_only_svg_file(output_path=output_dir, filename="lennon-mccartney-synastry-wheel")
```

### Change the Output Directory
To save the SVG file in a custom location, specify the `output_path` parameter in `save_svg()`:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subjects
first = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
second = AstrologicalSubjectFactory.from_birth_data(
"Paul McCartney", 1942, 6, 18, 15, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute synastry chart data
chart_data = ChartDataFactory.create_synastry_chart_data(first, second)
# Step 3: Create visualization with custom output directory
synastry_chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
synastry_chart.save_svg(output_path=output_dir)
print("Saved to", (output_dir / f"{synastry_chart.first_obj.name} - Synastry Chart.svg").resolve())
```
### Change Language
You can switch chart language by passing `chart_language` to the `ChartDrawer` class:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subject
birth_chart = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute chart data
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
# Step 3: Create visualization with Italian language
birth_chart_svg = ChartDrawer(
chart_data=chart_data,
chart_language="IT" # Change to Italian
)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
birth_chart_svg.save_svg(output_path=output_dir, filename="john-lennon-natal-it")
```
You can also provide custom labels (or introduce a brand-new language) by passing
a dictionary to `language_pack`. Only the keys you supply are merged on top of the
built-in strings:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
birth_chart = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
custom_labels = {
"PT": {
"info": "InformaΓ§Γ΅es",
"celestial_points": {"Sun": "Sol", "Moon": "Lua"},
}
}
custom_chart = ChartDrawer(
chart_data=chart_data,
chart_language="PT",
language_pack=custom_labels["PT"],
)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
custom_chart.save_svg(output_path=output_dir, filename="john-lennon-natal-pt")
```
**π Language configuration guide: [Chart Language Settings](https://www.kerykeion.net/content/examples/chart-language)**
The available languages are:
- EN (English)
- FR (French)
- PT (Portuguese)
- ES (Spanish)
- TR (Turkish)
- RU (Russian)
- IT (Italian)
- CN (Chinese)
- DE (German)
- HI (Hindi)
### Minified SVG
To generate a minified SVG, set `minify=True` in the `save_svg()` method:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subject
birth_chart = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute chart data
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
# Step 3: Create visualization
birth_chart_svg = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
birth_chart_svg.save_svg(
output_path=output_dir,
filename="john-lennon-natal-minified",
minify=True,
)
```
### SVG without CSS Variables
To generate an SVG without CSS variables, set `remove_css_variables=True` in the `save_svg()` method:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subject
birth_chart = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute chart data
chart_data = ChartDataFactory.create_natal_chart_data(birth_chart)
# Step 3: Create visualization
birth_chart_svg = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
birth_chart_svg.save_svg(
output_path=output_dir,
filename="john-lennon-natal-no-css-variables",
remove_css_variables=True,
)
```
This will inline all styles and eliminate CSS variables, resulting in an SVG that is more broadly supported.
### Grid Only SVG
It's possible to generate a grid-only SVG, useful for creating a custom layout. To do this, use the `save_aspect_grid_only_svg_file()` method:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subjects
birth_chart = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
second = AstrologicalSubjectFactory.from_birth_data(
"Paul McCartney", 1942, 6, 18, 15, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute synastry chart data
chart_data = ChartDataFactory.create_synastry_chart_data(birth_chart, second)
# Step 3: Create visualization with dark theme
aspect_grid_chart = ChartDrawer(chart_data=chart_data, theme="dark")
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
aspect_grid_chart.save_aspect_grid_only_svg_file(output_path=output_dir, filename="lennon-mccartney-aspect-grid")
```

## Modern Chart Style
All chart types support a **modern** concentric-ring layout as an alternative to the classic wheel. You can set the style at the instance level via `ChartDrawer(chart_data=..., style="modern")` or per-render via `save_svg(style="modern")`. The modern style works with all six themes.
Available `style` values: `"classic"` (default) and `"modern"`.
**Modern-only keyword arguments** (ignored by the classic style):
| Parameter | Type | Default | Description |
|---|---|---|---|
| `show_zodiac_background_ring` | `bool` | `True` | Draw colored zodiac wedges as the outer zodiac annulus around the cusp ring |
**Dual-chart keyword arguments** (Synastry, Transit, Composite, Dual Return):
| Parameter | Type | Default | Description |
|---|---|---|---|
| `double_chart_aspect_grid_type` | `str` | `"list"` | Aspect grid layout: `"list"` (compact vertical list) or `"table"` (traditional cross-reference grid) |
**Classic-only constructor arguments** (ignored by the modern style):
| Parameter | Type | Default | Description |
|---|---|---|---|
| `show_degree_indicators` | `bool` | `True` | Show degree indicators on planets |
| `show_aspect_icons` | `bool` | `True` | Show aspect icons on aspect lines |
### Modern Birth Chart
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
john = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
chart_data = ChartDataFactory.create_natal_chart_data(john)
chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
chart.save_svg(output_path=output_dir, filename="john-lennon-modern", style="modern")
```

### Modern Synastry Chart
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
john = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
yoko = AstrologicalSubjectFactory.from_birth_data(
"Yoko Ono", 1933, 2, 18, 20, 30,
lng=139.6917,
lat=35.6895,
tz_str="Asia/Tokyo",
online=False,
)
chart_data = ChartDataFactory.create_synastry_chart_data(john, yoko)
chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
chart.save_svg(output_path=output_dir, filename="lennon-ono-synastry-modern", style="modern")
```

### Modern Transit Chart
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
john = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
transit = AstrologicalSubjectFactory.from_birth_data(
"Transit", 2025, 3, 4, 12, 0,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
chart_data = ChartDataFactory.create_transit_chart_data(john, transit)
chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
chart.save_svg(output_path=output_dir, filename="lennon-transit-modern", style="modern")
```

### Modern Wheel Only
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
john = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
chart_data = ChartDataFactory.create_natal_chart_data(john)
chart = ChartDrawer(chart_data=chart_data, theme="dark")
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
chart.save_wheel_only_svg_file(
output_path=output_dir,
filename="john-lennon-modern-wheel-dark",
style="modern",
)
```

**π Modern chart examples: [Modern Charts Guide](https://www.kerykeion.net/content/examples/modern-charts)**
## Report Generator
`ReportGenerator` mirrors the chart-type dispatch of `ChartDrawer`. It accepts raw `AstrologicalSubjectModel` instances as well as any `ChartDataModel` produced by `ChartDataFactory`βincluding natal, composite, synastry, transit, and planetary return chartsβand renders the appropriate textual report automatically.
**π Full report documentation: [Report Generator Guide](https://www.kerykeion.net/content/docs/report)**
### Quick Examples
```python
from kerykeion import ReportGenerator, AstrologicalSubjectFactory, ChartDataFactory
# Subject-only report
subject = AstrologicalSubjectFactory.from_birth_data(
"Sample Natal", 1990, 7, 21, 14, 45,
lng=12.4964,
lat=41.9028,
tz_str="Europe/Rome",
online=False,
)
ReportGenerator(subject).print_report(include_aspects=False)
# Single-chart data (elements, qualities, aspects enabled)
natal_data = ChartDataFactory.create_natal_chart_data(subject)
ReportGenerator(natal_data).print_report(max_aspects=10)
# Dual-chart data (synastry, transit, dual return, β¦)
partner = AstrologicalSubjectFactory.from_birth_data(
"Sample Partner", 1992, 11, 5, 9, 30,
lng=12.4964,
lat=41.9028,
tz_str="Europe/Rome",
online=False,
)
synastry_data = ChartDataFactory.create_synastry_chart_data(subject, partner)
ReportGenerator(synastry_data).print_report(max_aspects=12)
```
Each report contains:
- A chart-aware title summarising the subject(s) and chart type
- Birth/event metadata and configuration settings
- Celestial points with sign, position, **daily motion**, **declination**, retrograde flag, and house
- House cusp tables for every subject involved
- Lunar phase details when available
- Element/quality distributions and active configuration summaries (for chart data)
- Aspect listings tailored for single or dual charts, with symbols for type and movement
- Dual-chart extras such as house comparisons and relationship scores (when provided by the data)
### Section Access
All section helpers remain available for targeted output:
```python
from kerykeion import ReportGenerator, AstrologicalSubjectFactory, ChartDataFactory
subject = AstrologicalSubjectFactory.from_birth_data(
"Sample Natal", 1990, 7, 21, 14, 45,
lng=12.4964,
lat=41.9028,
tz_str="Europe/Rome",
online=False,
)
natal_data = ChartDataFactory.create_natal_chart_data(subject)
report = ReportGenerator(natal_data)
sections = report.generate_report(max_aspects=5).split("\n\n")
for section in sections[:3]:
print(section)
```
**π Report examples: [Report Examples](https://www.kerykeion.net/content/examples/report)**
## AI Context Serializer
The `context_serializer` module transforms Kerykeion data models into precise, non-qualitative XML optimized for LLM consumption. It provides the essential "ground truth" data needed for AI agents to generate accurate astrological interpretations.
**π Full context serializer docs: [Context Serializer Guide](https://www.kerykeion.net/content/docs/context_serializer)**
### Quick Example
```python
from kerykeion import AstrologicalSubjectFactory, to_context
# Create a subject
subject = AstrologicalSubjectFactory.from_birth_data(
"John Doe", 1990, 1, 1, 12, 0,
city="London",
nation="GB",
lng=-0.1278,
lat=51.5074,
tz_str="Europe/London",
online=False,
)
# Generate AI-ready context
context = to_context(subject)
print(context)
```
**Output:**
```xml
...
...
```
**Key Features:**
- **XML Output:** Well-formed XML with semantic tags, proper escaping, and optional field omission.
- **Standardized Output:** Consistent format for Natal, Synastry, Composite, and Return charts.
- **Non-Qualitative:** Provides raw data (positions, aspects) without interpretive bias.
- **Prompt-Ready:** Designed to be injected directly into system prompts.
## Example: Retrieving Aspects
Kerykeion provides a unified `AspectsFactory` class for calculating astrological aspects within single charts or between two charts:
```python
from kerykeion import AspectsFactory, AstrologicalSubjectFactory
# Create astrological subjects
jack = AstrologicalSubjectFactory.from_birth_data(
"Jack", 1990, 6, 15, 15, 15,
lng=12.4964,
lat=41.9028,
tz_str="Europe/Rome",
online=False,
)
jane = AstrologicalSubjectFactory.from_birth_data(
"Jane", 1991, 10, 25, 21, 0,
lng=12.4964,
lat=41.9028,
tz_str="Europe/Rome",
online=False,
)
# For single chart aspects (natal, return, composite, etc.)
single_chart_result = AspectsFactory.single_chart_aspects(jack)
print(f"Found {len(single_chart_result.aspects)} aspects in Jack's chart")
print(single_chart_result.aspects[0])
# For dual chart aspects (synastry, transits, comparisons, etc.)
dual_chart_result = AspectsFactory.dual_chart_aspects(jack, jane)
print(f"Found {len(dual_chart_result.aspects)} aspects between Jack and Jane's charts")
print(dual_chart_result.aspects[0])
# Each AspectModel includes:
# - p1_name, p2_name: Planet/point names
# - p1_owner, p2_owner: Subject name string (e.g., "Jack", "Jane")
# - aspect: Aspect type (conjunction, trine, square, etc.)
# - orbit: Actual orb in degrees
# - aspect_degrees: Exact degrees for the aspect (0, 60, 90, 120, 180, etc.)
# - diff: Absolute angular difference between the two points
# - p1_abs_pos, p2_abs_pos: Absolute ecliptic positions
# - p1_speed, p2_speed: Daily speed of each point
# - aspect_movement: "Applying", "Separating", or "Static"
```
**π Aspects documentation: [Aspects Factory Guide](https://www.kerykeion.net/content/docs/aspects)**
**Advanced Usage with Custom Settings:**
```python
# You can also customize aspect calculations with custom orb settings
from kerykeion.settings.config_constants import DEFAULT_ACTIVE_ASPECTS
# Modify aspect settings if needed
custom_aspects = DEFAULT_ACTIVE_ASPECTS.copy()
# ... modify as needed
# The factory automatically uses the configured settings for orb calculations
# and filters aspects based on relevance and orb thresholds
```
**π Configuration options: [Settings Documentation](https://www.kerykeion.net/content/docs/settings)**
## Relationship Score
Kerykeion can calculate a relationship compatibility score based on synastry aspects, using the method of the Italian astrologer **Ciro Discepolo**:
```python
from kerykeion import AstrologicalSubjectFactory
from kerykeion.relationship_score_factory import RelationshipScoreFactory
# Create two subjects
person1 = AstrologicalSubjectFactory.from_birth_data(
"Alice", 1990, 3, 15, 14, 30,
lng=12.4964,
lat=41.9028,
tz_str="Europe/Rome",
online=False,
)
person2 = AstrologicalSubjectFactory.from_birth_data(
"Bob", 1988, 7, 22, 9, 0,
lng=12.4964,
lat=41.9028,
tz_str="Europe/Rome",
online=False,
)
# Calculate relationship score
score_factory = RelationshipScoreFactory(person1, person2)
result = score_factory.get_relationship_score()
print(f"Compatibility Score: {result.score_value}")
print(f"Description: {result.score_description}")
```
**π Relationship score guide: [Relationship Score Examples](https://www.kerykeion.net/content/examples/relationship-score)**
**π Factory documentation: [RelationshipScoreFactory](https://www.kerykeion.net/content/docs/relationship_score_factory)**
## Element & Quality Distribution Strategies
`ChartDataFactory` now offers two strategies for calculating element and modality totals. The default `"weighted"` mode leans on a curated map that emphasises core factors (for example `sun`, `moon`, and `ascendant` weight 2.0, angles such as `medium_coeli` 1.5, personal planets 1.5, social planets 1.0, outers 0.5, and minor bodies 0.3β0.8). Provide `distribution_method="pure_count"` when you want every active point to contribute equally.
You can refine the weighting without rebuilding the dictionary: pass lowercase point names to `custom_distribution_weights` and use `"__default__"` to override the fallback value applied to entries that are not listed explicitly.
```python
from kerykeion import AstrologicalSubjectFactory, ChartDataFactory
subject = AstrologicalSubjectFactory.from_birth_data(
"Sample", 1986, 4, 12, 8, 45,
lng=11.3426,
lat=44.4949,
tz_str="Europe/Rome",
online=False,
)
# Equal weighting: every active point counts once
pure_data = ChartDataFactory.create_natal_chart_data(
subject,
distribution_method="pure_count",
)
# Custom emphasis: boost the Sun, soften everything else
weighted_data = ChartDataFactory.create_natal_chart_data(
subject,
distribution_method="weighted",
custom_distribution_weights={
"sun": 3.0,
"__default__": 0.75,
},
)
print(pure_data.element_distribution.fire)
print(weighted_data.element_distribution.fire)
```
All convenience helpers (`create_synastry_chart_data`, `create_transit_chart_data`, returns, and composites) forward the same keyword-only parameters, so you can keep a consistent weighting scheme across every chart type.
**π Element/quality distribution guide: [Distribution Documentation](https://www.kerykeion.net/content/docs/element_quality_distribution)**
## Ayanamsa (Sidereal Modes)
By default, the zodiac type is **Tropical**. To use **Sidereal**, specify the sidereal mode:
```python
johnny = AstrologicalSubjectFactory.from_birth_data(
"Johnny Depp", 1963, 6, 9, 0, 0,
lng=-87.1112,
lat=37.7719,
tz_str="America/Chicago",
online=False,
zodiac_type="Sidereal",
sidereal_mode="LAHIRI"
)
# The ayanamsa offset (degrees) is available on sidereal charts:
print(johnny.ayanamsa_value) # e.g. 23.85
```
Kerykeion supports **47 named sidereal modes** plus a **USER** mode for custom ayanamsa definitions (48 total). Mode families include Indian/Vedic (Lahiri, Krishnamurti, Raman, Aryabhata, Suryasiddhanta, True Citra/Pushya/Revati, ...), Western sidereal (Fagan-Bradley, DeLuce, Hipparchos, ...), Babylonian (Kugler, Huber, Britton, ...), galactic alignment, and astronomical reference frames (J2000, J1900, B1950).
**Custom ayanamsa (USER mode):**
```python
custom = AstrologicalSubjectFactory.from_birth_data(
"Custom Ayanamsa", 2000, 1, 1, 0, 0,
lng=0.0, lat=51.5, tz_str="Etc/GMT", online=False,
zodiac_type="Sidereal",
sidereal_mode="USER",
custom_ayanamsa_t0=2451545.0, # J2000.0 reference epoch
custom_ayanamsa_ayan_t0=23.5, # ayanamsa offset at epoch (degrees)
)
```
**π Sidereal mode examples: [Sidereal Modes Guide](https://www.kerykeion.net/content/examples/sidereal-modes/)**
**π Full list of supported sidereal modes: [SiderealMode Schema](https://www.kerykeion.net/content/docs/schemas#siderealmode)**
## House Systems
By default, houses are calculated using **Placidus**. Configure a different house system as follows:
```python
johnny = AstrologicalSubjectFactory.from_birth_data(
"Johnny Depp", 1963, 6, 9, 0, 0,
lng=-87.1112,
lat=37.7719,
tz_str="America/Chicago",
online=False,
houses_system_identifier="M"
)
```
**π House system examples: [House Systems Guide](https://www.kerykeion.net/content/examples/houses-systems/)**
**π Full list of supported house systems: [HouseSystemIdentifier Schema](https://www.kerykeion.net/content/docs/schemas#housesystemidentifier)**
So far all the available houses system in the Swiss Ephemeris are supported but the Gauquelin Sectors.
## Perspective Type
By default, Kerykeion uses the **Apparent Geocentric** perspective (the most standard in astrology). Other perspectives (e.g., **Heliocentric**) can be set this way:
```python
johnny = AstrologicalSubjectFactory.from_birth_data(
"Johnny Depp", 1963, 6, 9, 0, 0,
lng=-87.1112,
lat=37.7719,
tz_str="America/Chicago",
online=False,
perspective_type="Heliocentric"
)
```
**π Perspective type examples: [Perspective Type Guide](https://www.kerykeion.net/content/examples/perspective-type/)**
**π Full list of supported perspective types: [PerspectiveType Schema](https://www.kerykeion.net/content/docs/schemas#perspectivetype)**
## Themes
|
Classic |
Dark |
Light |
Black & White |
| Classic Style |
 |
 |
 |
 |
| Modern Style |
 |
 |
 |
 |
Kerykeion provides several chart themes: **Classic** (default), **Dark**, **Light**, and **Black & White** (optimized for monochrome printing). Each is available in both **classic** and **modern** chart styles.
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.
**π Theming guide with all examples: [Theming Documentation](https://www.kerykeion.net/content/examples/theming)**
The Black & White theme renders glyphs, rings, and aspects in solid black on light backgrounds, designed for crisp B/W prints (PDF or paper) without sacrificing legibility.
Here's an example of how to set the theme:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subject
dark_theme_subject = AstrologicalSubjectFactory.from_birth_data(
"John Lennon - Dark Theme", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute chart data
chart_data = ChartDataFactory.create_natal_chart_data(dark_theme_subject)
# Step 3: Create visualization with dark high contrast theme
dark_theme_natal_chart = ChartDrawer(chart_data=chart_data, theme="dark-high-contrast")
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
dark_theme_natal_chart.save_svg(output_path=output_dir, filename="john-lennon-natal-dark-high-contrast")
```

## Alternative Initialization
Create an `AstrologicalSubjectModel` from a UTC ISO 8601 string:
```python
from kerykeion import AstrologicalSubjectFactory
subject = AstrologicalSubjectFactory.from_iso_utc_time(
name="Johnny Depp",
iso_utc_time="1963-06-09T05:00:00Z",
city="Owensboro",
nation="US",
lng=-87.1112,
lat=37.7719,
tz_str="America/Chicago",
online=False,
)
print(subject.iso_formatted_local_datetime)
```
If you prefer automatic geocoding, set `online=True` and provide your GeoNames credentials via `geonames_username`.
**π All initialization options: [AstrologicalSubjectFactory Documentation](https://www.kerykeion.net/content/docs/astrological_subject_factory)**
## Lunar Nodes (Rahu & Ketu)
Kerykeion supports both **True** and **Mean** Lunar Nodes:
- **True North Lunar Node**: `"True_North_Lunar_Node"`
- **True South Lunar Node**: `"True_South_Lunar_Node"`
- **Mean North Lunar Node**: `"Mean_North_Lunar_Node"`
- **Mean South Lunar Node**: `"Mean_South_Lunar_Node"`
By default, only the **True** nodes are active in charts and aspect calculations. To include the Mean nodes (or customize which nodes appear), pass the `active_points` parameter to the `ChartDataFactory` methods.
**π ChartDataFactory documentation: [ChartDataFactory Guide](https://www.kerykeion.net/content/docs/chart_data_factory)**
Example:
```python
from pathlib import Path
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.charts.chart_drawer import ChartDrawer
# Step 1: Create subject
subject = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833,
lat=53.4,
tz_str="Europe/London",
online=False,
)
# Step 2: Pre-compute chart data with custom active points including true nodes
chart_data = ChartDataFactory.create_natal_chart_data(
subject,
active_points=[
"Sun",
"Moon",
"Mercury",
"Venus",
"Mars",
"Jupiter",
"Saturn",
"Uranus",
"Neptune",
"Pluto",
"Mean_North_Lunar_Node",
"Mean_South_Lunar_Node",
"True_North_Lunar_Node",
"True_South_Lunar_Node",
"Ascendant",
"Medium_Coeli",
"Descendant",
"Imum_Coeli"
]
)
# Step 3: Create visualization
chart = ChartDrawer(chart_data=chart_data)
output_dir = Path("charts_output")
output_dir.mkdir(exist_ok=True)
chart.save_svg(output_path=output_dir, filename="johnny-depp-custom-points")
```
## Fixed Stars
Kerykeion includes **23 fixed stars** β the 2 original stars (Regulus, Spica) plus 21 new stars added in v5.12, completing all 15 Behenian stars of the medieval/Hermetic tradition plus 8 additional bright stars. The set includes the 4 Royal Stars of Persian/Hellenistic astrology (Regulus, Aldebaran, Antares, Fomalhaut). Each star provides ecliptic longitude, daily motion (`speed`), equatorial `declination`, and apparent visual `magnitude`.
Fixed stars are computed for every subject but are **inactive by default** in charts and aspect calculations. To include them, pass their names in `active_points`:
```python
from kerykeion import AstrologicalSubjectFactory
from kerykeion.chart_data_factory import ChartDataFactory
from kerykeion.settings.config_constants import DEFAULT_ACTIVE_POINTS
subject = AstrologicalSubjectFactory.from_birth_data(
"John Lennon", 1940, 10, 9, 18, 30,
lng=-2.9833, lat=53.4, tz_str="Europe/London", online=False,
)
# Access fixed star data directly
print(subject.sirius.abs_pos) # Ecliptic longitude
print(subject.sirius.magnitude) # -1.44
print(subject.sirius.declination) # Equatorial declination
# Include fixed stars in chart rendering
chart_data = ChartDataFactory.create_natal_chart_data(
subject,
active_points=list(DEFAULT_ACTIVE_POINTS) + [
"Sirius", "Regulus", "Aldebaran", "Antares", "Fomalhaut",
],
)
```
Available fixed stars: Regulus, Spica, Aldebaran, Antares, Sirius, Fomalhaut, Algol, Betelgeuse, Canopus, Procyon, Arcturus, Pollux, Deneb, Altair, Rigel, Achernar, Capella, Vega, Alcyone, Alphecca, Algorab, Deneb_Algedi, Alkaid.
**π Full active points list: [Active Points Documentation](https://www.kerykeion.net/content/docs/active_points)**
## JSON Support
You can serialize the astrological subject (the base data used throughout the library) to JSON:
```python
from kerykeion import AstrologicalSubjectFactory
johnny = AstrologicalSubjectFactory.from_birth_data(
"Johnny Depp", 1963, 6, 9, 0, 0,
lng=-87.1112,
lat=37.7719,
tz_str="America/Chicago",
online=False,
)
print(johnny.model_dump_json(indent=2))
```
**π Data models and schemas: [Schemas Documentation](https://www.kerykeion.net/content/docs/schemas)**
## Moon Phase Details
The `MoonPhaseDetailsFactory` generates a rich lunar phase context from any astrological subject β including illumination, upcoming major phases, next eclipses (solar and lunar), sunrise/sunset, and apparent solar position. All timings use Swiss Ephemeris for ~1 second precision.
```python
from kerykeion import AstrologicalSubjectFactory, MoonPhaseDetailsFactory, ReportGenerator
subject = AstrologicalSubjectFactory.from_birth_data(
"Example", 2025, 4, 1, 7, 51,
lng=-0.1276, lat=51.5074, tz_str="Europe/London",
online=False,
)
overview = MoonPhaseDetailsFactory.from_subject(subject)
print(f"Phase: {overview.moon.phase_name} {overview.moon.emoji}")
print(f"Illumination: {overview.moon.illumination}")
print(f"Stage: {overview.moon.stage}")
if overview.moon.detailed and overview.moon.detailed.upcoming_phases:
fm = overview.moon.detailed.upcoming_phases.full_moon
if fm and fm.next:
print(f"Next Full Moon: {fm.next.datestamp}")
# Generate a formatted ASCII report
ReportGenerator(overview).print_report()
```
**Report output (truncated):**
```text
=====================================================
Moon Phase Overview β Tue, 01 Apr 2025 06:51:00 +0000
=====================================================
+Moon Summary--+--------------------+
| Field | Value |
+--------------+--------------------+
| Phase Name | Waxing Crescent π |
| Major Phase | New Moon |
| Stage | Waxing |
| Illumination | 8% |
| Age (days) | 3 |
| Lunar Cycle | 9.571% |
| Sun Sign | Ari |
| Moon Sign | Gem |
+--------------+--------------------+
+Illumination Details-------+
| Field | Value |
+------------------+--------+
| Percentage | 8.0% |
| Visible Fraction | 0.0837 |
| Phase Angle | 34.46Β° |
+------------------+--------+
+Upcoming Phases+---------------------------------+---------------------------------+
| Phase | Last | Next |
+---------------+---------------------------------+---------------------------------+
| New Moon | Sun, 29 Mar 2025 10:57:49 +0000 | Mon, 28 Apr 2025 00:31:07 +0000 |
| First Quarter | ... | ... |
| Full Moon | ... | ... |
| Last Quarter | ... | ... |
+---------------+---------------------------------+---------------------------------+
...
```
You can also get the full model as JSON:
```python
print(overview.model_dump_json(exclude_none=True, indent=2))
```
**JSON output (truncated):**
```json
{
"timestamp": 1743490260,
"datestamp": "Tue, 01 Apr 2025 06:51:00 +0000",
"sun": {
"sunrise_timestamp": "06:35",
"sunset_timestamp": "19:34",
"solar_noon": "13:04",
"day_length": "12:59",
"next_solar_eclipse": { "type": "Partial Solar Eclipse", "...": "..." }
},
"moon": {
"phase_name": "Waxing Crescent",
"major_phase": "New Moon",
"stage": "waxing",
"illumination": "12%",
"emoji": "π",
"next_lunar_eclipse": { "type": "Total Lunar Eclipse", "...": "..." },
"detailed": { "upcoming_phases": { "...": "..." }, "illumination_details": { "...": "..." } }
},
"location": { "latitude": "51.5074", "longitude": "-0.1276" }
}
```
**π Full documentation: [Moon Phase Details Factory](https://www.kerykeion.net/content/docs/moon_phase_details_factory)**
**π Examples: [Moon Phase Details Examples](https://www.kerykeion.net/content/examples/moon-phase-details)**
## Documentation
- **Main Website**: [kerykeion.net](https://www.kerykeion.net)
- **Getting Started**: [kerykeion.net/docs](https://www.kerykeion.net/content/docs/)
- **Examples Gallery**: [kerykeion.net/examples](https://www.kerykeion.net/content/examples/)
- **API Reference**: [kerykeion.net/pydocs](https://www.kerykeion.net/pydocs/)
- **Astrologer API Docs**: [kerykeion.net/astrologer-api](https://www.kerykeion.net/content/astrologer-api/)
- **Migration Guide (v4 β v5)**: [Migration Guide](https://www.kerykeion.net/content/docs/migration)
## Projects built with Kerykeion
**[Astrologer Studio](https://www.astrologerstudio.com/)** is professional online astrology software built on the Kerykeion engine β chart generation, client management, transit tracking, and AI-powered insights.
## Development
Clone the repository or download the ZIP via the GitHub interface.
```bash
git clone https://github.com/g-battaglia/kerykeion.git
cd kerykeion
pip install -e ".[dev]"
```
## Integrating Kerykeion into Your Project
If you would like to incorporate Kerykeion's astrological features into your application, please reach out via [email](mailto:kerykeion.astrology@gmail.com?subject=Integration%20Request). Whether you need custom features, support, or specialized consulting, I am happy to discuss potential collaborations.
For commercial or closed-source applications, consider using the paid [Astrologer API (RapidAPI plans & pricing)](https://www.kerykeion.net/astrologer-api/subscribe) which provides REST endpoints for all Kerykeion functionality.
## License
This project is covered under the AGPL-3.0 License. For detailed information, please see the [LICENSE](LICENSE) file. If you have questions, feel free to contact me at [kerykeion.astrology@gmail.com](mailto:kerykeion.astrology@gmail.com?subject=Kerykeion).
As a rule of thumb, if you import this library directly into a project, that project should be open-sourced under a compatible license.
Alternatively, if the source code must remain private, consider the hosted **[Astrologer API](https://www.kerykeion.net/astrologer-api/subscribe)**. Since it functions as an external third-party service, consuming its REST endpoints does *not* require the calling application to be open-source.
## Contributing
Contributions are welcome! Feel free to submit pull requests or report issues.
By submitting a contribution, you agree to assign the copyright of that contribution to the maintainer. The project stays openly available under the AGPL for everyone, while the re-licensing option helps sustain future development. Your authorship remains acknowledged in the commit history and release notes.
## Citations
If using Kerykeion in published or academic work, please cite as follows:
```
Battaglia, G. (2025). Kerykeion: A Python Library for Astrological Calculations and Chart Generation.
https://github.com/g-battaglia/kerykeion
```