NWP — API reference#
Open numerical-weather-prediction data source subpackage —
earthlens.nwp. Background and usage are covered under the other pages
in this section (Introduction, Usage,
Catalog & install); this page is the rendered API.
earthlens.nwp
#
NWP backend — open numerical-weather-prediction forecasts.
One subpackage over the open NWP buckets (NOAA NODD, ECMWF Open Data,
DWD Open Data, with Météo-France / ECCC as follow-ons). Unlike the
observation-time backends, NWP is indexed by a forecast time axis
(cycle_datetime_utc, forecast_step_hours): start / end select
the cycle date range and a steps= / horizon= kwarg picks the lead
times. The request is variables = {model_key: [param, ...]} and the
output is one bbox-cropped COG per (cycle, step).
Herbie owns the GRIB2 .idx byte-range subsetting for the NOAA /
ECMWF models; earthlens contributes a thin per-centre adapter plus
direct modules (DWD HTTPS .bz2) for what Herbie does not cover. The
[nwp] extra pulls herbie-data + ecmwf-opendata; both SDKs (and
the cfgrib / eccodes stack Herbie's import chain needs) are imported
lazily, so this package imports without the extra installed.
Public surface (re-exported from this package):
- :class:
NWP— the backend; instantiate with a date range, a bbox, and a{model_key: [param, ...]}mapping, then call :meth:NWP.download. - :class:
Catalog— pydantic-backed loader for the bundlednwp_data_catalog.yaml. - :class:
NWPModel— one curated model row (provider, cycles, backend, mirrors, band → selector map). - :data:
CATALOG_PATH— absolute path to the bundled catalog YAML; monkey-patchable to redirect the loader.
Catalog
#
Bases: AbstractCatalog
Model catalog for the NWP backend.
Reads the bundled nwp_data_catalog.yaml (shipped as package data)
and exposes its datasets: block as a typed dict[str, NWPModel].
Instantiate with no arguments (Catalog()) —
:func:model_post_init parses the YAML and populates
:attr:datasets in one pass.
Attributes:
| Name | Type | Description |
|---|---|---|
datasets |
dict[str, NWPModel]
|
Structural map keyed by the model key; each value is
an :class: |
Examples:
- Load the bundled catalog and check which models are present:
- Resolve one model and read its download backend:
Source code in libs/providers/atmosphere/src/earthlens/nwp/catalog.py
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | |
get_model(model_key)
#
Resolve a model key to its :class:NWPModel row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_key
|
str
|
A curated model key (e.g. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
NWPModel |
NWPModel
|
The resolved row. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When |
Examples:
- Resolve a known model:
- A typo raises with a did-you-mean hint:
Source code in libs/providers/atmosphere/src/earthlens/nwp/catalog.py
NWP
#
Bases: AbstractDataSource
Open numerical-weather-prediction backend (forecast time axis).
Resolves each requested model key against the bundled catalog,
dispatches its download to the matching centre module, and yields
one bbox-cropped COG per (cycle, step). Open buckets only — no
authentication.
Attributes:
| Name | Type | Description |
|---|---|---|
OUTPUT_KIND |
OutputKind
|
Fixed |
Source code in libs/providers/atmosphere/src/earthlens/nwp/backend.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 | |
__init__(start, end, variables, lat_lim, lon_lim, temporal_resolution='6hourly', path=None, fmt='%Y-%m-%d', *, mirror='auto', steps=None, horizon=None, members=None, mode='subset', catalog=None)
#
Initialise an NWP backend instance.
Resolves every requested model key against the catalog
before the parent constructor runs, because the parent
calls :meth:_initialize first and self.vars is not yet set
there.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
str
|
Inclusive start of the cycle-date range (parsed with
|
required |
end
|
str
|
Inclusive end of the cycle-date range. |
required |
variables
|
dict[str, list[str]]
|
Mapping from model key to a list of parameter
names, e.g. |
required |
lat_lim
|
list[float]
|
|
required |
lon_lim
|
list[float]
|
|
required |
temporal_resolution
|
str
|
Advisory label only — ignored by
NWP. The real cadence is per-model ( |
'6hourly'
|
path
|
Path | str | None
|
Output directory. Created by the parent class. |
None
|
fmt
|
str
|
|
'%Y-%m-%d'
|
mirror
|
str
|
Cloud-mirror key ( |
'auto'
|
steps
|
list[int] | None
|
Explicit forecast lead times in hours. Defaults to
|
None
|
horizon
|
int | None
|
Maximum forecast lead time in hours; expands to a
step list per model cadence (resolved in |
None
|
members
|
list[str] | None
|
Ensemble member ids to fetch (e.g. GEFS |
None
|
mode
|
str
|
How much of each GRIB2 to download — |
'subset'
|
catalog
|
Catalog | None
|
Optional pre-built :class: |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When |
Source code in libs/providers/atmosphere/src/earthlens/nwp/backend.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |
download(progress_bar=True, aggregate=None, errors='warn')
#
Fetch the requested forecasts as bbox-cropped COGs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress_bar
|
bool
|
Whether the centres show per-download progress
(threaded into Herbie's |
True
|
aggregate
|
AggregationConfig | None
|
Optional
:class: |
None
|
errors
|
str
|
How to treat a
|
'warn'
|
Returns:
| Type | Description |
|---|---|
list[Path]
|
list[Path]: One cropped COG per successfully fetched
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in libs/providers/atmosphere/src/earthlens/nwp/backend.py
NWPModel
#
Bases: BaseModel
One curated NWP model row.
Mirrors a single datasets.<key>: block in
nwp_data_catalog.yaml. The model key itself is the parent key in
:attr:Catalog.datasets and is not stored on the row.
Attributes:
| Name | Type | Description |
|---|---|---|
provider |
str
|
Provider slug (e.g. |
model_family |
str
|
Herbie model family token (e.g. |
resolution |
str
|
Native horizontal resolution, advisory (e.g.
|
cycles_utc |
list[int]
|
The model's daily run hours, in |
horizon_h |
int
|
Maximum forecast lead time in hours. |
cadence_h |
int | None
|
Spacing of the run hours in |
step_cadence_h |
int
|
Spacing between published forecast steps, in
hours, used to expand a |
product |
str | None
|
Herbie product token, required for some models (e.g.
HRRR |
format |
str
|
On-disk format the fetch produces ( |
idx |
bool
|
Whether the source exposes a |
backend |
BackendLiteral
|
Which download path handles this model (see
:data: |
mirrors |
list[str]
|
Ordered list of cloud-mirror keys the model is served
from (e.g. |
url_template |
str | None
|
For |
bands |
dict[str, str]
|
Map from earthlens parameter name to the centre's
selector — a Herbie |
members |
list[str]
|
Ensemble member ids, when the model is an ensemble
(empty for deterministic models). The first entry is the
default representative fetched when no |
request_options |
dict[str, Any]
|
Free-form per-centre extras the adapter splats
into its request. ECMWF Open Data uses |
license |
str | None
|
SPDX-style licence identifier the provider publishes the
data under, surfaced as catalog metadata so downstream users
and redistribution honour it. Never inferred from the URL —
populated row-by-row in |
retention_days |
int | None
|
How long the provider keeps a cycle online before
it rolls off the live endpoint. |
grid_kind |
Literal['regular-latlon', 'icosahedral']
|
The model's native horizontal grid type. Defaults to
|
title |
str | None
|
Short human-readable label (e.g. |
description |
str | None
|
One-sentence summary of the model — provider,
domain, resolution, and forecast horizon. Backs the CLI's
title fallback and gives |
Examples:
- Build a minimal Herbie-backed row and read its selector:
- Optional fields fall back to documented defaults:
Source code in libs/providers/atmosphere/src/earthlens/nwp/catalog.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | |
RetentionWarning
#
Bases: UserWarning
A request asks for a cycle the provider has already rolled off.
Emitted by NWP.__init__ when the resolved model row carries a
retention_days and the request start is older than
now - retention_days. Subclasses UserWarning so it surfaces by
default and can be promoted to an error with warnings.simplefilter
('error', RetentionWarning).
Source code in libs/providers/atmosphere/src/earthlens/nwp/_warnings.py
earthlens.nwp.backend
#
Backend that fetches open NWP forecasts as bbox-cropped COGs.
NWP(AbstractDataSource) is one backend over the open
numerical-weather-prediction buckets — NOAA NODD (GFS / GEFS / HRRR /
…), ECMWF Open Data (IFS), DWD Open Data (ICON), with Météo-France /
ECCC as follow-ons. It differs from the observation-time backends in
its forecast time axis: data is indexed by
(cycle_datetime_utc, forecast_step_hours), not a single valid time.
start / end select the cycle date range; a steps= /
horizon= kwarg picks the forecast lead times; one COG is produced
per (cycle, step).
The request shape is variables = {model_key: [param, ...]} (mirrors
the GEE / STAC backends). Each param resolves through the catalog to
the centre's selector — a Herbie search regex or a DWD variable
token. The download path per model is the catalog backend: value,
dispatched to a sibling :mod:earthlens.nwp.centres module.
OUTPUT_KIND is fixed "raster": every centre yields a GRIB2 file
that the shared pipeline reads with pyramids.grib.open_grib, crops
to the request bbox, and writes as a COG (C3); aggregate= reduces
the (cycle, step) stack (C6).
NWP
#
Bases: AbstractDataSource
Open numerical-weather-prediction backend (forecast time axis).
Resolves each requested model key against the bundled catalog,
dispatches its download to the matching centre module, and yields
one bbox-cropped COG per (cycle, step). Open buckets only — no
authentication.
Attributes:
| Name | Type | Description |
|---|---|---|
OUTPUT_KIND |
OutputKind
|
Fixed |
Source code in libs/providers/atmosphere/src/earthlens/nwp/backend.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 | |
__init__(start, end, variables, lat_lim, lon_lim, temporal_resolution='6hourly', path=None, fmt='%Y-%m-%d', *, mirror='auto', steps=None, horizon=None, members=None, mode='subset', catalog=None)
#
Initialise an NWP backend instance.
Resolves every requested model key against the catalog
before the parent constructor runs, because the parent
calls :meth:_initialize first and self.vars is not yet set
there.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
str
|
Inclusive start of the cycle-date range (parsed with
|
required |
end
|
str
|
Inclusive end of the cycle-date range. |
required |
variables
|
dict[str, list[str]]
|
Mapping from model key to a list of parameter
names, e.g. |
required |
lat_lim
|
list[float]
|
|
required |
lon_lim
|
list[float]
|
|
required |
temporal_resolution
|
str
|
Advisory label only — ignored by
NWP. The real cadence is per-model ( |
'6hourly'
|
path
|
Path | str | None
|
Output directory. Created by the parent class. |
None
|
fmt
|
str
|
|
'%Y-%m-%d'
|
mirror
|
str
|
Cloud-mirror key ( |
'auto'
|
steps
|
list[int] | None
|
Explicit forecast lead times in hours. Defaults to
|
None
|
horizon
|
int | None
|
Maximum forecast lead time in hours; expands to a
step list per model cadence (resolved in |
None
|
members
|
list[str] | None
|
Ensemble member ids to fetch (e.g. GEFS |
None
|
mode
|
str
|
How much of each GRIB2 to download — |
'subset'
|
catalog
|
Catalog | None
|
Optional pre-built :class: |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When |
Source code in libs/providers/atmosphere/src/earthlens/nwp/backend.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |
download(progress_bar=True, aggregate=None, errors='warn')
#
Fetch the requested forecasts as bbox-cropped COGs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress_bar
|
bool
|
Whether the centres show per-download progress
(threaded into Herbie's |
True
|
aggregate
|
AggregationConfig | None
|
Optional
:class: |
None
|
errors
|
str
|
How to treat a
|
'warn'
|
Returns:
| Type | Description |
|---|---|
list[Path]
|
list[Path]: One cropped COG per successfully fetched
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in libs/providers/atmosphere/src/earthlens/nwp/backend.py
earthlens.nwp.catalog
#
Dataset-catalog loader for the NWP backend.
Hosts :class:Catalog, the pydantic-backed reader for the bundled
nwp_data_catalog.yaml. Mirrors the shape of
:mod:earthlens.ecmwf.catalog and :mod:earthlens.gee.catalog: a
single YAML file with a top-level datasets: block keyed by model key
(gfs, gefs, hrrr, ifs-hres, icon-global, …). Each block
parses into an :class:NWPModel carrying the provider, the forecast
cadence (cycles_utc / horizon_h), the download backend
(herbie / ecmwf-opendata / direct-https / direct-boto3), the
cloud mirrors, the direct-centre url_template, and the
param → selector band map.
A model key resolves to an :class:NWPModel via
:meth:Catalog.get_model / :meth:Catalog.resolve /
Catalog()["..."], each with a did-you-mean hint on a miss (inherited
from :class:earthlens.base.AbstractCatalog). The path to the bundled
YAML lives at :data:CATALOG_PATH; tests can monkey-patch that module
attribute to redirect the loader at a temporary file.
Catalog
#
Bases: AbstractCatalog
Model catalog for the NWP backend.
Reads the bundled nwp_data_catalog.yaml (shipped as package data)
and exposes its datasets: block as a typed dict[str, NWPModel].
Instantiate with no arguments (Catalog()) —
:func:model_post_init parses the YAML and populates
:attr:datasets in one pass.
Attributes:
| Name | Type | Description |
|---|---|---|
datasets |
dict[str, NWPModel]
|
Structural map keyed by the model key; each value is
an :class: |
Examples:
- Load the bundled catalog and check which models are present:
- Resolve one model and read its download backend:
Source code in libs/providers/atmosphere/src/earthlens/nwp/catalog.py
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | |
get_model(model_key)
#
Resolve a model key to its :class:NWPModel row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_key
|
str
|
A curated model key (e.g. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
NWPModel |
NWPModel
|
The resolved row. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When |
Examples:
- Resolve a known model:
- A typo raises with a did-you-mean hint:
Source code in libs/providers/atmosphere/src/earthlens/nwp/catalog.py
NWPModel
#
Bases: BaseModel
One curated NWP model row.
Mirrors a single datasets.<key>: block in
nwp_data_catalog.yaml. The model key itself is the parent key in
:attr:Catalog.datasets and is not stored on the row.
Attributes:
| Name | Type | Description |
|---|---|---|
provider |
str
|
Provider slug (e.g. |
model_family |
str
|
Herbie model family token (e.g. |
resolution |
str
|
Native horizontal resolution, advisory (e.g.
|
cycles_utc |
list[int]
|
The model's daily run hours, in |
horizon_h |
int
|
Maximum forecast lead time in hours. |
cadence_h |
int | None
|
Spacing of the run hours in |
step_cadence_h |
int
|
Spacing between published forecast steps, in
hours, used to expand a |
product |
str | None
|
Herbie product token, required for some models (e.g.
HRRR |
format |
str
|
On-disk format the fetch produces ( |
idx |
bool
|
Whether the source exposes a |
backend |
BackendLiteral
|
Which download path handles this model (see
:data: |
mirrors |
list[str]
|
Ordered list of cloud-mirror keys the model is served
from (e.g. |
url_template |
str | None
|
For |
bands |
dict[str, str]
|
Map from earthlens parameter name to the centre's
selector — a Herbie |
members |
list[str]
|
Ensemble member ids, when the model is an ensemble
(empty for deterministic models). The first entry is the
default representative fetched when no |
request_options |
dict[str, Any]
|
Free-form per-centre extras the adapter splats
into its request. ECMWF Open Data uses |
license |
str | None
|
SPDX-style licence identifier the provider publishes the
data under, surfaced as catalog metadata so downstream users
and redistribution honour it. Never inferred from the URL —
populated row-by-row in |
retention_days |
int | None
|
How long the provider keeps a cycle online before
it rolls off the live endpoint. |
grid_kind |
Literal['regular-latlon', 'icosahedral']
|
The model's native horizontal grid type. Defaults to
|
title |
str | None
|
Short human-readable label (e.g. |
description |
str | None
|
One-sentence summary of the model — provider,
domain, resolution, and forecast horizon. Backs the CLI's
title fallback and gives |
Examples:
- Build a minimal Herbie-backed row and read its selector:
- Optional fields fall back to documented defaults:
Source code in libs/providers/atmosphere/src/earthlens/nwp/catalog.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | |
clear_catalog_cache()
#
Empty the module-level catalog parse cache.
Useful in tests that rewrite the catalog on disk and want to force
a re-parse. Production callers do not need this — the cache key
includes the file's st_mtime_ns, so any real mutation invalidates
the entry on its own.
Source code in libs/providers/atmosphere/src/earthlens/nwp/catalog.py
earthlens.nwp.centres.base
#
Centre-dispatch base for the NWP backend.
Each numerical-weather-prediction centre (NOAA NODD, ECMWF Open
Data, DWD Open Data, …) has its own download protocol — Herbie's
.idx byte-range subsetting, ecmwf-opendata's Client.retrieve,
or a plain per-variable HTTPS .bz2 fetch. The NWP backend owns the
provider-agnostic half (the cycle-grid walk, the GRIB2→cropped-COG
pipeline); the per-centre half — "given a model, cycle, step, the
requested params, and a mirror, put a GRIB2 file on disk" — lives
behind the :class:_NWPCentre interface implemented by the sibling
centres/*.py modules.
:func:resolve_centre maps a model's catalog backend: value to the
concrete centre class, importing it lazily so the optional SDK for a
centre you do not use never has to be installed.
resolve_centre(backend, save_dir)
#
Construct the :class:_NWPCentre for a catalog backend: value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
backend
|
str
|
The model's |
required |
save_dir
|
Path | str
|
Directory raw GRIB2 downloads are written to. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
_NWPCentre |
_NWPCentre
|
A centre instance bound to |
Raises:
| Type | Description |
|---|---|
ValueError
|
When |
ImportError
|
When the centre module is registered but its optional SDK is not installed (re-raised with a hint). |
Source code in libs/providers/atmosphere/src/earthlens/nwp/centres/base.py
earthlens.nwp.centres.noaa
#
NOAA NODD centre — GRIB2 subset fetch via Herbie.
Herbie owns the .idx byte-range subsetting that cuts >99 % of the
download volume for the NOAA models (GFS / GEFS / HRRR / RAP / NAM /
…). :class:NOAACentre is the thin adapter: it maps the requested
earthlens params to a single Herbie search regex, builds the
mirror-priority list from the mirror= kwarg, and returns the local
path of the variable-subset GRIB2 that Herbie wrote.
Herbie is imported lazily inside :meth:NOAACentre.fetch_one (never at
module import) for two reasons: its import chain pulls cfgrib /
eccodes (the [nwp] extra + the eccodes binary), and its package
__init__ prints a Unicode banner that crashes a cp1252 Windows
console — :func:_import_herbie captures that banner and rewrites a
missing-dependency import into a friendly earthlens[nwp] hint.
NOAACentre
#
Bases: _NWPCentre
Herbie-backed fetcher for the NOAA NODD models.
Source code in libs/providers/atmosphere/src/earthlens/nwp/centres/noaa.py
fetch_one(model, cycle, step, params, mirror, member=None, *, whole=False)
#
Download the GRIB2 for one (cycle, step[, member]).
In the default subset path, joins the requested params' Herbie
search regexes with | into a single .idx selector, runs
Herbie(...).download(search), and returns the path Herbie
wrote. When whole is set, calls Herbie(...).download(None)
instead — Herbie's contract for a full-file download (the whole
GRIB2 is cropped downstream exactly like a subset).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
NWPModel
|
The resolved catalog row. |
required |
cycle
|
datetime
|
The forecast cycle datetime (UTC). |
required |
step
|
int
|
The forecast lead time in hours. |
required |
params
|
list[str]
|
The requested earthlens parameter names. |
required |
mirror
|
str
|
The selected cloud-mirror key. |
required |
member
|
str | None
|
Ensemble member id (e.g. GEFS |
None
|
whole
|
bool
|
When |
False
|
Returns:
| Type | Description |
|---|---|
Path
|
pathlib.Path: The local GRIB2 file — a variable subset by
default, or the full field when |
Source code in libs/providers/atmosphere/src/earthlens/nwp/centres/noaa.py
earthlens.nwp.centres.ecmwf
#
ECMWF Open Data centre — IFS GRIB2 fetch via ecmwf-opendata.
ECMWF publishes IFS HRES / ENS / AIFS forecasts as open data (CC-BY-4.0,
no auth) and ships the ecmwf-opendata client, which does its own
index-based parameter subsetting. :class:ECMWFCentre maps the
requested earthlens params to the client's param tokens ("2t",
"tp", …), selects the mirror source, and returns the local GRIB2
the client wrote.
ecmwf-opendata is imported lazily inside
:meth:ECMWFCentre.fetch_one so the package imports without the
[nwp] extra.
ECMWFCentre
#
Bases: _NWPCentre
ecmwf-opendata-backed fetcher for the IFS models.
Source code in libs/providers/atmosphere/src/earthlens/nwp/centres/ecmwf.py
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | |
fetch_one(model, cycle, step, params, mirror, member=None, *, whole=False)
#
Retrieve the param-subset GRIB2 for one (cycle, step[, member]).
whole is accepted for interface parity but ignored: ecmwf-opendata
is param-addressed (Client.retrieve(param=...)), so there is no
whole-file request to force — every retrieve is already the
requested subset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
NWPModel
|
The resolved catalog row. |
required |
cycle
|
datetime
|
The forecast cycle datetime (UTC). |
required |
step
|
int
|
The forecast lead time in hours. |
required |
params
|
list[str]
|
The requested earthlens parameter names. |
required |
mirror
|
str
|
The selected cloud-mirror key. |
required |
member
|
str | None
|
ENS member id — a numeric id selects |
None
|
whole
|
bool
|
Ignored (see above); accepted for |
False
|
Returns:
| Type | Description |
|---|---|
Path
|
pathlib.Path: The local param-subset GRIB2 file. |
Source code in libs/providers/atmosphere/src/earthlens/nwp/centres/ecmwf.py
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | |
earthlens.nwp.centres.dwd
#
DWD Open Data centre — ICON GRIB2 fetch over plain HTTPS.
DWD publishes ICON forecasts as per-variable, bz2-compressed GRIB2
files over plain HTTPS (no .idx, no SDK): one file per
(cycle, step, variable). :class:DWDCentre builds each variable's
URL from the catalog url_template, downloads and decompresses it
in-flight, and concatenates the decompressed GRIB messages into a
single .grib2 — valid because GRIB is a stream of self-describing
messages, so pyramids.grib.open_grib sees every requested band.
Grid caveat. DWD's native ICON-global files are on an
icosahedral grid (icon_global_icosahedral_…), which is not a
regular lat/lon raster and will not crop meaningfully through the
shared _fetch pipeline. For a croppable COG the catalog should point
at a regular-lat/lon ICON product (e.g. ICON-EU, or a regridded
global feed). The download path here is correct regardless of grid;
only the downstream crop assumes a regular raster.
DWDCentre
#
Bases: _NWPCentre
Direct-HTTPS fetcher for the DWD ICON models.
Source code in libs/providers/atmosphere/src/earthlens/nwp/centres/dwd.py
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | |
fetch_one(model, cycle, step, params, mirror, member=None, *, whole=False)
#
Download + decompress one .bz2 per variable into one GRIB2.
Each variable is streamed and fed through an incremental
bz2.BZ2Decompressor, so neither the compressed body nor the
decompressed result is ever held whole in memory — a global ICON
band runs to hundreds of megabytes on each side. The decompressed
messages are appended to a single .part that is renamed only once
every variable has succeeded.
member and whole are accepted for interface parity but ignored
— the ICON rows here are deterministic (ICON-EPS is a separate
model), and DWD already serves one whole .bz2 per variable, so
there is no byte-range subset for whole to override.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
NWPModel
|
The resolved catalog row (carries |
required |
cycle
|
datetime
|
The forecast cycle datetime (UTC). |
required |
step
|
int
|
The forecast lead time in hours. |
required |
params
|
list[str]
|
The requested earthlens parameter names. |
required |
mirror
|
str
|
Ignored — DWD serves from a single origin host (kept for interface parity with the other centres). |
required |
member
|
str | None
|
Ignored (see above). |
None
|
whole
|
bool
|
Ignored — already whole-per-variable. |
False
|
Returns:
| Type | Description |
|---|---|
Path
|
pathlib.Path: One local |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the model has no |
HTTPError
|
When any variable's download fails — the
partial file is removed first, so no truncated |
Source code in libs/providers/atmosphere/src/earthlens/nwp/centres/dwd.py
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | |