pysatellitespotter
Predict when satellites are visible to the naked eye, the way See A Satellite Tonight does. This is a Python port of James Darpinian's site, made with his permission. It powers the Home Assistant Satellite Spotter integration.
This is a fork of Willem Vooijs's
see-a-satellite, with fixes for
crashes on valid catalog data and on passes past the prediction window
(wildekek/see-a-satellite#2).
It installs as its own module, pysatellitespotter, so it can sit beside
see-a-satellite in one environment, as it does when Home Assistant runs both
integrations.
pip install pysatellitespotter
import aiohttp
from pysatellitespotter import fetch_site_catalog, group_transits, predict_transits
async with aiohttp.ClientSession() as session:
satellites = await fetch_site_catalog(session)
# CPU bound (a few seconds): run it in an executor from async code.
for group in group_transits(predict_transits(satellites, 52.03, 5.56, 10)):
t = group.primary
print(group.start, t.satellite.name, f"mag {group.min_magnitude:.1f}",
f"rises {t.rise.azimuth:.0f}°/{t.rise.elevation:.0f}°", "bright" if group.bright else "")
What it computes
The pipeline follows the website step by step:
- Propagation. SGP4 runs from OMM elements at one-minute steps for 5 days, and positions are rotated from the TEME frame to Earth-fixed coordinates.
- Brightness. The intrinsic magnitude at 1000 km is adjusted for range, atmospheric extinction (Green 1992) and phase angle (diffuse sphere). Starlink and BlueBird satellites use their own phase-function models (Mallama et al. 2025; Cole et al. 2025).
- Visibility. A satellite counts as visible when it is at least 10° up, brighter than the limiting magnitude for the sun's depression (Weaver 1947), and lit by the sun above the troposphere (grazing height ≥ 15 km).
- Refinement and grouping. Each pass is refined to one second. Overlapping passes are grouped, incidental Starlinks are pruned, and a "bright" label is applied.
Checked against the website, for every pass the site shows over 5 days:
- start times agree within 9 s
- end times agree within 19 s
- magnitudes agree within 0.03
A 5-day prediction for the website's catalog of about 860 satellites takes 0.8 s on one core of an Apple M5. Minutes when the sky is too bright for a satellite to be seen are skipped, so most of the time goes to SGP4 for the twilight and night hours.
Catalog
fetch_site_catalog(session, "brightest" | "starlink") downloads the
website's catalog, which the site's author collects and curates. Orbital
elements come mostly from Space-Track (US
Space Force 18th Space Defense Squadron), and Starlink elements come from
CelesTrak. Magnitudes come from Mike McCants and the
MMT-9 survey (Karpov et al. 2016), and constellation phase functions come from
published photometry. See James's
write-up.
This library only consumes the catalog. The site refreshes it every 8 hours.
Cache it (dump_catalog / parse_site_catalog) rather than downloading it on
every prediction.
Development
uv sync
uv run pytest && uv run mypy && uv run ruff check src tests
Metadata
Release files for pysatellitespotter 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pysatellitespotter-0.2.0.tar.gz | 17.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pysatellitespotter-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.8 kB
Release files / pysatellitespotter-0.2.0.tar.gz
| Download URL | pysatellitespotter-0.2.0.tar.gz |
|---|---|
| Size | 17.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6d30c8d7a9899563849b42d8b20c9faf40afd013b2e0bcd903263ab610d626d6
|
|
BLAKE2b-256 checksum How to use checksums |
77b8f0b0c5f4b4856db0b26f369b745c0b3378d23a34c243d1e6a8e9ceee92fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / pysatellitespotter-0.2.0-py3-none-any.whl
| Download URL | pysatellitespotter-0.2.0-py3-none-any.whl |
|---|---|
| Size | 15.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
574254e38a87925c198f1912a0dfeaaf2df16701355b4a3020aa444476aeb84a
|
|
BLAKE2b-256 checksum How to use checksums |
6ba1c1dd5709763db10107764f4a8735776c053e01dc6e49b5eca7c4e26ddc36
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for pysatellitespotter 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.