2025 Aug 15 – Ephem Devlog 01
Since I first posted about the pyswisseph library, I've been working on the first version of my CLI-only Astrolog... not quite replacement, but a tool used in conjunction. I call it Ephem, and it's ant to approximate the experience of looking up dates in a print ephemeris like The American Ephemeris by Neil F. Michelsen and Rique Pottenger, which I am constantly moving on and off my desk in the pursuit of minimalism.
This is my first ever devlog for maybe my... third ever Python project? So I'm following the example of Mitchell Hashimoto's Ghosttty devlogs.
Tech stack
Ephem should work anywhere you have a terminal emulator. It depends on these Python libraries, most of which are standard:
- pyswisseph
- rich
- argparse
- datetime
- zoneinfo
- configparser
- re
- sys
- sqlite3
Some strong choices
The philosophy of Ephem as it heads (quickly) toward 1.0 is if I don't personally use it, it's not in scope. Astrology is a vast and multitudinous practice with many traditions. Frankly, I wouldn't feel comfortable adding a feature I don't understand, like anything for astrocartography, but I do occasionally look at the sidereal zodiac, so ayanamsas make the cut.
A lot of this comes down to a term I just learned, "domain knowledge." Which is the ultimate conundrum of making open-source software for a very niche community: everyone has different needs, and no matter how popular Python is as a language, contributors with enough astrological knowledge to meet them... could be everyone Dependabot finds using pyswisseph. Maybe.
But I don't want to maintain a project that aims to please everyone, because I don't know everyone! I belong to a generation of astrologers who read premodern sources in translation. We're a minority in all of western astrology. I wrote a little about "sane defaults" and astrology software in my Aquarius full moon newsletter: every astrology software is rooted in the develooper's personal practice.
Ephem is no different. I practice natal and electional astrology, so I think Ephem v1.0 benefits natal and electional astrologers who only use 7-10 planets, no asteroids. I think it also suits horary astrologers.
- I have no interest in house cusps. Ephem replicates an ephemeris, not tables of houses. (I also squarely blame the availability of The Michelsen Book of Tables: Koch and Placidus Tables of Houses for those house systems' popularity among older western astrologers, by the way.) It's quite easy to ignore house cups because the sweph houses function returns two tuples: one with house cusps, which are quite boring if you use whole sign houses like I do, and one with the ascendant, midheaven, and various "co-" and hypothetical ascendants.
- I was born in a 3k-person town, so I intimately know atlas data is rarely able to find extremely rural locations. I don't care that Astro.com can. I put myself through an angular hand-calculation bootcamp that mostly gave me a greater appreciation of geography. Maybe it's Saturnine of me, but astrologers should concern themselves with coordinates in part because they have such a great effect on the angles.
- A strong choice I quickly had to backtrack: I initially only accepted UTC dates and standard times, thinking of my hand-calculation journey, but this blew up in my face at my first field use of this tool! I had a client born at 86W and nearly midnight UTC. They're from a state that observes daylight savings inconsistently, and 90W is the CST meridian. So I knew I had to add time zone support because the client's exact word is important information.
All that said, this first devlog will look at Ephem's four (so far) commands.
ephem now and ephem asc
ephem now
replicates the Chart of the Moment on Astro.com, which you can get to by clicking the ☉☽☿ at the top right of their header. It prints planetary positions with no geographic information as a table, which you can also view as a horoscope wheel. Considering this entire pursuit started with the need for a humble ascendant clock for my swaybar, it only makes sense to localize the Chart of the Moment.
In my adventures with asc-mc calculation by hand, I developed such a distaste for time zones and daylight savings that I didn't think twice about using datetime.now(timezone.utc)
for this.
ephem asc
calls a slim little module that's a efficient version of the ascendant clock I made last month.
ephem cast
I would have stopped at this being an only-astrology-of-right-now app if the reality of electional astrology wasn't that we need to shift around in the future looking for cute dates. This is the reason for ephem now --shift
, which uses ReGex to interpret a string like "1h" or "2d" to shift the current time by that amount, but that's not viable for if you're, say, electing a wedding or an app launch. So the function to cast a chart for a specific date and time became necessary.
What's been a real headache here is I often cast charts with incomplete information, like missing times (Taylor Swift's birth chart) or uncertain locations (announcing Debian Linux), and I still want to see a hypothetical without time and locale data like the angles.
This was more an adventure with argparse than anything. Astrolog takes data for its -q
command switch in a strict, positional order. I first tried using an excess of optional flags so finding Taylor Swift's hypothetical chart would look like
ephem cast --date 1989-12-13 --lat 40.33 --lng -75.9505 --name "Taylor Swift"
This gets a bit convoluted, so I now break down a list called EVENT that goes DATE [TIME] [TITLE]
. I kind of want to make the coordinates a list, too, but I don't know about prescribing two positional arguments in a row.
A casual little imperialism of Astro.com is given an unknown location, it defaults to Greenwich, England. Why? Longitude 0, of course, but why bias it to such an insanely northern latitude? I do not care about the history of GMT, so my fallback is instead Null Island, a buoy in the Gulf of Guinea at 0 N, 0 E. I happen to read the charts of quite a few equatorial and southern hemisphere biths, so Greenwich is especially absurd.
Besides all that... if a chart is hypothetical, you shouldn't even have the possibility of being led astray by inaccurate angles, so I don't print them at all if time is missing. Locale is another story; you may be casting an electional chart for yourself, so to you'll need to use a display flag to toggle angles off if you know you're missing coordinates.
ephem config
I keep a sticky note with my IP-geolocated coordinates on my monitor and have typed them countless times without having them memorized, so a simple .ini or .yaml config file for calculation defaults a must. This also allows for display options like whether to show angles or not; hiding coordinates, because I'm sick of almost doxxing myself sharing electional charts; disabling color output for readability/accessibility; and between a sensible 3 ANSI schemes.
- By sect (default): Mimics Astro.com's Hellenistic chart style. I'm very proud of my Mercury sect logic.
- By mode: Uses sign modalities to color the planets. Good for visualizing trines and sextiles.
- By element: Uses sign elements to color the planets. Helps visualize squares and oppositions.
That's it, so far. My last planned feature before 1.0 is a YAML/SQLite chart database, which I suspect is a weekend's work and will warrant a post of its own. Until then!