Skip to main content

sgp4-predict — Python bindings

Test PyPI Python versions License: MIT OR Apache-2.0

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

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)

Source distribution for sgp4-predict 0.2.0
File Size Uploaded
sgp4_predict-0.2.0.tar.gz 344.3 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for sgp4-predict 0.2.0
File
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 log

Release 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 log

Release 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 log

Release 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 log

Release 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 log

Release 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 log

Release 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

Release history Release notifications | RSS feed

0.3.0

7 release files

0.2.1

7 release files

This release

0.2.0 This release

7 release files

0.1.0

7 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page