133 lines
4.3 KiB
Markdown
133 lines
4.3 KiB
Markdown
# Weather API Integration
|
|
|
|
This document describes the external Weather API contract used by
|
|
`weatherreporter`.
|
|
|
|
## Purpose
|
|
|
|
`weatherreporter` uses a configured Weather API base URL to fetch normalized
|
|
weather source data and assemble a `forecast.Bundle`. This is an integration
|
|
contract for the project adapter, not a complete public API reference for the
|
|
upstream service.
|
|
|
|
## Base URL
|
|
|
|
`weather_api.base_url` must be an absolute URL. Adapter requests join this base
|
|
URL with the endpoint paths listed below. Generation and explicit bundle fetches
|
|
fail before any HTTP request when the base URL is empty or not absolute.
|
|
|
|
The HTTP client uses `weather_api.timeout`.
|
|
|
|
## Response Envelope
|
|
|
|
Every response used by the adapter must be JSON with a top-level `data` field:
|
|
|
|
```json
|
|
{
|
|
"data": {}
|
|
}
|
|
```
|
|
|
|
For most sources, `data: null` is treated as a missing source. Missing optional
|
|
sources follow the configured missing-source policy. Missing hourly forecast
|
|
data fails bundle fetching because hourly periods are required for report
|
|
generation.
|
|
|
|
`/alerts/active` is the exception: a successful response with `data: null`
|
|
means the endpoint was checked and there are no current active alerts. The
|
|
adapter records a non-missing alerts source and an empty alert run.
|
|
|
|
Malformed JSON envelopes, non-2xx statuses, and response read failures include
|
|
endpoint context in returned errors. Decode errors include source context when
|
|
they fail the fetch; optional malformed sources follow the missing-source policy.
|
|
|
|
## Query Parameters
|
|
|
|
The adapter sends these query parameters:
|
|
|
|
- `format`: from `weather_api.format`; the implemented configuration requires
|
|
`json`
|
|
- `units`: from `weather_api.units`
|
|
- `precision`: from `weather_api.precision` on observations, current
|
|
conditions, hourly forecast, and narrative forecast requests
|
|
- `tz`: from `weather_api.timezone` on hourly forecast, narrative forecast, and
|
|
discussion requests
|
|
|
|
Alerts do not receive `precision` or `tz`.
|
|
|
|
## Endpoints Used
|
|
|
|
The adapter fetches these endpoints once per bundle:
|
|
|
|
- `/observations`
|
|
- `/conditions/current`
|
|
- `/forecast/hourly`
|
|
- `/forecast/narrative`
|
|
- `/alerts/active`
|
|
- `/discussion`
|
|
|
|
`weatherreporter` does not call day-slice forecast endpoints or discussion
|
|
subsection endpoints. Report-period selection and daypart summarization happen
|
|
inside Go after the full hourly and narrative products are fetched.
|
|
|
|
## Required And Optional Sources
|
|
|
|
Hourly forecast is required:
|
|
|
|
- `data: null` for `/forecast/hourly` fails the fetch.
|
|
- an hourly forecast with no `periods` fails the fetch.
|
|
- malformed hourly data fails the fetch.
|
|
|
|
Other fetched sources are optional and follow `missing_source.default` or a
|
|
source-specific `missing_source.sources` policy:
|
|
|
|
- `observations` for `/observations`
|
|
- `current` for `/conditions/current`
|
|
- `narrative` for `/forecast/narrative`
|
|
- `alerts` for `/alerts/active`
|
|
- `discussion` for `/discussion`
|
|
|
|
The adapter also creates missing stub source records for `daily` and
|
|
`weather_story` because those source slots exist in the internal bundle but are
|
|
not fetched from the Weather API.
|
|
|
|
Policy behavior:
|
|
|
|
- `error`: fail the fetch for that source
|
|
- `warn`: omit the source data, add a warning, and continue
|
|
- `none`: omit the source data and continue without a warning
|
|
|
|
For `/alerts/active`, an HTTP error or missing `data` field still fails or
|
|
follows the relevant error path, but explicit `data: null` is not a
|
|
missing-source condition.
|
|
|
|
## Source Identity
|
|
|
|
For source payloads accepted into the bundle, including the explicit `null`
|
|
alerts payload, the adapter records:
|
|
|
|
- source name
|
|
- endpoint path
|
|
- query parameters sent
|
|
- fetch time
|
|
- source issue and update timestamps when present in the payload
|
|
- SHA-256 hash of the compact raw `data` JSON
|
|
|
|
Warnings are recorded both on the affected source and on the bundle-level
|
|
warnings list.
|
|
|
|
## Compatibility Assumptions
|
|
|
|
The adapter expects payload fields compatible with the internal forecast bundle
|
|
types in `internal/forecast/bundle.go`, including:
|
|
|
|
- observation timestamps and observation values
|
|
- current condition values
|
|
- forecast run metadata and `periods`
|
|
- active alert run data
|
|
- discussion metadata, key messages, and short/long-term sections
|
|
|
|
The adapter intentionally keeps upstream transport and envelope details inside
|
|
`internal/adapters/weatherapi`; downstream packages consume the normalized
|
|
bundle.
|