Use one documented schema across sources.

Mostly Right maps provider keys, units, identifiers, and missing-value sentinels into documented fields. Functions and columns use descriptive names, and every row says which source produced it.

observation.json
 {
  "station": "KNYC",
  "event_time_utc": "2025-01-15T23:51:00Z",
  "temp_c": -2.2,
  "temp_f": 28.0,
  "dewpoint_c": -13.9,
  "visibility_miles": 10.0,
  "source": "iem",
  "raw_metar": "METAR KNYC ..."
} 

Keep columns, units, and nulls consistent.

Provider-specific payloads are normalized before the row reaches your code. Source identity and missing measurements remain explicit.

Keep columns consistent

Provider keys map to documented fields such as event_time_utc, temp_c, visibility_miles, and source.

Read units in the name

Fields such as temp_c, wind_speed_ms, and precipitation_mm_1h state the unit used by each value.

Keep missing values null

Provider sentinels and omitted measurements become null, never zero, an empty string, or a guessed value.

Read the call and the result without a translation guide.

Functions say what they return. Arguments repeat across related calls. Columns state the measurement and unit.

weather.observations()
The function name states the data it returns. Domain namespaces keep related calls together.
station / from_date / to_date
The same argument names repeat across supported date-bound reads.
temp_c / visibility_miles
Column names state the measurement and unit without a separate provider key map.
source / raw_metar
The normalized row retains the selected provider and original record when the source exposes it.

Change providers without changing downstream code.

Adapters absorb supported provider differences and return the documented schema for that data domain.

  1. 01

    Call the data you need

    Python and TypeScript use corresponding names such as weather.observations() and weather.forecasts().

  2. 02

    Write against one schema

    Build analysis on documented columns, units, null behavior, and identifiers rather than provider payloads.

  3. 03

    Handle outcomes by type

    NoDataError and ContractError separate missing data from an invalid request without parsing error strings.

Build on the schema, not the provider payload.

// contact

Talk to the team

Self-serve signup lives at app.mostlyright.md. This form is for everything it cannot do: procurement, invoicing, custom licensing, or anything you want to ask first. We reply by email.

I'm a

One email from the team. No spam.