CLI¶
Install the CLI extra:
pip install "omni-weather-forecast-apis[cli]"
The base package still installs the omni-weather wrapper because Python
extras cannot conditionally install console scripts. If the CLI dependencies
are absent, it exits 2 with an installation hint.
Interactive setup¶
omni-weather init [--config PATH]
The wizard writes all interaction to stderr and prompts in this order:
- Required latitude and longitude.
- At least one provider. Open-Meteo is the recommended, preselected keyless provider; MET Norway, NWS, and NBM are also keyless, and the other twelve are grouped under “Requires credentials.”
- One shared application name/contact email when MET Norway or NWS is used.
- Provider settings: NBM visibly collects its non-secret station ID. Keyed
provider credentials are masked; Xweather collects a client ID and client
secret, while Apple WeatherKit collects its team, service, and key
identifiers plus the path to the
.p8signing key. - A required SQLite path, defaulting to the platform data directory.
- One or more compatible granularities, defaulting to hourly and daily.
- Optional automatic daily collection at a chosen local time, using cron on Linux, launchd on macOS, or Windows Task Scheduler.
Generated TOML and every provider setting are validated before an exact preview
is displayed. The preview contains collected credentials. Nothing is created
or overwritten until the final confirmation. Writes are atomic; new
directories and the config receive private POSIX permissions. Explicit init
then offers a platform-native daily schedule, defaulting to no, followed by a
test forecast, defaulting to yes. Re-running init for the same config replaces
that config's managed schedule rather than adding a duplicate.
With no explicit --config, forecasts use the platform-native
omni-weather/config.toml, then the legacy
~/.config/omni_weather_forecast_apis.toml. If neither exists and stdin/stderr
are interactive, the wizard runs automatically and the original forecast
continues with its overrides. Non-interactive first use exits 2 with setup
instructions. An explicitly supplied missing file is always an error, and an
explicit path that exists but is not a file — a directory, for example — is
rejected before any provider work, also exiting 2.
Forecast¶
uv run omni-weather --config ./config.toml --lat 40.7128 --lon -74.0060
Each invocation performs exactly one forecast collection. For recurring collection, see Scheduling.
--provider and --granularity are repeatable, and narrow the run without
editing the config:
uv run omni-weather \
--config ./config.toml \
--lat 34.2484 \
--lon -117.1931 \
--sqlite ./forecasts.sqlite \
--provider open_meteo \
--provider nws \
--granularity hourly
Flags¶
| Flag | Description |
|---|---|
--config PATH |
TOML config path (default: platform path, then legacy path) |
--lat / --lon |
Coordinates in decimal degrees (override config) |
--sqlite PATH |
SQLite output file (overrides config); persistence is skipped when neither is set |
--format {table,json,csv,ndjson} |
Output format (default: table) |
--provider ID |
Restrict to one or more configured providers (repeatable) |
--granularity {minutely,hourly,daily} |
Granularity to request (repeatable) |
--language CODE |
Provider language preference |
--include-raw |
Persist raw provider payloads alongside normalized results |
--no-raw-archive |
Skip the raw HTTP payload archive (raw/<UTC timestamp>-<unique suffix>.jsonl.gz next to the SQLite database), which is written by default |
--timeout-ms N |
Override the default request timeout |
--debug |
Verbose logging to stderr and a log file next to the SQLite database, or ./omni-weather.log when --sqlite is omitted |
The forecast exit code is 0 when every provider succeeded, 1 when at least
one provider failed, and 2 for invalid arguments or configuration/load
errors. Partial provider failures are visible to schedulers and shell scripts.
When SQLite output is configured, the CLI caches coordinate-to-IANA-timezone
mappings in a companion file beside the forecast database. For example,
forecasts.sqlite uses forecasts.timezones.sqlite. Coordinates are keyed at
six decimal places and entries are refreshed after 30 days. Missing, locked,
corrupt, or unwritable cache state produces a warning and collection continues
uncached; the cache is an optimization, not a prerequisite for other providers.
Provider discovery¶
omni-weather providers
This renders one catalog shared with the setup wizard, including provider ID and name, coverage, supported granularities, authentication requirements, and official signup/setup links.
Diagnostics¶
omni-weather doctor [--config PATH] [--provider ID]... [--live]
Static doctor checks aggregate config presence, TOML and Pydantic validation, required coordinates, typed provider settings, recursive environment references, config/SQLite path type and writability, POSIX config permissions, duplicate registrations, provider/granularity compatibility, and the platform-native daily schedule. A missing or inactive schedule is a warning, not a failure. Environment variable names and presence are shown; values are never printed.
Repeatable --provider filters narrow provider-specific static and live checks;
top-level config and path checks always run. Static mode never contacts a
weather API. --live checks all enabled providers (or the selected filters),
skips statically invalid providers, and does not persist results. These calls
can consume provider quota, trigger rate limits, or incur provider charges.
Doctor exits 0 when required checks pass, including when there are warnings
only, and 1 for any static or live failure. Exit 2 is reserved for invalid
invocation or unexpected operational errors. Cancelling explicit init exits
0; cancelling automatic setup exits 2. Ctrl+C exits 130 with a concise
Aborted. message rather than a traceback.
Output formats¶
--format table (default) renders a per-provider summary table: status,
latency, row counts per granularity, and error details for failures.
--format json prints the entire normalized ForecastResponse as JSON on
stdout — ideal for piping into jq or another program:
uv run omni-weather --config config.toml --lat 40.7 --lon -74.0 --format json \
| jq '.results[] | {provider, status}'
--format csv and --format ndjson flatten forecast data for tooling such as
pandas, DuckDB, and jq. Every CSV row and every NDJSON forecast_point
object carries provider, model, granularity (minutely / hourly /
daily), the source timezone, and the normalized point fields; fields that
do not apply to a row's granularity are empty. NDJSON alert and
provider_error objects use their own schemas and do not carry model,
granularity, or source-timezone fields.
- csv — a single wide table with a fixed column order derived from the normalized schema. Weather alerts are omitted (a note is printed to stderr) and provider errors are summarized on stderr, so stdout stays machine-parseable.
- ndjson — one compact JSON object per line, each tagged with a
typeofforecast_point,alert, orprovider_error:
uv run omni-weather --config config.toml --lat 40.7 --lon -74.0 --format ndjson \
| jq 'select(.type == "forecast_point") | {provider, timestamp, temperature}'
SQLite output¶
When --sqlite (or sqlite in the config) is set, the CLI creates a
normalized database with these tables:
| Table | Contents |
|---|---|
forecast_runs |
Request metadata per invocation |
provider_results |
One row per provider outcome (success or error) |
source_forecasts |
One row per model/source forecast within a provider |
minutely_points |
Precipitation intensity at minute intervals |
hourly_points |
Normalized hourly forecast rows |
daily_points |
Normalized daily summary rows |
alerts |
Weather alerts and warnings |
provider_logs |
Per-provider lifecycle log entries per run |
provider_quota_usage |
Requests per provider per UTC day (daily quota enforcement) |
source_forecasts.timezone records the IANA timezone actually used for a
source's civil-time normalization. The companion timezone cache is intentionally
separate from this normalized forecast database.
The stacking_features view joins hourly points with their provider, model,
run cycle, and forecast horizon — a ready-made feature matrix for
downstream ensemble/ML work. See Database Design for the
complete relationship model, column reference, indexes, lifecycle, and query
examples, and Extending for downstream integration patterns.