Python astrology libraries

Python's astrology and astronomy libraries compared by licence and status, and how to call the Zodiacs engine from Python over HTTP.

Engine 1.0.0: On npm. Archive identity and release status.

Read this page as Markdown

The libraries

As PyPI and the projects gave them on 13 October 2026:

pyswisseph 2.10.3.2, of June 2023, AGPL-3.0: the Swiss Ephemeris for Python, and with it its licence choice of the AGPL or Astrodienst's paid professional licence.

kerykeion 6.0.5, of October 2026, AGPL-3.0: charts with houses, aspects, returns and SVG drawings. Its commercial licence documents are marked as drafts.

immanuel 1.6.0, of September 2026: chart data built on the Swiss Ephemeris. Its README and licence file give the AGPL, version 3 or later; its PyPI entry names no licence.

flatlib 0.2.3, of April 2021, MIT: traditional astrology. Its repository was archived in October 2026 and its README calls it deprecated.

skyfield 1.55, of August 2026, MIT: research-grade astronomy; its PyPI page does not mention astrological houses.

Zodiacs from Python

Zodiacs has no Python package. Python reaches the engine through the Compute API, with the standard library alone. The birth details are the API's synthetic example; the guide checks run this code against the committed answer, with ZODIACS_COMPUTE_ORIGIN pointing it at a local copy.

import json
import os
from urllib.error import HTTPError
from urllib.request import Request, urlopen

body = {
    "local": {"date": "1990-06-15", "time": "14:30", "zone": "Europe/Paris"},
    "latitude": 48.8566,
    "longitude": 2.3522,
    "houseSystem": "whole",
}
origin = os.environ.get("ZODIACS_COMPUTE_ORIGIN", "https://zodiacs.org")
request = Request(
    origin.rstrip("/") + "/api/v1/chart",
    data=json.dumps(body).encode("utf-8"),
    headers={"Content-Type": "application/json"},
    method="POST",
)
try:
    with urlopen(request, timeout=15) as response:
        answer = json.load(response)
except HTTPError as error:
    raise SystemExit(f"The service refused this request: {error.code}")
for row in answer["result"]["bodies"]:
    print(row["body"], row["sign"], round(row["degree"], 2))
print(answer["backend"]["name"], answer["backend"]["version"], answer["cite"]["receipt"])

Choosing

The AGPL adds to the GPL a condition for network use: if people reach a modified version over a network, they must be offered its source. The MIT libraries carry no such term; the Compute API is a service you call, not code you include.

References