CLI · commit 1da3695

skywatch

"What's up tonight?" astronomy planner CLI

Download skywatch.zip
Quickstart
unzip skywatch.zip && cd skywatch
uv venv .venv && uv pip install -p .venv/bin/python -e '.[dev]'
.venv/bin/python -m pytest -q

skywatch

skywatch answers the amateur astronomer's eternal question — what's up tonight? — completely offline. Give it a location and a date and it computes twilight times, the Moon's phase and rise/set, a planet table, the moonless dark-sky window and a ranked list of the best targets, and it draws an all-sky chart and altitude-vs-time plots as SVG. Every number comes from textbook algorithms implemented from scratch (Jean Meeus, Astronomical Algorithms; JPL approximate planetary elements; Roman 1987 constellation boundaries) — no skyfield, astropy or ephem, no network, no API keys.

Features

Install

cd skywatch
uv venv .venv && uv pip install -p .venv/bin/python -e '.[dev]'
source .venv/bin/activate          # or call .venv/bin/skywatch directly

Requires Python ≥ 3.11 (tomllib, zoneinfo); runtime dependencies are only click and rich.

Quickstart

skywatch config set-location --lat 18.52 --lon 73.86 --elev 560 --tz Asia/Kolkata --name Pune
skywatch config set-location --lat 51.5074 --lon -0.1278 --elev 11 --tz Europe/London --name London
skywatch tonight --date 2026-10-16
skywatch where Saturn --at "2026-10-16 23:30"
skywatch chart --date 2026-10-16 --at 22:00 -o sky.svg
skywatch altitude M31 M42 Saturn Jupiter --date 2026-10-16 -o alt.svg
skywatch calendar --month 2026-11
skywatch ical --month 2026-11 -o november.ics

Usage

All observing commands accept --location/-l NAME (default: the configured default location) or an ad-hoc --lat/--lon/--tz/--elev. Longitudes are east positive. Times are shown in the location's time zone.

skywatch tonight [--date YYYY-MM-DD] [--targets N]

The "night of" a date runs from local noon to local noon the next day.

$ skywatch tonight --date 2026-10-16
skywatch · Friday 16 October 2026 · Pune (+18.52°, +73.86°, Asia/Kolkata)

Sun & twilight                                      
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓
┃ Event                        ┃ Evening ┃ Morning ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━┩
│ Sunset / sunrise             │ 18:12   │ 06:29   │
│ Civil twilight (−6°)         │ 18:34   │ 06:07   │
│ Nautical twilight (−12°)     │ 18:59   │ 05:41   │
│ Astronomical twilight (−18°) │ 19:24   │ 05:16   │
└──────────────────────────────┴─────────┴─────────┘

Moon 🌒 Waxing Crescent, 33% illuminated · rise — · transit 16:51 · set 22:21
Dark-sky window (astronomical night, Moon down): 22:24–05:16 = 6.9 h

