sgp4-predict — Python bindings
Python bindings for the sgp4-predict Rust library:
satellite pass prediction from TLE or OMM data, with type stubs and native datetime support.
pip install sgp4-predict
Quick start
Find the passes over a ground station and sample each one:
from datetime import datetime, timedelta, timezone
from sgp4_predict import GroundObserver, Interval, Predictor, Tle
tle = Tle(
"SENTINEL-2C",
"1 60989U 24157A 25356.66913557 .00000141 00000+0 70244-4 0 9990",
"2 60989 98.5671 69.0082 0001197 95.1447 264.9872 14.30821394 67740",
)
predictor = Predictor.from_tle(tle)
glasgow = GroundObserver(latitude_deg=55.86, longitude_deg=-4.25, altitude=40.0)
start = datetime(2025, 12, 22, tzinfo=timezone.utc)
window = Interval(start=start, end=start + timedelta(days=1))
for transit in predictor.transits_iter(glasgow, window, min_elevation_deg=5.0):
print(f"AoS {transit.start} → LoS {transit.end} ({transit.duration_seconds:.0f}s)")
# A Transit is itself an interval, so it can be passed straight back in.
for t, obs in predictor.observation_iter(glasgow, transit, timedelta(seconds=10)):
print(f" {t} az={obs.azimuth_deg:.1f}° el={obs.elevation_deg:.1f}°")
Predictor
Construct from a Tle, or from Elements parsed from OMM JSON:
from sgp4_predict import Elements
predictor = Predictor.from_tle(tle) # raises ValueError if malformed
predictor = Predictor(Elements.from_json(omm_json)) # CCSDS OMM (Celestrak, Space-Track)
SGP4 accuracy degrades with element age — check predictor.tle_age_seconds(now) and treat LEO TLEs
older than 3–7 days with caution. Fresh TLEs are available from CelesTrak.
Besides transits_iter, Predictor yields apsides, sunlit and eclipse windows, ground-track
points, area overpasses and raw state vectors, and answers point queries such as propagate,
observe_at and sub_point. The package ships type stubs, so an IDE or help(Predictor) lists
them with their signatures and units.
Every method taking a time range accepts any object with .start and .end datetime properties —
an Interval, a Transit, an Illumination, an AoiWindow, or your own type. All iterators are
lazy.
Predictor.with_refinement(Refinement(...)) returns a copy with a different root-finder
configuration for event times.
Areas of interest
An area is a region on the ground; aoi_iter yields the windows in which it is within the
payload's reach. Points are LatLon objects, Geodetic objects whose altitude is ignored — so a
sub_point result can be passed straight in — or plain (latitude_deg, longitude_deg) tuples.
from sgp4_predict import Circle, LatLon, Polygon, Rectangle
# An arbitrary ring. Concave and self-intersecting rings are both fine, the ring
# closes itself, and vertex order does not matter.
scotland = Polygon([(54.0, -8.0), (54.0, -1.0), (60.0, -1.0), LatLon(60.0, -8.0)])
# A latitude/longitude box, whose north and south edges follow their parallels
# exactly. Runs eastward from the south-west corner, so this one wraps the
# antimeridian.
pacific = Rectangle((-20.0, 160.0), (20.0, -160.0))
arctic = Rectangle.latitude_band(66.5, 90.0)
# A circular area 500 km across. The radius is angular — a degree of arc is about
# 111.2 km on the ground.
cape_town = Circle((-33.9, 18.4), radius_deg=2.25)
for overpass in predictor.aoi_iter(scotland, window):
print(overpass.start, overpass.end)
A malformed area raises ValueError — fewer than three distinct vertices, a latitude outside
[-90, 90], a nan or infinite coordinate, a polygon larger than a hemisphere, an empty box, or
a circle radius outside (0, 90).
By default a window opens when the ground track itself crosses into the area. Pass
max_off_nadir_deg — the half-angle of the satellite's field of regard, the largest nadir angle the
payload can be slewed to — and the window instead covers whenever the area is within reach.
coverage chooses whether any part of the area or all of it must be in reach:
from sgp4_predict import Coverage
for window in predictor.aoi_iter(cape_town, interval, max_off_nadir_deg=30.0):
print(window.start, window.end)
# Every part of the area reachable at once, rather than any part of it. Needs a
# field of regard wider than the area, or no window ever opens.
predictor.aoi_iter(cape_town, interval, max_off_nadir_deg=30.0, coverage=Coverage.Full)
A window longer than max_window_duration — one hour by default — raises RuntimeError rather than
being yielded, since a window that long usually means the area is bigger than intended. Raise the
cap for an area that really is near-global:
band = Rectangle.latitude_band(-90.0, 60.0) # ~85 min of each 100-minute orbit
predictor.aoi_iter(band, window, max_window_duration=timedelta(hours=2))
An area the ground track never leaves at all — a whole-Earth box, or a band wider than the orbit's inclination reaches — has no window end to find, so it raises whatever the cap is set to.
min_step is the shortest crossing the scan is guaranteed to see. Lower it below the default second
for an area the ground track crosses faster than that. It also raises the scan's ten-minute upper
bound wherever it exceeds it, so a min_step above that pins every step there and a small area is
passed straight over.
Every detection method takes its tuning the same way, as keyword-only arguments left at the library's defaults unless passed.
Polygon edges are great-circle arcs, so two vertices at the same latitude are not joined along
the parallel: the arc bows toward the nearer pole, by about 0.05° for the 7° ring above and roughly
8° for vertices a quarter of the globe apart. Densify edges that long, or use Rectangle when the
region really is "these latitudes by these longitudes". A polygon must also fit inside a hemisphere —
polar caps, equator-spanning and antimeridian-spanning areas are all fine, a region larger than half
the globe is not.
Coordinate frames
propagate() returns a StateVectorTeme. The frame chain is available step by step if you need an
intermediate:
sv_teme = predictor.propagate(t) # StateVectorTeme
sv_ecef = sv_teme.to_ecef(t) # StateVectorEcef (GMST rotation)
sv_enu = sv_ecef.to_enu(gs) # StateVectorEnu (geodetic to local ENU)
obs = sv_enu.to_observation() # equivalent to predictor.observe_at(t, gs)
All three expose .position and .velocity as Vec3(x, y, z).
Units
SI throughout: positions in metres, velocities and range rate in m/s, apsis altitude in metres above
the WGS-84 equatorial radius. Angles are plain floats in degrees — every angular name is suffixed
_deg.
Azimuth is measured clockwise from north over (-180, 180], so a southwesterly bearing is negative
rather than the [0, 360) most tracking software reports.
Development
cd sgp4-predict-py/
uv sync --extra dev # create .venv and install dev dependencies
make dev # compile the Rust extension in-place (maturin develop)
make test # compile + run pytest
make lint # ruff check --fix + ruff format
make targets use uv run, so no venv activation is needed.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Metadata
Release files for sgp4-predict 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 | |
|---|---|---|---|
| sgp4_predict-0.2.0.tar.gz | 344.3 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| sgp4_predict-0.2.0-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| sgp4_predict-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl | CPython 3.10 | abi3 | Linux musl 1.2+ x86-64 | Details |
| sgp4_predict-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| sgp4_predict-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| sgp4_predict-0.2.0-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
| sgp4_predict-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl | CPython 3.10 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 4.2 MB
Release files / sgp4_predict-0.2.0.tar.gz
| Download URL | sgp4_predict-0.2.0.tar.gz |
|---|---|
| Size | 344.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
404a1b64dc1454002c6ef7604e44c6842ece9833c4c3c8bbea93aa6cefedaceb
|
|
BLAKE2b-256 checksum How to use checksums |
00e88ff4abe54f6a9bb919a280be8392d140ffe38c9beb2a573eccac98de7857
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / sgp4_predict-0.2.0-cp310-abi3-win_amd64.whl
| Download URL | sgp4_predict-0.2.0-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 459.0 kB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
90befa6897324b4a1b2f565123e7f0acda525d3e09dd6766f62beee20de5ca0d
|
|
BLAKE2b-256 checksum How to use checksums |
bc5031746d337280d26b63c39c60903ab7db9e6cb6a389890e01fa8b75c6a4c0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / sgp4_predict-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl
| Download URL | sgp4_predict-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 875.8 kB |
| Tags | CPython 3.10 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
197c4ef3c25fb9d205ade3518501651cf6a9522df77b21e5a67c25055cba3e2b
|
|
BLAKE2b-256 checksum How to use checksums |
e4b11c713fd7bc156e6bf2709f9ce4461a4e30c715c9f592835cb7d2ef62938c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / sgp4_predict-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | sgp4_predict-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 674.0 kB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
5df9c76238e270840827170ff6fea6132aa6797170b104003110f25fb7b88460
|
|
BLAKE2b-256 checksum How to use checksums |
2e93761448aa65b83ac9a17bcf08e7ac6349d2fd330e1b90514afdc05493906e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / sgp4_predict-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | sgp4_predict-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 656.8 kB |
| Tags | CPython 3.10 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
eaea0f2182a239ad186c3a23a29c3c47564a639741884e367a636a06f0df24de
|
|
BLAKE2b-256 checksum How to use checksums |
1b9907ff46230dd96dbd163f50f13fe8e97555a089cd2292194ecf0fc6257662
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / sgp4_predict-0.2.0-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | sgp4_predict-0.2.0-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 597.5 kB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
f38d75c2a0a4262b563ed9e962a44e401384bae1ef509f1de771950013e6ecdb
|
|
BLAKE2b-256 checksum How to use checksums |
ebd8edf02b3b38911bd48dfa72cd1dc525e430b7f53c1466a9684c2debfecbba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / sgp4_predict-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl
| Download URL | sgp4_predict-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 590.1 kB |
| Tags | CPython 3.10 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
a53d410418dc73cb046f4ac3d5d079f0dabe0a2fdc6d5b95d2eccf57858ffc5e
|
|
BLAKE2b-256 checksum How to use checksums |
9937375f1b467550446386e797b10c15f4e65b19775f9c8cd6135adb0e11ae46
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency log