# 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: https://zodiacs.org/developers/engine/

## 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.

~~~python
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

- [Python hosted quickstart](https://zodiacs.org/developers/docs/python/)
- [Compute API reference](https://zodiacs.org/developers/compute/)
- [pyswisseph on PyPI](https://pypi.org/project/pyswisseph/)
- [kerykeion on PyPI](https://pypi.org/project/kerykeion/)
- [immanuel on PyPI](https://pypi.org/project/immanuel/)
- [flatlib on PyPI](https://pypi.org/project/flatlib/)
- [skyfield on PyPI](https://pypi.org/project/skyfield/)
