13  Page: Define The ERA5 Download Job

Turn one grouped request into one CDS download task

This page aims to make one grouped request concrete: define the request parameters, translate the country code into a bounding box, and describe how one download task writes its output.

Before defining the download job, confirm that the grouped request fields from the orchestration page are available and that CDS credentials have already been configured.

from pathlib import Path

assert Path.home().joinpath(".cdsapirc").exists(), "Expected CDS credentials in ~/.cdsapirc."

required_fields = [
    "country",
    "dataset",
    "variable",
    "year",
    "month",
    "day",
    "time",
    "data_format",
    "download_format",
]
required_fields

The original notebook starts by showing the parameter shape for a single ERA5 download job.

# Pseudocode adapted from the original notebook
request = {
    "country": "MDG",
    "dataset": "reanalysis-era5-land",
    "variable": "2m_temperature",
    "year": "2021",
    "month": "01",
    "day": ["01", "02", "...", "31"],
    "time": [f"{hour:02d}:00" for hour in range(24)],
    "data_format": "grib",
    "download_format": "unarchived",
}

The notebook then defines a general-purpose download_era5() function. Its key responsibilities are to build a predictable output path, translate a country code into a CDS bounding box, and optionally run in dry-run mode.

# Pseudocode adapted from the original notebook
def download_era5(request_dict, output_dir="data/intermediates/download_era5_nb", dry_run=True):
    request_dict = request_dict.copy()
    dataset = request_dict.pop("dataset")
    output_file = (
        f"{request_dict['country']}_{dataset}_{request_dict['variable']}_"
        f"{request_dict['year']}-{request_dict['month']}.grib"
    )

    area = get_country_bbox(request_dict["country"])
    request_dict["area"] = area
    request_dict.pop("country")

    if dry_run:
        # Report the intended request and output path without contacting CDS.
        return output_file

    # Otherwise:
    # 1. instantiate cdsapi.Client()
    # 2. call client.retrieve(dataset, request_dict, output_file)
    # 3. verify that output_file now exists
    return output_file

The notebook also defines a helper that maps each ISO country code to the bounding box required by CDS.

# Pseudocode adapted from the original notebook
def get_country_bbox(iso_code):
    # look up country subunits by ISO code
    # return [north, west, south, east] in CDS-compatible order
    return ["north", "west", "south", "east"]

In this check section, the author can add a computational test to verify that the download job is defined correctly, or that a single download executes and produces the expected output file.

# This page is complete when the operator can point to:
# - the fields required in one grouped ERA5 request,
# - the output file naming pattern,
# - the difference between dry-run and real-run behavior,
# - and the role of the country bounding-box helper in building the final CDS request.
output_file = download_era5(request, dry_run=False)
assert output_file == "MDG_reanalysis-era5-land_2m_temperature_2021-01.grib", \
    f"Expected output file name, got {output_file}"
assert Path(output_file).exists()