How the data pipeline works
This page covers the data and software side of the Climate Extremes AI Agent. It shows how precipitation data are pulled from five public data services, each with its own access method. It then follows how they become a small compressed demo store, and how an AI agent runs fixed, deterministic diagnostics on that store without ever doing the climate maths itself.
1. The pipeline at a glance
Data flows from left to right. Each box is one stage, and the blue text names the code that does it. The access scripts run once. The deployed app works only from the demo store.
2. Five services, five ways in
Each data service has its own way of finding data, logging in and delivering it. The scripts in scripts/ are small,
readable examples of each one.
| Service | How data are found | How data are delivered | Login | Script |
|---|---|---|---|---|
| Copernicus Climate Data Store (ERA5) | Named dataset plus a request dictionary: variable, dates, hours | The request is queued on the server and cut to a Europe box there, then returned as NetCDF | CDS API key | download_era5_precip.py |
| ESGF search (CMIP6) | Search API with facets (project, source_id, experiment_id, table_id, member_id) returning Solr JSON | File records are filtered by the date range in the file name, then fetched over HTTPS | none | download_cmip6_precip.py |
| ESGF and NOAA THREDDS (OPeNDAP) | Known dataset URLs per year or per 5-year file | OPeNDAP subsetting: only the Germany box travels over the network, never the global file | none | download_germany_20yr.py |
| DestinE Harmonised Data Access (Climate DT) | STAC search (POST /stac/search) on collection DT_CLIMATE_ADAPTATION, filtered by model, experiment, resolution and parameter | An order is placed, the script polls while the server answers 202 (queued), then streams the file | DestinE platform account, bearer token, Climate DT access check | download_destine_precip.py |
| NOAA PSL (CPC) | Fixed file pattern per year | Plain HTTPS download | none | download_cpc_precip.py |
3. Problems the pipeline had to solve
Don't download the globe
Twenty years of daily global data would be large. For Germany, OPeNDAP cuts the box on the server, so only the subset is sent, and the CDS request asks for a Europe area instead of the whole globe.
Different grids and units
CMIP6 comes in kg m⁻² s⁻¹ and is converted to mm/day. Longitudes run 0–360° in one source and −180–180° in another, and latitude order differs. The subset code checks the latitude direction before slicing, and fields are regridded to a common 0.5° grid.
A safe fallback
xESMF is used for regridding when it is installed. Otherwise the code falls back to xarray interpolation, so the app still runs on a host without the heavier library.
Queued orders
DestinE and the CDS do not hand over files at once. The DestinE script follows the order's Location header and polls every five seconds until the file is ready. Requests are retried automatically on 500–504 errors.
Secrets stay out of the code
DestinE credentials come from environment variables, a local .env file or a password prompt. LLM keys come from Streamlit secrets. None of them is stored in the repository.
Small enough to ship
The demo files are re-saved with zlib compression (level 5), without losing data, so the whole store is 14 MB and the free app host needs no download at start-up.
The LLM never does the maths
Extreme indices, biases, trends and fits are checked-in Python, xarray and SciPy functions. The JSON schema for each tool is built automatically from the function's signature and docstring, so the agent's view of a tool always matches the code.
Bounded and sandboxed
The agent stops after three rounds of tool calls and must then summarise. The fallback code tool checks scripts for imports and unsafe calls before running them. It then runs them in a separate process with a 60-second limit and read access to the project data folders only.
4. How the code is organised
| Safeguard | What it does |
|---|---|
| Fixed tool registry | The agent can call only the 11 registered functions. An unknown tool name comes back as an error, and when a tool fails the agent stops instead of answering from incomplete results. |
| Activity trace | Every question shows which tools ran, with which arguments and with what result, next to the answer. |
| Fallback for broken tool calls | If a model returns malformed tool-call JSON, the agent falls back to a plain text answer instead of crashing. |
| Metadata from the files | The knowledge base reads dimensions, variables and attributes straight from the NetCDF files, so answers about the data match the data. |
| Pinned environment | environment.yml and requirements.txt pin versions, including numpy < 2 for Cartopy, and packages.txt lists the system libraries for the cloud host. |
5. What could come next
| Step | Why |
|---|---|
| Automated tests and CI | The extreme indices and statistics are good candidates for small offline tests on GitHub Actions. |
| Km-scale DestinE data | The STAC access route already exists. Adding Climate DT precipitation to the store would move the extremes to km-scale models. |
| Cloud-native store | Saving the prepared data as chunked Zarr would let the app read larger, multi-year datasets lazily. |
6. In one sentence
Precipitation data are found and fetched through five public services: an API request queue, a search API, OPeNDAP server-side subsetting, a STAC catalogue with token login and plain HTTPS. They are harmonised and compressed into a 14 MB store. A tool-bounded AI agent then runs only deterministic, checked-in diagnostics on that store and shows every step it took.