Planets (max altitude between sunset and sunrise)                                         
┏━━━━━━━━━┳━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Planet  ┃ Rise  ┃ Transit ┃ Set   ┃ Max alt     ┃ Mag  ┃ Size  ┃ Elong ┃ Constellation ┃
┡━━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━┩
│ Mercury │ 08:17 │ 13:52   │ 19:26 │ 16° @ 18:12 │ +0.1 │ 7.3"  │ 25°   │ Libra         │
│ Venus   │ 07:17 │ 12:56   │ 18:29 │ 3° @ 18:12  │ -4.2 │ 59.5" │ 14°   │ Virgo         │
│ Mars    │ 01:18 │ 07:47   │ 14:17 │ 72° @ 06:29 │ +1.0 │ 6.0"  │ 73°   │ Cancer        │
│ Jupiter │ 02:10 │ 08:32   │ 14:57 │ 60° @ 06:29 │ -1.9 │ 34.4" │ 61°   │ Leo           │
│ Saturn  │ 17:33 │ 23:36   │ 05:40 │ 73° @ 23:35 │ +0.4 │ 19.6" │ 167°  │ Cetus         │
│ Uranus  │ 20:35 │ 03:06   │ 09:37 │ 88° @ 03:07 │ +5.7 │ 3.7"  │ 138°  │ Taurus        │
│ Neptune │ 17:04 │ 23:05   │ 05:06 │ 71° @ 23:04 │ +7.7 │ 2.3"  │ 159°  │ Pisces        │
└─────────┴───────┴─────────┴───────┴─────────────┴──────┴───────┴───────┴───────────────┘
Top 15 targets (moonless astronomical night)                                                                              
┏━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━┳━━━━━━━━━━━┳━━━━━┳━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┓
┃ #  ┃ Target                          ┃ Type           ┃ Mag ┃ Best time ┃ Alt ┃ Dir ┃ Constellation ┃ Moon sep ┃ Score ┃
┡━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━╇━━━━━━━━━━━╇━━━━━╇━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━┩
│ 1  │ M45 Pleiades                    │ open cluster   │ 1.2 │ 02:43     │ 84° │ N   │ Taurus        │ 146°     │ 100   │
│ 2  │ M31 Andromeda Galaxy            │ galaxy         │ 3.4 │ 23:41     │ 67° │ N   │ Andromeda     │ 114°     │ 84    │
│ 3  │ M42 Great Orion Nebula          │ cluster+nebula │ 4.0 │ 04:30     │ 66° │ S   │ Orion         │ 145°     │ 78    │
│ 4  │ M44 Beehive                     │ open cluster   │ 3.1 │ 05:16     │ 57° │ E   │ Cancer        │ 148°     │ 78    │
│ 5  │ NGC 1499 California Nebula      │ nebula         │ 5.0 │ 02:59     │ 72° │ N   │ Perseus       │ 150°     │ 78    │
│ 6  │ M33 Triangulum Galaxy           │ galaxy         │ 5.8 │ 00:26     │ 78° │ N   │ Triangulum    │ 120°     │ 69    │
│ 7  │ NGC 1980 Lower Sword            │ cluster+nebula │ 2.5 │ 04:30     │ 66° │ S   │ Orion         │ 145°     │ 67    │
│ 8  │ NGC 7000 North America Nebula   │ nebula         │ 4.0 │ 22:24     │ 49° │ NW  │ Cygnus        │ 82°      │ 67    │
│ 9  │ NGC 2264 Christmas Tree Cluster │ cluster+nebula │ 3.9 │ 05:16     │ 80° │ SSE │ Monoceros     │ 162°     │ 66    │
│ 10 │ M35                             │ open cluster   │ 5.1 │ 05:01     │ 84° │ N   │ Gemini        │ 176°     │ 66    │
│ 11 │ NGC 752                         │ open cluster   │ 5.7 │ 00:57     │ 71° │ N   │ Andromeda     │ 126°     │ 63    │
│ 12 │ Saturn                          │ planet         │ 0.4 │ 23:41     │ 73° │ S   │ Cetus         │ 98°      │ 63    │
│ 13 │ NGC 2232                        │ open cluster   │ 3.9 │ 05:16     │ 67° │ S   │ Monoceros     │ 148°     │ 60    │
│ 14 │ M34                             │ open cluster   │ 5.2 │ 01:43     │ 66° │ N   │ Perseus       │ 135°     │ 59    │
│ 15 │ NGC 1981 Upper Sword            │ cluster+nebula │ 4.2 │ 04:30     │ 67° │ S   │ Orion         │ 146°     │ 58    │
└────┴─────────────────────────────────┴────────────────┴─────┴───────────┴─────┴─────┴───────────────┴──────────┴───────┘

The dark-sky window is astronomical night minus the time the Moon is above the horizon. When there is no such window (e.g. London in June) targets are ranked over the darkest period available instead, and the table title says which. A — rise time means the body was already up at the start of the noon-to-noon window.

skywatch where NAME [--at TIME] [--date DATE]

NAME can be Sun, Moon, a planet, a Messier/NGC/IC id (M42, NGC 869, ngc0869), a common name (Pleiades) or a star name (Sirius). --at accepts now (default), HH:MM or "YYYY-MM-DD HH:MM".

$ skywatch where Saturn --at "2026-10-16 23:30"
Saturn — Fri 16 Oct 23:30 Asia/Kolkata from Pune
  Altitude   +73.06°  (above horizon)
  Azimuth    174.78° (S)
  RA/Dec     00h42m35.7s +01°38′10″ (apparent, of date)
  RA/Dec     00h41m13.2s +01°29′22″ (J2000)
  Constellation  Cetus (Cet)
  Distance   8.4570 au (1265.1 million km), light time 70.3 min
  Magnitude  +0.40   diameter 19.6"   elongation 166.8°   phase 100% lit
  Next rise  Sat 17 Oct 17:28   next transit Fri 16 Oct 23:36 (alt 73°)   next set Sat 17 Oct 05:40

$ skywatch where M31 -l London --at "2026-10-16 23:00"
M31 Andromeda Galaxy — Fri 16 Oct 23:00 Europe/London from London
  Altitude   +75.25°  (above horizon)
  Azimuth    126.96° (SE)
  RA/Dec     00h44m12.8s +41°25′00″ (apparent, of date)
  RA/Dec     00h42m44.4s +41°16′13″ (J2000)
  Constellation  Andromeda (And)
  Type       galaxy, mag 3.4, size 177.8′
  Rise/set   circumpolar — never sets from this latitude

skywatch chart [--at TIME] [--date DATE] [--mag 4.5] -o sky.svg

Zenith-centred stereographic all-sky chart: horizon, 30°/60° altitude rings, cardinal points (east on the left, as when looking up), stars sized by magnitude, constellation figures and names, Messier objects, planets and the Moon. Example: examples/sky-pune-2026-10-16.svg.

Sky chart

skywatch altitude OBJ... [--date DATE] -o alt.svg

Altitude-vs-local-time curves from one hour before sunset to one hour after sunrise, on a background shaded by day / civil / nautical / astronomical twilight / night, with the Moon as a dashed reference line.

