openmeteo-rs 1.0.0

Rust client for the Open-Meteo weather API.
Documentation
# openmeteo-rs

Typed async Rust client for the [Open-Meteo](https://open-meteo.com/) API.

`openmeteo-rs` builds Open-Meteo requests with Rust enums instead of raw query
strings, validates common parameter mistakes before sending, and decodes
weather responses into nullable column-oriented time series.

## Quickstart

```toml
[dependencies]
openmeteo-rs = "1"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
```

```rust
use openmeteo_rs::{Client, HourlyVar, Result};

#[tokio::main]
async fn main() -> Result<()> {
    let client = Client::new();
    let response = client
        .forecast(52.52, 13.41)
        .hourly([HourlyVar::Temperature2m, HourlyVar::Precipitation])
        .forecast_days(1)
        .send()
        .await?;

    if let Some(hourly) = response.hourly {
        for row in hourly.iter_rows().take(6) {
            println!(
                "{} temp={:?} precipitation={:?}",
                row.time(),
                row.temperature_2m(),
                row.precipitation()
            );
        }
    }

    Ok(())
}
```

## Supported APIs

- Forecast, including multi-location forecast requests
- Historical archive
- Historical forecast
- Previous model runs
- Ensemble forecast
- Seasonal forecast
- Climate projections
- Marine forecast
- Air quality
- Satellite radiation
- Flood forecast
- Geocoding
- Elevation lookup

Most weather-like endpoints support typed variable selection, units, timezones,
cell selection, fixed or relative time windows, JSON decoding, nullable values,
and exact-token escape hatches. When Open-Meteo adds a token before the crate
exposes it as a typed variant, use the relevant `other(...)` constructor, for
example `WeatherModel::other("exact_model_token")`.

## Multi-Location Forecast

```rust
use openmeteo_rs::{Client, HourlyVar, Result};

# async fn example() -> Result<()> {
let client = Client::new();
let responses = client
    .forecast_batch([(52.52, 13.41), (47.3769, 8.5417)])
    .hourly([HourlyVar::Temperature2m])
    .forecast_days(1)
    .send()
    .await?;

for response in responses {
    println!("{},{}", response.latitude, response.longitude);
}
# Ok(())
# }
```

## Geocode Then Forecast

```rust
use openmeteo_rs::{Client, HourlyVar, Result};

# async fn example() -> Result<()> {
let client = Client::new();
let Some(location) = client.geocode("Zurich").count(1).send().await?.into_iter().next() else {
    return Ok(());
};

let forecast = client
    .forecast(location.latitude, location.longitude)
    .hourly([HourlyVar::Temperature2m])
    .forecast_days(1)
    .send()
    .await?;

println!("{:?}", forecast.hourly);
# Ok(())
# }
```

## Examples

Examples live under `examples/<endpoint>/` but keep stable Cargo target names.

```sh
cargo run --example forecast_basic
cargo run --example forecast_multi_location
cargo run --example geocode_then_forecast
cargo run --example archive_basic
cargo run --example historical_forecast_basic
cargo run --example previous_runs_basic
cargo run --example ensemble_basic
cargo run --example seasonal_basic
cargo run --example climate_basic
cargo run --example marine_basic
cargo run --example air_quality_basic
cargo run --example satellite_radiation_basic
cargo run --example flood_basic
cargo run --example elevation
```

## Limitations

These capabilities are intentionally not part of the first stable JSON release:

- FlatBuffers responses
- Polars or Arrow exports
- blocking client API
- batch builders for every endpoint family
- reverse geocoding, which Open-Meteo does not currently provide
- CSV/XLSX decoding; request JSON and export from your application instead

## Attribution

Open-Meteo data is licensed under CC BY 4.0. Applications using the API should
include attribution such as `Weather data by Open-Meteo.com`.

This crate is MIT licensed.