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.total_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.1

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.1
File Size Uploaded
sgp4_predict-0.2.1.tar.gz 346.3 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for sgp4-predict 0.2.1
File
sgp4_predict-0.2.1-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
sgp4_predict-0.2.1-cp310-abi3-musllinux_1_2_x86_64.whl CPython 3.10 abi3 Linux musl 1.2+ x86-64 Details
sgp4_predict-0.2.1-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.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
sgp4_predict-0.2.1-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
sgp4_predict-0.2.1-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 4.3 MB

Release files / sgp4_predict-0.2.1.tar.gz

Download URL sgp4_predict-0.2.1.tar.gz
Size 346.3 kB
Tags Source
SHA-256 checksum
How to use checksums
1e9df843f9c1708c4f819f05bfb0f68c74ed291d59cce988881612661cb9d698
BLAKE2b-256 checksum
How to use checksums
4a7d4aa9cebc7138d15daa590fde562fd95c0dc67db5ab3ce30b3b139dbceb55
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 26, 2026.

Transparency log

Release files / sgp4_predict-0.2.1-cp310-abi3-win_amd64.whl

Download URL sgp4_predict-0.2.1-cp310-abi3-win_amd64.whl
Size 468.3 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
9cc0f32c5b202115bbc20f794e22808a5ab1dfb663f95179d252d1aec308c517
BLAKE2b-256 checksum
How to use checksums
73b8f6496ab72b7cdeea8dc7ebd4b90e738da1e4af92e55a7c26fea1975fc8bc
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 26, 2026.

Transparency log

Release files / sgp4_predict-0.2.1-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL sgp4_predict-0.2.1-cp310-abi3-musllinux_1_2_x86_64.whl
Size 887.5 kB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
f5f40a5d37d58e50c67532c3924a69b2d3d50e7dc61f6dc6e646675da215f3fe
BLAKE2b-256 checksum
How to use checksums
dbbe00918b6be2030257f1a8e4ab88120c3e72b3a822d4e45bd1ce1eb431eca4
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 26, 2026.

Transparency log

Release files / sgp4_predict-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL sgp4_predict-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 686.4 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
cd86d9435d1c9930eb365389ca84c6bdda21e5a2752f5ac05dd672dafc14588f
BLAKE2b-256 checksum
How to use checksums
64765f650376fdf35e6ac80c8e26a9ec25136815fb90e33c56bfc20e39526bfa
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 26, 2026.

Transparency log

Release files / sgp4_predict-0.2.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL sgp4_predict-0.2.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 669.4 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
6fa03a1892486d0455a34051bf426947a189a153fb0c47e571cd0e90e3bc3a64
BLAKE2b-256 checksum
How to use checksums
5644db7dd874b6330ffda83b1dafc2f5805fdfcdd0b113961a72aef110de6d50
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 26, 2026.

Transparency log

Release files / sgp4_predict-0.2.1-cp310-abi3-macosx_11_0_arm64.whl

Download URL sgp4_predict-0.2.1-cp310-abi3-macosx_11_0_arm64.whl
Size 608.6 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
ae1c9178249231d86589858b2524971eb6b44de9a82cea184a998f815d77b4d7
BLAKE2b-256 checksum
How to use checksums
73aac93b589fbfdaf24fd175b11f2f76608290e948aaa282ebc727a67cbdef18
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 26, 2026.

Transparency log

Release files / sgp4_predict-0.2.1-cp310-abi3-macosx_10_12_x86_64.whl

Download URL sgp4_predict-0.2.1-cp310-abi3-macosx_10_12_x86_64.whl
Size 600.5 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
2440479cfc3e75fd18cbd4e5f95b00adbfa28a3095c6d04a7ed14c15f8bd0a32
BLAKE2b-256 checksum
How to use checksums
b00503e1185ba8b00495bc127acca306c8420841f92d9ce6965f779283de3c02
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 26, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

7 release files

This release

0.2.1 This release

7 release files

0.2.0

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