Diagnostics: Logging & Warnings

Stellium is silent by default — importing it and calculating charts writes nothing to your stdout. Diagnostics reach you through two standard Python channels you fully control: warnings and logging.

Warnings — “something about your input or result is off”

When Stellium can still proceed but something is degraded — a bad row in a CSV import, a geocoding failure, an invalid orb configuration — it raises a typed warning. These show once by default (to stderr) and are easy to filter.

All Stellium warnings derive from StelliumWarning, so one filter silences them all:

import warnings
from stellium import StelliumWarning

warnings.filterwarnings("ignore", category=StelliumWarning)

Or target a specific kind:

Warning

Raised when

DataQualityWarning

An import row / registry entry / requested part was malformed or skipped

GeocodingWarning

A location couldn’t be geocoded, or the geocoder was unavailable

ConfigurationWarning

A config value was invalid and ignored (e.g. a bad orb key, a missing house system)

MissingEphemerisWarning

A body was skipped because its ephemeris file isn’t installed

from stellium import DataQualityWarning
warnings.filterwarnings("ignore", category=DataQualityWarning)

To capture warnings instead of printing them (e.g. to report skipped rows):

import warnings
from stellium import DataQualityWarning, ChartBuilder
from stellium.io import parse_csv

with warnings.catch_warnings(record=True) as caught:
    warnings.simplefilter("always")
    natives = parse_csv("births.csv")

skipped = [w for w in caught if issubclass(w.category, DataQualityWarning)]

Logging — internal operational detail

Operational diagnostics (cache writes, ephemeris setup) go to the stellium logger, which has a NullHandler and is off by default. Turn it on with one call:

import stellium
stellium.configure_logging("INFO")     # or "DEBUG", "WARNING", ...

configure_logging attaches a stream handler and sets the level. You can point it anywhere and customize the format:

import sys
stellium.configure_logging("DEBUG", stream=sys.stdout, fmt="%(levelname)s: %(message)s")

Prefer to wire it into your own logging setup? Just configure the stellium logger directly — Stellium never adds handlers of its own beyond the NullHandler:

import logging
logging.getLogger("stellium").setLevel(logging.DEBUG)
logging.basicConfig()  # your application's handlers

Which is which?

  • Warning = “you (the caller) should know — act on it or suppress it.” On by default.

  • Log = “what Stellium did internally, for when you’re debugging.” Off by default; opt in with configure_logging.

Contributors: the rule that keeps this consistent (and the ban on bare print) is in CONTRIBUTING.md; the full design is in docs/development/specs/STRUCTURED_LOGGING_SPEC.md.