Altitude plot

skywatch calendar [--month YYYY-MM]

$ skywatch calendar --month 2026-11
Sky calendar · November 2026 · times in Asia/Kolkata                                                       
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ When             ┃ Event                                           ┃ Details                            ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Mon 02 Nov 01:58 │ ☾ Last Quarter                                  │                                    │
│ Mon 02 Nov 19:09 │ ☌ Moon–Mars conjunction                         │ separation 0.97°                   │
│ Tue 03 Nov 04:19 │ ☌ Moon–Jupiter conjunction                      │ separation 0.49°                   │
│ Fri 06 Nov 00:27 │ ☄ Southern Taurids meteor shower peak           │ ZHR ~5, radiant RA 2.1h Dec +9°    │
│ Sat 07 Nov 16:13 │ ☌ Moon–Venus conjunction                        │ separation 0.95°                   │
│ Mon 09 Nov 12:32 │ ☾ New Moon                                      │                                    │
│ Thu 12 Nov 23:44 │ ☄ Northern Taurids meteor shower peak           │ ZHR ~5, radiant RA 3.9h Dec +22°   │
│ Mon 16 Nov 09:36 │ ☌ Mars–Jupiter conjunction                      │ separation 1.19°                   │
│ Tue 17 Nov 17:18 │ ☾ First Quarter                                 │                                    │
│ Wed 18 Nov 05:19 │ ☄ Leonids meteor shower peak                    │ ZHR ~15, radiant RA 10.1h Dec +22° │
│ Sat 21 Nov 05:01 │ ∡ Mercury at greatest elongation west (morning) │ 19.6° from the Sun                 │
│ Tue 24 Nov 20:23 │ ☾ Full Moon                                     │                                    │
│ Thu 26 Nov 04:00 │ ☍ Uranus at opposition                          │ mag 5.7, 18.439 au                 │
│ Mon 30 Nov 13:58 │ ☌ Moon–Jupiter conjunction                      │ separation 1.06°                   │
│ Mon 30 Nov 22:25 │ ☌ Moon–Mars conjunction                         │ separation 3.00°                   │
└──────────────────┴─────────────────────────────────────────────────┴────────────────────────────────────┘

skywatch ical [--month YYYY-MM] [-o file.ics]

Writes the same events as RFC 5545 iCalendar (UTC timestamps, CRLF line endings, folded lines); without -o it prints to stdout. Example: examples/skywatch-2026-11.ics.

skywatch config ...

Command Purpose
config set-location --lat --lon [--elev] --tz --name [--default] add/update a named location (the first one becomes default)
config list show saved locations (* marks the default)
config use NAME change the default
config remove NAME delete a location
config path print the config file path

Configuration

Locations are stored as TOML in $XDG_CONFIG_HOME/skywatch/config.toml (normally ~/.config/skywatch/config.toml). Set SKYWATCH_CONFIG=/path/to/file.toml to use another file; the sample examples/config.toml holds Pune and London:

default = "Pune"

[locations."Pune"]
lat = 18.52
lon = 73.86
elev = 560.0
tz = "Asia/Kolkata"

Elevation scales atmospheric refraction by the standard-atmosphere pressure ratio.

Architecture

Module Responsibility
astrotime.py Julian Day, ΔT, GMST/GAST/LST, datetime ↔ JD
coords.py nutation, obliquity, precession, frame transforms, Bennett refraction, separations, formatting
sun.py solar position (Meeus 25), equation of time (Meeus 28)
moon.py lunar position (Meeus 47), phase angle and illumination (48), phase instants (49)
planets.py JPL approximate elements → apparent geocentric positions, magnitudes, sizes
catalog.py CSV catalog loading, constellation names, Roman (1987) constellation lookup
bodies.py Observer/Target model, name resolution, topocentric alt/az
riseset.py crossing search (bracket + bisection), rise/transit/set, twilight, interval sampling
planner.py tonight report: dark window, planet table, target scoring
events.py monthly events: phases, conjunctions, elongations/oppositions, meteor showers
charts.py SVG sky chart and altitude plot
ical.py iCalendar export
config.py TOML location store
cli.py click commands and rich tables
data/*.csv embedded catalogs, regenerated by tools/build_catalogs.py from HYG v3.8, OpenNGC, d3-celestial and CDS VI/42

See docs/algorithms.md for formulas, worked examples, the accuracy table and sources.

Tests

.venv/bin/pytest -q

70 tests: Meeus worked examples (7.a, 12.a/b, 13.b, 15.a, 16.a, 21.b, 22.a, 25.a, 28.b, 33.a, 47.a, 48.a, 49.a/b), sunrise/sunset for London and Pune against published tables (±2 min), twilight, circumpolar detection, the 2020 Jupiter–Saturn great conjunction (0.10°), USNO lunar phase times, the 2020 Mars opposition and Venus greatest elongation, the Roman (1987) reference points, catalog lookups, the scoring function, and end-to-end CLI runs including SVG well-formedness and iCalendar format.

Limitations