Skip to content

Your First Brahe Script

This page will walk you through setting up your environment and writing your first Brahe script. All subsequent examples in the getting started guide and documentation will assume you are using this same environment setup.

Environment Setup

Python

For python, we will assume you are using uv as your package manager and environment tool. If you haven't already installed it, you can so from their instructions here.

Rust

In rust we'll use rust-script to run a single-file rust script without needing to setup a full cargo project. You can install rust-script with cargo:

cargo install rust-script

Migration to cargo-script

Rust is building native support for running single-file scripts with "cargo script" in an upcoming release (tracking issue). Once this is available we will migrate over to using the native cargo support and remove the rust-script dependency.

Preamble

To use Brahe in a script, we need to declare it as a dependency of the script so that it is properly imported when we run the script. To do this you can use the following preamble at the top of your script file:

# /// script
# dependencies = ["brahe"]
1
2
3
4
5
6
7
//! ```cargo
//! [dependencies]
//! brahe = "*"
//! nalgebra = { version = "*", features = ["serde-serialize"] }
//! serde_json = "*"
//! rayon = "*"
//! ```

Your First Script

Now we can write your first script. We'll use Brahe to predict the next time the International Space Station (ISS) will be in view of NASA Johnson Space Center (JSC) in Houston, TX.

To do this, we need to import brahe, download the latest ephemeris information for the ISS, and then use that information to predict the next pass of the ISS over JSC, and print the results.

To do this, add the following code to your script after the preamble:

import brahe as bh

# Initialize EOP
bh.initialize_eop()

# Set the location
location = bh.PointLocation(
    -122.4194,  # Longitude [deg]
    37.7749,    # Latitude [deg]
    0.0         # Altitude [m]
    ).with_name("San Francisco")

# Get the latest TLE for the ISS (NORAD ID 25544) from Celestrak
client = bh.celestrak.CelestrakClient()
propagator = client.get_sgp_propagator(catnr=25544, step_size=60.0)

# Configure Search Window
epoch_start = bh.Epoch.now()
epoch_end = epoch_start + 7 * 86400.0  # 7 days later

# Set access constraints -> Must be above 10 degrees elevation
constraint = bh.ElevationConstraint(min_elevation_deg=10.0)

# Compute access windows
windows = bh.location_accesses(location, propagator, epoch_start, epoch_end, constraint)

# Print first 3 access windows
for window in windows[:3]:
    print(
        f"Access Window: {window.window_open} to {window.window_close}, Duration: {window.duration / 60:.2f} minutes"
    )

Save this file as first_script.py and you can run it with:

uv run first_script.py
#[allow(unused_imports)]
use brahe as bh;
use brahe::utils::Identifiable;

fn main() {
    // Initialize EOP
    bh::initialize_eop().unwrap();

    // Set the location
    let location = bh::PointLocation::new(
        -122.4194,      // Longitude [deg]
        37.7749,        // Latitude [deg]
        0.0             // Altitude [m]
    )
        .with_name("San Francisco");

    // Get the latest TLE for the ISS (NORAD ID 25544) from Celestrak
    let client = bh::celestrak::CelestrakClient::new();
    let propagator = client.get_sgp_propagator_by_catnr(25544, 60.0).unwrap();

    // Configure Search Window
    let epoch_start = bh::Epoch::now();
    let epoch_end = epoch_start + 7.0 * 86400.0;  // 7 days later

    // Set access constraints -> Must be above 10 degrees elevation
    let constraint = bh::ElevationConstraint::new(Some(10.0), None).unwrap();

    // Compute access windows
    let windows = bh::location_accesses(
        &location,
        &propagator,
        epoch_start,
        epoch_end,
        &constraint,
        None,
        None,
    ).unwrap();

    // Print first 3 access windows
    for window in windows.iter().take(3) {
        println!(
            "Access Window: {} to {}, Duration: {:.2} minutes",
            window.window_open,
            window.window_close,
            window.duration() / 60.0
        );
    }
}

Save this file as first_script.rs and you can run it with:

rust-script first_script.rs

You can see the expected output below:

Output
1
2
3
Access Window: 2026-06-17 12:26:23.845 UTC to 2026-06-17 12:32:59.632 UTC, Duration: 6.60 minutes
Access Window: 2026-06-17 14:04:04.460 UTC to 2026-06-17 14:09:17.839 UTC, Duration: 5.22 minutes
Access Window: 2026-06-17 17:22:10.837 UTC to 2026-06-17 17:23:12.336 UTC, Duration: 1.02 minutes
1
2
3
Access Window: 2026-06-17 12:26:23.845 UTC to 2026-06-17 12:32:59.631 UTC, Duration: 6.60 minutes
Access Window: 2026-06-17 14:04:04.461 UTC to 2026-06-17 14:09:17.839 UTC, Duration: 5.22 minutes
Access Window: 2026-06-17 17:22:10.837 UTC to 2026-06-17 17:23:12.336 UTC, Duration: 1.02 minutes