Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

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 GeodeticPoint, 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 = GeodeticPoint(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, point_at and sub_point. The package ships type stubs, so an IDE or help(Predictor) lists them with their signatures and units.

observe_at looks up from the ground; point_at looks down from the satellite, which is what an RF link budget or an instrument-pointing calculation needs:

pointing = predictor.point_at(t, glasgow)
d = pointing.direction  # unit vector in the satellite's LVLH frame
print(f"{pointing.off_nadir_deg:.1f}° off nadir, {pointing.range / 1000:.0f} km")

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, GeodeticPoint 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.3.0rc1

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.3.0rc1
File Size Uploaded
sgp4_predict-0.3.0rc1.tar.gz 355.9 kB Details

Built distributions (wheels)

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

Download URL sgp4_predict-0.3.0rc1.tar.gz
Size 355.9 kB
Tags Source
SHA-256 checksum
How to use checksums
092d41d5cc135e5a56e1a83ba49a2e65c56c79cefee39295a02044c54227282f
BLAKE2b-256 checksum
How to use checksums
2f539acefcd377a3913ebebd6c08b0e11279483ba1efa082340f90ce0c23d495
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 Sep 2, 2026.

Transparency log

Release files / sgp4_predict-0.3.0rc1-cp310-abi3-win_amd64.whl

Download URL sgp4_predict-0.3.0rc1-cp310-abi3-win_amd64.whl
Size 470.9 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
5d22b33502b28d77bf75a278d6f94bfbec8e53f4bbecde0b7b46561169cb5841
BLAKE2b-256 checksum
How to use checksums
c267ba5b8cb39ca6640d16871e19cafb3d6189c5dc1d3facbec8dcd5af8e002f
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 Sep 2, 2026.

Transparency log

Release files / sgp4_predict-0.3.0rc1-cp310-abi3-musllinux_1_2_x86_64.whl

Download URL sgp4_predict-0.3.0rc1-cp310-abi3-musllinux_1_2_x86_64.whl
Size 890.3 kB
Tags CPython 3.10 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
72c4b1553c3cef25864d16055a976a829cddb2b9d2852f1ecee8ce542674b3b6
BLAKE2b-256 checksum
How to use checksums
b3d76feff52b7524777c5ffa03654e0d37728234c034279e2b70537c359eb3c2
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 Sep 2, 2026.

Transparency log

Release files / sgp4_predict-0.3.0rc1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL sgp4_predict-0.3.0rc1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 690.0 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
5696ef64ff3267f08562c7fab07bc168fbd052edac17296b1dcfa8de462beaa4
BLAKE2b-256 checksum
How to use checksums
48a5ec6bd8f95115418ea55fcfcce179e91f33e4c51467a07028252519d3f80e
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 Sep 2, 2026.

Transparency log

Release files / sgp4_predict-0.3.0rc1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL sgp4_predict-0.3.0rc1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 675.0 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
e3c2558287f3343ce96c399e511452c14aad6700e2d4463e894d2bd802d58f30
BLAKE2b-256 checksum
How to use checksums
97a32587b75b2f3bfba5950c63e55823d57bc34e664fc5dd7296c307259e961f
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 Sep 2, 2026.

Transparency log

Release files / sgp4_predict-0.3.0rc1-cp310-abi3-macosx_11_0_arm64.whl

Download URL sgp4_predict-0.3.0rc1-cp310-abi3-macosx_11_0_arm64.whl
Size 615.0 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
7c9dcb99fa64363c0bae7d2c5e05acc60c12ecada3239249e297e6eb85cd5796
BLAKE2b-256 checksum
How to use checksums
cb63d3655a6bb88e49a9b3e42cd2445fe58825ca157601c029b77bd4d091758c
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 Sep 2, 2026.

Transparency log

Release files / sgp4_predict-0.3.0rc1-cp310-abi3-macosx_10_12_x86_64.whl

Download URL sgp4_predict-0.3.0rc1-cp310-abi3-macosx_10_12_x86_64.whl
Size 606.1 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
ae55ca77ae5b262df2f3991a7ae8f3af429fdb2e11d0e38aeccd74795d972b14
BLAKE2b-256 checksum
How to use checksums
c0d0f3479c58b78a7aa15b0923b0e714fd5b14c12d00790866dd65de9cb841d8
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 Sep 2, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

7 release files

This release

0.3.0rc1 This release

7 release files

0.2.1

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